2012-05-24 32 views
7

Nếu một người phát hành một chuỗi tuần tự write(2) trong Linux/Unix được phân tách bởi fdatasync(2) hoặc fsync(2) hoặc sync(2) thì đảm bảo rằng chữ viết đầu tiên() sẽ được ghi vào đĩa trước ghi thứ hai của bạn() ? Các SO post sau đây dường như nói rằng đảm bảo như vậy không thể được đưa ra, vì có nhiều lớp bộ nhớ đệm liên quan. Đối với các hệ thống cơ sở dữ liệu đảm bảo tính nhất quán, điều này có vẻ quan trọng, vì trong quá trình khôi phục WAL (Write Ahead Logging), bạn cần các bản ghi của mình được lưu trữ trên đĩa trước khi thực sự thay đổi dữ liệu của bạn, trong trường hợp lỗi ứng dụng/hệ thống bạn có thể hoàn nguyên về trạng thái nhất quán đã biết cuối cùng của mình. Làm thế nào điều này được đảm bảo/thực hiện trong một hệ thống cơ sở dữ liệu thực tế?Đảm bảo thực hiện ghi nhật ký trước

+0

Tôi sẽ xem xét các giải thích trên trang web SQLite. Nó bao gồm cách các phương pháp được sử dụng rất nhiều vì nó cung cấp một cái nhìn tổng quan về thời điểm sử dụng các phần cứng (đồng bộ), v.v. –

Trả lời

1

Cuộc gọi hệ thống sync() thực tế không giúp được gì; nó hứa hẹn sẽ lên lịch các hoạt động ghi vào đĩa, nhưng đó là tất cả.

Kỹ thuật thông thường được sử dụng là đặt các tùy chọn chính xác khi bạn open() bộ mô tả tệp cho tệp đĩa: O_DSYNC, O_RSYNC, O_SYNC. Tuy nhiên, fsync()fdatasync() nhận được khá gần với các hiệu ứng tương tự. Bạn cũng có thể xem O_DIRECTIO thường được hỗ trợ, mặc dù POSIX không chuẩn hóa gì cả.

Cuối cùng, DBMS dựa vào O/S để thực hiện dữ liệu được ghi và đồng bộ hóa với một đĩa được bảo mật. Miễn là thiết bị sẽ luôn trả về những gì DBMS đã viết cuối cùng, ngay cả khi nó không nằm trên đĩa thực sự vì bộ nhớ đệm (vì nó được sao lưu trong bộ đệm không bay hơi, hay cái gì đó tương tự), thì nó không quan trọng . Nếu, mặt khác, bạn có NAS (mạng lưu trữ đính kèm) mà không đảm bảo rằng những gì bạn đã viết cuối cùng (và đã được nói là an toàn trên đĩa) được trả lại khi bạn đọc nó, sau đó DBMS của bạn có thể bị ảnh hưởng nếu nó phải làm phục hồi. Vì vậy, bạn chọn nơi bạn lưu trữ DBMS của bạn một cách cẩn thận, đảm bảo lưu trữ hoạt động hợp lý. Nếu bộ nhớ không hoạt động đầy đủ như đĩa giả định, bạn có thể sẽ mất dữ liệu.

+0

DirectIO không cung cấp các đảm bảo mà câu hỏi này yêu cầu. Nhưng OSYNC cờ để mở không những gì được mong đợi, chắc chắn. – ArekBulski

0

Có, fsync trong phiên bản hiện tại của hạt nhân làm cả bộ nhớ tuôn ra (bộ đệm đệm) vào bộ đệm phần cứng đĩa và đĩa để đĩa. Trang Man cho biết các hạt nhân cũ chỉ được sử dụng để làm điều đầu tiên.

MÔ TẢ fsync() chuyển ("bừng") tất cả các sửa đổi dữ liệu trong lõi của (ví dụ, các trang bộ nhớ cache đệm sửa đổi cho) các tập tin được gọi bởi các tập tin descrip- tor fd vào đĩa thiết bị (hoặc thiết bị lưu trữ cố định khác) để tất cả thông tin đã thay đổi có thể được truy xuất ngay cả sau khi hệ thống bị lỗi hoặc được khởi động lại. Điều này bao gồm ghi hoặc xóa bộ nhớ cache trên đĩa nếu có. Các khối gọi cho đến khi thiết bị báo cáo rằng quá trình chuyển đã hoàn thành . Nó cũng xóa thông tin siêu dữ liệu được liên kết tại số với tệp (xem stat (2)).

Việc triển khai fsync() trong các hạt cũ hơn và ít được sử dụng các tệp không biết cách xóa bộ đệm đĩa. Trong các trường hợp này , cần lưu ý bộ nhớ cache đĩa bằng cách sử dụng hdparm (8) hoặc sdparm (8) để đảm bảo hoạt động an toàn.

Điều này đề cập đến những ứng dụng có thể yêu cầu. Fsync là một giao diện mà hệ thống tập tin cung cấp cho các ứng dụng, hệ thống tập tin tự sử dụng một cái gì đó khác bên dưới. Hệ thống tập tin sử dụng các rào cản, hoặc khá rõ ràng flushes và FUA yêu cầu để cam kết tạp chí.Hãy xem LWN post.

Các vấn đề liên quan