安全持久化到磁盘

Safely Persisting to Disk

几年前,MongoDB 因与磁盘持久性相关的不安全默认设置而引起了一些热议(例如,请参见 this question)。数据库实施必须采取哪些措施来确保写入磁盘是安全的?在写入后调用 fsync() 是否足够,或者是否必须采取其他预防措施,例如日志记录或使用磁盘的特定方式?

调用fsync()会将缓冲区缓存中的脏页刷新到磁盘。这取决于您服务器上的负载,因为缓存中有大量脏页并启动刷新可能会导致系统挂起或进入无响应状态。然而,它建议使用 vm.dirty_expire_centisecsvm.dirty_background_ratio 的最佳值调整一些内核转盘,以确保所有写入都安全快速,并且不会长时间保存在缓存中。具有较低的值可能会降低平均 I/O 速度,因为不断尝试写出脏页只会更频繁地触发 I/O 拥塞代码。

或者,一些数据库提供直接 I/O 作为文件系统的一项功能,文件读写直接从应用程序到存储设备,绕过缓存。直接 I/O 主要用于使用 O_DIRECT 标志管理自己的缓存的应用程序(数据库)。