Giảm kích thước tệp cơ sở dữ liệu MongoDB


165

Tôi đã có một cơ sở dữ liệu MongoDB đã từng lớn (> 3GB). Kể từ đó, các tài liệu đã bị xóa và tôi hy vọng kích thước của các tệp cơ sở dữ liệu sẽ giảm theo.

Nhưng vì MongoDB giữ không gian được phân bổ, các tệp vẫn còn lớn.

Tôi đọc ở đây và ở đó rằng lệnh quản trị viên mongod --repairđược sử dụng để giải phóng không gian chưa sử dụng, nhưng tôi không có đủ dung lượng trên đĩa để chạy lệnh này.

Bạn có biết một cách tôi có thể giải phóng không gian không sử dụng?


7
Là câu hỏi này được coi là trả lời? Chúng ta có cần thêm dữ liệu không?
Gates VP

2
bắt đầu với phiên bản 2.8, bạn có thể nén dữ liệu của mình , giúp tiết kiệm dung lượng đáng kể.
Salvador Dali

1
Tôi đã có một thách thức chính xác tương tự, cách dễ nhất để giải quyết nó là tạo một bản sao của cơ sở dữ liệu với hàm copyDatabase (), sau đó đến db.dropDatabase () cơ sở dữ liệu ban đầu và sau đó sao chép lại cơ sở dữ liệu. cơ sở dữ liệu của tôi hầu như trống rỗng và khi tôi thực hiện sao chép, chỉ có dữ liệu thực tế có thể sử dụng được sao chép. thả cơ sở dữ liệu gốc đã xóa các tập tin lớn. sử dụng db.repairDatabase () không phải là một tùy chọn vì máy chủ của tôi đã hết dung lượng ổ đĩa và thao tác này sẽ cần một lượng không gian trống rất lớn, nhiều hơn mức cần thiết cho thao tác này.
dùng3892260

Câu trả lời:


144

CẬP NHẬT: với compactlệnh WiredTiger, có vẻ như không gian đĩa thêm sẽ thực sự được phát hành cho HĐH .


CẬP NHẬT: kể từ v1.9 + có compactlệnh.

Lệnh này sẽ thực hiện việc nén "nội tuyến". Nó vẫn sẽ cần thêm không gian, nhưng không nhiều.


MongoDB nén các tệp bằng cách:

  • sao chép các tập tin vào một vị trí mới
  • lặp qua các tài liệu và sắp xếp lại / giải quyết chúng
  • thay thế các tập tin gốc bằng các tập tin mới

Bạn có thể thực hiện việc "nén" này bằng cách chạy mongod --repairhoặc bằng cách kết nối trực tiếp và chạy db.repairDatabase().

Trong cả hai trường hợp, bạn cần không gian ở đâu đó để sao chép các tập tin. Bây giờ tôi không biết tại sao bạn không có đủ không gian để thực hiện nén, tuy nhiên, bạn có một số tùy chọn nếu bạn có một máy tính khác có nhiều không gian hơn.

  1. Xuất cơ sở dữ liệu sang máy tính khác có cài đặt Mongo (sử dụng mongoexport) và sau đó bạn có thể Nhập cùng cơ sở dữ liệu đó (sử dụng mongoimport). Điều này sẽ dẫn đến một cơ sở dữ liệu mới được nén nhiều hơn. Bây giờ bạn có thể dừng mongodthay thế ban đầu bằng các tệp cơ sở dữ liệu mới và bạn đã sẵn sàng để sử dụng.
  2. Dừng mongod hiện tại và sao chép các tệp cơ sở dữ liệu vào một máy tính lớn hơn và chạy sửa chữa trên máy tính đó. Sau đó, bạn có thể di chuyển các tệp cơ sở dữ liệu mới trở lại máy tính ban đầu.

Hiện tại không có cách nào tốt để "thu gọn tại chỗ" bằng Mongo. Và Mongo chắc chắn có thể hút rất nhiều không gian.

