Đăng một câu trả lời mới để làm sạch điều này. Tôi đã thực hiện các bài kiểm tra và đọc lại mã nguồn và tôi chắc chắn rằng sự khó chịu đến từ một câu không may trong tài liệu viết về mối quan tâm. Khi bật tính năng ghi nhật ký và j:true
ghi mối quan tâm, việc ghi được lâu bền và không có cửa sổ bí ẩn nào về việc mất dữ liệu.
Ngay cả khi đang bật tính năng viết nhật ký, thì vẫn có cơ hội bị mất các bài viết trong MongoDB chứ?
Có, bởi vì độ bền cũng phụ thuộc vào các hoạt động cá nhân viết mối quan tâm.
"Theo mặc định, mức độ lớn nhất của các bài viết bị mất, tức là những bài viết không được đưa vào tạp chí, là những bài viết được thực hiện trong 100 mili giây qua."
Đây là từ Quản lý nhật ký, cho biết bạn có thể mất các ghi chép đã thực hiện kể từ lần cuối cùng tạp chí được lưu vào đĩa.
Đúng rồi. Nhật ký được xóa không đồng bộ bởi một chuỗi riêng biệt, vì vậy bạn có thể mất mọi thứ kể từ lần gửi cuối cùng.
Nếu tôi muốn độ bền cao hơn, "Để buộc mongod đăng ký nhật ký thường xuyên hơn, bạn có thể chỉ định
j:true
. Khi thao tác ghi vớij:true
đang chờ xử lý, mongod sẽ giảmjournalCommitInterval
đến một phần ba giá trị đã đặt. "
Điều này cũng làm tôi khó chịu. Đây là ý nghĩa của nó:
Khi bạn gửi một thao tác ghi với j:true
, nó không kích hoạt quá trình xả đĩa ngay lập tức và không có trên chuỗi mạng. Điều đó có ý nghĩa, bởi vì có thể có hàng tá ứng dụng nói chuyện với cùng một phiên bản mongod. Nếu mọi ứng dụng đều sử dụng tính năng ghi nhật ký nhiều, db sẽ rất chậm vì nó luôn luôn đồng bộ hóa.
Thay vào đó, điều xảy ra là 'chuỗi độ bền' sẽ lấy tất cả các cam kết tạp chí đang chờ xử lý và chuyển chúng vào đĩa. Luồng được triển khai như thế này (nhận xét của tôi):
sleepmillis(oneThird); //dur.cpp, line 801
for( unsigned i = 1; i <= 2; i++ ) {
// break, if any j:true write is pending
if( commitJob._notify.nWaiting() )
break;
// or the number of bytes is greater than some threshold
if( commitJob.bytes() > UncommittedBytesLimit / 2 )
break;
// otherwise, sleep another third
sleepmillis(oneThird);
}
// fsync all pending writes
durThreadGroupCommit();
Vì vậy, một j:true
đang chờ xử lý thao tác này sẽ khiến chuỗi cam kết tạp chí cam kết sớm hơn bình thường và nó sẽ cam kết tất cả các lần ghi đang chờ xử lý vào tạp chí, bao gồm cả những bài viết không có j:true
đặt.
Ngay cả trong trường hợp này, có vẻ như việc chuyển nhật ký vào đĩa không đồng bộ nên vẫn có khả năng bị mất ghi. Tôi có thiếu điều gì đó về cách đảm bảo rằng các bài viết không bị mất không?
Ghi (hoặc getLastError
lệnh) với j:true
mối quan tâm viết nhật ký sẽ đợi chuỗi độ bền kết thúc đồng bộ hóa , vì vậy không có rủi ro mất dữ liệu (miễn là hệ điều hành và phần cứng đảm bảo điều đó).
Câu "Tuy nhiên, có một cửa sổ giữa các cam kết của tạp chí khi hoạt động ghi không hoàn toàn bền" có thể đề cập đến một mongod đang chạy với tính năng ghi nhật ký được bật chấp nhận một ghi mà KHÔNG sử dụng j:true
viết mối quan tâm. Trong trường hợp đó, có khả năng bài viết bị mất kể từ lần đăng ký tạp chí cuối cùng.
Tôi đã gửi báo cáo lỗi tài liệu cho việc này.