Chiến lược tốt nhất ngay bây giờ để nén là chạy một thiết lập Master-Slave. Sau đó, bạn có thể nén Slave, để nó bắt kịp và chuyển chúng. Tôi biết vẫn còn một ít lông. Có thể nhóm Mongo sẽ đưa ra giải pháp nén tốt hơn, nhưng tôi không nghĩ nó cao trong danh sách của họ. Dung lượng ổ đĩa hiện được coi là rẻ (và nó thường là).


Cảm ơn Gates VP cho câu trả lời của bạn. Tôi đã nghĩ về hai lựa chọn mà bạn đề cập. Nhưng trước khi làm những việc như vậy, tôi muốn biết liệu có sẵn một giải pháp nhỏ gọn tại chỗ không. Cảm ơn một lần nữa.
tan vào

3
Kể từ hôm nay (2010-11-18) Dwight (phát biểu tại sự kiện MongoDC ở Washington, DC) đã khuyến nghị phương pháp sao chép / --repair / chuyển đổi nếu bạn muốn thu gọn mà không cần lấy cơ sở dữ liệu ngoại tuyến.
David J.

10
Chỉ cần một cái đầu lên 'đừng làm như tôi đã làm' và chạy - sửa chữa như root. chown các tệp db để root. doh
Totoro

18
Tài liệu cho 'compact' nói: "Thao tác này sẽ không làm giảm dung lượng đĩa được sử dụng trên hệ thống tệp." Tôi không hiểu làm thế nào đây là một giải pháp cho câu hỏi ban đầu.
Ed Norris

Nếu bạn nhìn vào câu hỏi ban đầu, một phần của vấn đề liên quan đến việc có quá nhiều dữ liệu để thực hiện sửa chữa. Nếu bạn đã lấp đầy 2/3 ổ đĩa của mình bằng một DB, bạn không thể thực hiện sửa chữa. Các tệp được phân bổ mới sẽ hút hết dung lượng còn lại trước khi DB mới hoàn toàn được "sao chép & sửa chữa" và "công tắc" sẽ không bao giờ xảy ra. Với compact, anh ta ít nhất có thể giữ các tập tin hiện có tại chỗ. Tôi đồng ý, nó không phải là một giải pháp đầy đủ, nhưng đó là một cải tiến gia tăng.
Gates VP

39

Tôi đã có cùng một vấn đề, và giải quyết bằng cách đơn giản làm điều này tại dòng lệnh:

mongodump -d databasename
echo 'db.dropDatabase()' | mongo databasename
mongorestore dump/databasename

khẳng định: 15936 Tạo bộ sưu tập db.collection không thành công. Errmsg: ngoại lệ: chỉ định kích thước: <n> khi giới hạn là đúng
chỉnh2

: Trông giống như một hồi quy ubfox ... tệp kết xuất có siêu dữ liệu đã được giới hạn: "không xác định" trong đó ... xóa các bản sửa lỗi này để khắc phục sự cố nhập.
chỉnh2

2
Cơ sở dữ liệu của tôi đã ghi được gần như toàn bộ đĩa. đó là 120 GB (đĩa 160 GB) Máy compact không làm giảm kích thước tệp và không thể sửa chữa Cơ sở dữ liệu do thiếu dung lượng. Sau mongodump & dropDatabase & mongorestore của db, tôi có 40 GB kích thước cơ sở dữ liệu.
Igor Benikov

Chỉnh sửa nhỏ cho lệnh khôi phụcmongorestore --db databasename dump/databasename
JERRY

34

Có vẻ như Mongo v1.9 + đã hỗ trợ cho máy compact tại chỗ!

> db.runCommand( { compact : 'mycollectionname' } )

Xem các tài liệu ở đây: http://docs.mongodb.org/manual/reference/command/compact/

"Không giống như RepairDatabase, lệnh compact không yêu cầu dung lượng đĩa kép để thực hiện công việc của nó. Nó yêu cầu một lượng nhỏ không gian bổ sung trong khi làm việc. Ngoài ra, compact nhanh hơn."


3
@AnujGupta "Lệnh RepairDatabase thu gọn tất cả các bộ sưu tập trong cơ sở dữ liệu. Nó giống hệt như chạy lệnh compact trên mỗi bộ sưu tập riêng lẻ." docs.mongodb.org/manual/reference/command/repairDatabase/ . Vì vậy, nếu RepairDatabase giảm kích thước sao cho gọn. Tôi đã thu gọn các bộ sưu tập của mình với rất nhiều thao tác xóa và cập nhật mỗi tuần. Tôi thích nhỏ gọn hơn repariDatabase vì trước tiên, nó nhắm mục tiêu đến các bộ sưu tập bạn muốn không phải toàn bộ cơ sở dữ liệu. Thứ hai, nó chỉ cần 2GB dung lượng trống thay vì x2 kích thước tệp db của bạn (trong trường hợp của tôi là 500GB).
Maziyar

1
Btw kiểm tra điều này: "MongoDB cung cấp 2 cách khác nhau để thu gọn dữ liệu của bạn và khôi phục hiệu suất tối ưu: RepairDatabase và compact. RepairDatabase phù hợp nếu cơ sở dữ liệu của bạn tương đối nhỏ hoặc bạn có thể đủ khả năng để lấy một nút ra khỏi vòng quay trong một thời gian khá dài Đối với kích thước cơ sở dữ liệu và khối lượng công việc truy vấn của chúng tôi, việc chạy nén liên tục trên tất cả các bộ sưu tập của chúng tôi có ý nghĩa hơn. " blog.parse.com/2013/03/26/always-be-compacting github.com/PudePl
Maziyar

3
@Maziyar docs.mongodb.org/manual/reference/command/compact/#disk-space - "Không giống như RepairDatabase, compact không giải phóng không gian trên hệ thống tệp".
Anuj Gupta

4
@Maziyar OP muốn giải phóng không gian chưa sử dụng , điều này đạt được thông qua repairDatabase, không compact. compactkhông giải phóng không gian, nó chỉ chống phân mảnh không gian đã sử dụng, không làm giảm nó.
Anuj Gupta

5
Kể từ mongo 3.0, compact sẽ lấy lại không gian nếu sử dụng công cụ lưu trữ WiredTiger.
Gary

19

Nén tất cả các bộ sưu tập trong cơ sở dữ liệu hiện tại

db.getCollectionNames().forEach(function (collectionName) {
    print('Compacting: ' + collectionName);
    db.runCommand({ compact: collectionName });
});

13

Nếu bạn cần chạy một sửa chữa đầy đủ, sử dụng repairpathtùy chọn. Trỏ nó vào một đĩa có nhiều không gian hơn

Ví dụ: trên máy Mac của tôi, tôi đã sử dụng:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair

Cập nhật: Mỗi vé máy chủ Core MongoDB 4266 , bạn có thể cần thêm --nojournalđể tránh lỗi:

mongod --config /usr/local/etc/mongod.conf --repair --repairpath /Volumes/X/mongo_repair --nojournal

1
Điều này đã làm việc tuyệt vời. Tôi thiếu không gian 2x cần thiết để sửa chữa tại chỗ, vì vậy tôi đã gắn một NAS. Chỉ có vấn đề, phải mất 18 giờ để hoàn thành, nhưng nó đã làm việc. Đảm bảo thêm cờ --nojoural.
zenocon


7

Chúng ta cần giải quyết 2 cách, dựa trên StorageEngine.

1. Động cơ MMAP ():

lệnh: db.repairDatabase ()

LƯU Ý: RepairDatabase yêu cầu dung lượng đĩa trống bằng với kích thước của tập dữ liệu hiện tại của bạn cộng với 2 gigabyte. Nếu ổ chứa dbpath thiếu đủ dung lượng, bạn có thể lắp một ổ riêng và sử dụng nó để sửa chữa. Khi lắp một ổ đĩa riêng cho sửa chữa Cơ sở dữ liệu, bạn phải chạy sửa chữa Cơ sở dữ liệu từ dòng lệnh và sử dụng công tắc --repairpath để chỉ định thư mục lưu trữ các tệp sửa chữa tạm thời. ví dụ: Tưởng tượng kích thước DB là 120 GB nghĩa là, (120 * 2) +2 = 242 GB Dung lượng đĩa cứng cần thiết.

một cách khác để bạn thu thập thông minh, lệnh: db.runCommand ({compact: 'CollectionName'})

2. WiredTiger: Nó tự động tự giải quyết.


6

Đã có một số nhầm lẫn đáng kể về việc cải tạo không gian trong MongoDB, và một số thực tiễn được khuyến nghị là hết sức nguy hiểm để thực hiện trong các loại triển khai nhất định. Thêm chi tiết dưới đây:

TL; DR repairDatabase cố gắng cứu vãn dữ liệu từ các triển khai MongoDB độc lập đang cố gắng khôi phục từ hỏng đĩa. Nếu nó phục hồi không gian, nó hoàn toàn là một tác dụng phụ . Phục hồi không gian không bao giờ nên được xem xét chính của việc chạyrepairDatabase .

Khôi phục không gian trong một nút độc lập

WiredTiger: Đối với một nút độc lập với WiredTiger, việc chạy compactsẽ giải phóng không gian cho HĐH, với một cảnh báo: compactLệnh trên WiredTiger trên MongoDB 3.0.x đã bị ảnh hưởng bởi lỗi này: SERVER-21833 đã được sửa trong MongoDB 3.2.3. Trước phiên bản này, compacttrên WiredTiger có thể âm thầm thất bại.

MMAPv1: Do cách thức hoạt động của MMAPv1, không có phương pháp an toàn và được hỗ trợ để khôi phục dung lượng bằng cách sử dụng công cụ lưu trữ MMAPv1. compacttrong MMAPv1 sẽ chống phân mảnh các tệp dữ liệu, có khả năng cung cấp thêm dung lượng trống cho các tài liệu mới, nhưng nó sẽ không giải phóng không gian trở lại HĐH.

Bạn thể chạy repairDatabasenếu bạn hiểu đầy đủ hậu quả của lệnh nguy hiểm tiềm tàng này (xem bên dưới), vìrepairDatabase về cơ bản viết lại toàn bộ cơ sở dữ liệu bằng cách loại bỏ các tài liệu bị hỏng. Là một tác dụng phụ, điều này sẽ tạo ra các tệp dữ liệu MMAPv1 mới mà không có bất kỳ sự phân mảnh nào trên đó và giải phóng không gian trở lại HĐH.

Đối với một phương pháp ít phiêu lưu hơn, việc chạy mongodumpmongorestorecó thể cũng có thể trong triển khai MMAPv1, tùy thuộc vào quy mô triển khai của bạn.

Khôi phục không gian trong một bộ bản sao

Đối với cấu hình bộ bản sao, phương pháp tốt nhất và an toàn nhất để khôi phục dung lượng là thực hiện đồng bộ hóa ban đầu , cho cả WiredTiger và MMAPv1.

Nếu bạn cần khôi phục không gian từ tất cả các nút trong tập hợp, bạn có thể thực hiện đồng bộ hóa ban đầu. Đó là, thực hiện đồng bộ hóa ban đầu trên mỗi thứ hai, trước khi cuối cùng bước xuống chính và thực hiện đồng bộ hóa ban đầu trên nó. Phương pháp đồng bộ hóa ban đầu là phương pháp an toàn nhất để thực hiện bảo trì bộ bản sao và nó cũng không bao gồm thời gian chết như một phần thưởng.

Xin lưu ý rằng tính khả thi của việc thực hiện đồng bộ hóa ban đầu cũng phụ thuộc vào quy mô triển khai của bạn. Đối với các triển khai cực kỳ lớn, có thể không khả thi khi thực hiện đồng bộ hóa ban đầu và do đó các tùy chọn của bạn có phần hạn chế hơn. Nếu WiredTiger được sử dụng, bạn thể lấy một thứ cấp ra khỏi tập hợp, khởi động nó dưới dạng độc lập, chạy compacttrên nó và nối lại nó với tập hợp.

Về repairDatabase

Vui lòng không chạy repairDatabasetrên các nút thiết lập bản sao . Điều này rất nguy hiểm, như được đề cập trong trang RepairDatabase và được mô tả chi tiết hơn dưới đây.

Tên repairDatabasenày là một chút sai lệch, vì lệnh không cố gắng sửa chữa bất cứ điều gì. Lệnh được dự định sẽ được sử dụng khi có hỏng đĩa trên một nút độc lập , điều này có thể dẫn đến các tài liệu bị hỏng.

Các repairDatabaselệnh có thể được mô tả một cách chính xác hơn là "cơ sở dữ liệu cứu hộ". Đó là, nó tạo lại cơ sở dữ liệu bằng cách loại bỏ các tài liệu bị hỏng trong nỗ lực đưa cơ sở dữ liệu vào trạng thái nơi bạn có thể khởi động nó và trục vớt tài liệu nguyên vẹn từ nó.

Trong các triển khai MMAPv1, việc xây dựng lại các tệp cơ sở dữ liệu này sẽ giải phóng không gian cho HĐH như là một tác dụng phụ . Phát hành không gian cho hệ điều hành không bao giờ là mục đích.

Hậu quả của repairDatabasemột bộ bản sao

Trong một bộ bản sao, MongoDB hy vọng tất cả các nút trong tập hợp có chứa dữ liệu giống hệt nhau. Nếu bạn chạy repairDatabasetrên một nút đặt bản sao, có khả năng nút đó chứa tham nhũng không bị phát hiện vàrepairDatabase sẽ loại bỏ các tài liệu bị hỏng cho bạn.

Có thể dự đoán, điều này làm cho nút đó chứa một tập dữ liệu khác với phần còn lại của tập hợp. Nếu một bản cập nhật xảy ra với tài liệu đơn lẻ đó, toàn bộ thiết bị có thể bị sập.

Để làm cho vấn đề tồi tệ hơn, hoàn toàn có thể là tình huống này có thể không hoạt động trong một thời gian dài, chỉ để tấn công bất ngờ mà không có lý do rõ ràng.


5

Trong trường hợp một khối dữ liệu lớn bị xóa khỏi bộ sưu tập và bộ sưu tập không bao giờ sử dụng không gian đã xóa cho các tài liệu mới, không gian này cần phải được trả về hệ điều hành để các cơ sở dữ liệu hoặc bộ sưu tập khác có thể sử dụng. Bạn sẽ cần chạy một hoạt động nhỏ gọn hoặc sửa chữa để chống phân mảnh không gian đĩa và lấy lại không gian trống có thể sử dụng.

Hành vi của quá trình nén phụ thuộc vào công cụ MongoDB như sau

db.runCommand({compact: collection-name })

MMAPv1

Thao tác nén phân mảnh tệp dữ liệu & chỉ mục. Tuy nhiên, nó không giải phóng không gian cho hệ điều hành. Hoạt động này vẫn hữu ích để chống phân mảnh và tạo thêm không gian tiếp giáp để sử dụng lại bởi MongoDB. Tuy nhiên, nó không có tác dụng mặc dù khi dung lượng đĩa trống rất thấp.

Cần thêm dung lượng đĩa tối đa 2GB trong quá trình nén.

Một khóa cấp cơ sở dữ liệu được tổ chức trong quá trình hoạt động nén.

WiredTiger

Công cụ WiredTiger cung cấp nén theo mặc định, tiêu thụ ít dung lượng đĩa hơn MMAPv1.

Quá trình nhỏ gọn giải phóng không gian trống cho hệ điều hành. Không gian đĩa tối thiểu là cần thiết để chạy các hoạt động nhỏ gọn. WiredTiger cũng chặn tất cả các hoạt động trên cơ sở dữ liệu vì nó cần khóa cấp độ cơ sở dữ liệu.

Đối với động cơ MMAPv1 , doest nhỏ gọn không trả lại không gian cho hệ điều hành. Bạn cần phải chạy hoạt động sửa chữa để giải phóng không gian không sử dụng.

db.runCommand({repairDatabase: 1})

3

Mongodb 3.0 trở lên có công cụ lưu trữ mới - WiredTiger. Trong trường hợp của tôi, công cụ chuyển đổi đã giảm mức sử dụng đĩa từ 100 Gb xuống 25Gb.


1

Các tập tin cơ sở dữ liệu không thể giảm kích thước. Trong khi "sửa chữa" cơ sở dữ liệu, máy chủ mongo chỉ có thể xóa một số tệp của nó. Nếu một lượng lớn dữ liệu đã bị xóa, máy chủ mongo sẽ "giải phóng" (xóa), trong quá trình sửa chữa, một số tệp hiện có của nó.


1

Nói chung nhỏ gọn là thích hợp hơn để sửa chữa Cơ sở dữ liệu. Nhưng một lợi thế của sửa chữa nhỏ gọn là bạn có thể phát hành sửa chữa cho toàn bộ cụm. nhỏ gọn bạn phải đăng nhập vào từng phân đoạn, đó là loại gây phiền nhiễu.


1

Khi tôi gặp vấn đề tương tự, tôi đã dừng máy chủ mongo của mình và khởi động lại bằng lệnh

mongod --repair

Trước khi chạy hoạt động sửa chữa, bạn nên kiểm tra xem bạn có đủ dung lượng trống trên ổ cứng không (tối thiểu - là kích thước của cơ sở dữ liệu của bạn)


1

Đối với chế độ độc lập, bạn có thể sử dụng nhỏ gọn hoặc sửa chữa,

Đối với cụm sao hoặc bộ sao chép được phân tách, theo kinh nghiệm của tôi, sau khi bạn chạy compact trên sơ cấp, tiếp theo là nén thứ cấp, kích thước của cơ sở dữ liệu chính giảm, nhưng không phải là thứ cấp. Bạn có thể muốn làm lại thành viên để giảm kích thước của cơ sở dữ liệu thứ cấp. và bằng cách này, bạn có thể thấy rằng kích thước của cơ sở dữ liệu thứ cấp thậm chí còn giảm hơn so với chính, tôi đoán lệnh compact không thực sự nén bộ sưu tập. Vì vậy, tôi đã kết thúc việc chuyển đổi chính và phụ của bộ bản sao và thực hiện lại thành viên đồng bộ lại.

kết luận của tôi là, cách tốt nhất để giảm kích thước của tập hợp phân đoạn / bản sao là bằng cách thực hiện lại thành viên, chuyển đổi thứ cấp chính và đồng bộ lại lần nữa.


0

mongoDB -repair không được khuyến nghị trong trường hợp cụm bị phân mảnh.

Nếu sử dụng cụm sao được đặt phân cụm, sử dụng lệnh rút gọn, nó sẽ ghi lại và chống phân mảnh tất cả các tệp dữ liệu và chỉ mục của tất cả các bộ sưu tập. cú pháp:

db.runCommand( { compact : "collection_name" } )

khi được sử dụng với lực: true, compact chạy trên sơ cấp của bộ bản sao. ví dụ db.runCommand ( { command : "collection_name", force : true } )

Các điểm khác cần xem xét: -Nó chặn các hoạt động. Vì vậy, nên thực hiện trong cửa sổ bảo trì. -Nếu bộ sao chép chạy trên các máy chủ khác nhau, cần phải được thực thi riêng trên từng thành viên - Trong trường hợp cụm bị phân tách, compact cần phải thực hiện riêng trên từng thành viên phân đoạn. Không thể thực thi chống lại mongos.


-5

Chỉ cần một cách là tôi đã có thể làm điều đó. Không đảm bảo về sự an toàn của dữ liệu hiện tại của bạn. Hãy thử với rủi ro của riêng bạn.

Xóa các tệp dữ liệu trực tiếp và khởi động lại mongod.

Ví dụ: với ubfox (đường dẫn mặc định tới dữ liệu: / var / lib / mongodb), tôi đã có một vài tệp có tên như: sưu tập. #. Tôi giữ bộ sưu tập.0 và xóa tất cả những người khác.

Có vẻ là một cách dễ dàng hơn nếu bạn không có dữ liệu nghiêm trọng trong cơ sở dữ liệu.


các tệp được lưu trữ dưới dạng <cơ sở dữ liệu>. <số> ví dụ mydb.3 - bạn không thể nói với bộ sưu tập.
bobmarkie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.