保证提前写入日志记录的实现

时间:2012-05-24 04:15:58

标签: c algorithm file-io

如果要在{/ 1}}或write(2)fdatasync(2)分隔的Linux / Unix中发出一系列fsync(2),那么第一次写()将保证在第二次写()之前被提交到磁盘?以下SO post似乎表示无法提供此类保证,因为涉及多个缓存层。对于保证一致性的数据库系统,这似乎很重要,因为在WAL(写入前向记录)恢复中,您需要在实际更改数据之前将日志保留在磁盘上,以便在应用程序/系统发生故障时您可以恢复到上次已知的一致状态。如何在实际的数据库系统中确保/实现?

2 个答案:

答案 0 :(得分:1)

sync()系统调用几乎没有任何帮助;它承诺安排写入磁盘操作,但这就是所有。

使用的常规技术是在open()磁盘文件的文件描述符时设置正确的选项:O_DSYNCO_RSYNCO_SYNC。但是,fsync()fdatasync()非常接近相同的效果。您也可以查看经常支持的O_DIRECTIO,尽管POSIX根本没有标准化。

最终,DBMS依靠O / S来承担写入并同步到一个磁盘的数据是安全的。只要设备总是返回DBMS上次写入的内容,即使它因为缓存而不在实际磁盘上(因为它在非易失性缓存中备份,或类似的东西),那么它并不重要。另一方面,如果你有NAS(网络附加存储)不保证你上次写的(并且被告知在磁盘上是安全的)在你阅读它时会被返回,那么你的DBMS如果必须这样做就会受到影响复苏。因此,您要谨慎选择存储DBMS的位置,确保存储工作正常。如果存储不能像假想磁盘那样充分工作,那么最终可能会丢失数据。

答案 1 :(得分:0)

是的,现代版本的内核中的fsync会将内存(缓冲区缓存)刷新到磁盘,将磁盘硬件缓冲区刷新到盘片。手册页说老内核以前只做第一件事。

  

说明fsync()传输("刷新")所有已修改的核心内数据   对于所引用的文件(即,修改过的缓冲区高速缓存页面)   通过文件描述符fd到磁盘设备(或其他永久性的   存储设备),以便可以检索所有更改的信息   即使系统崩溃或重新启动后。 这包括   写入或刷新磁盘缓存(如果存在)。   调用块,直到设备报告传输有   完成。它还刷新相关的元数据信息   与文件(见统计(2))。

     

旧内核中的fsync()实现使用较少   filesys- tems不知道如何刷新磁盘缓存。在这些中   使用hdparm(8)或者需要禁用磁盘缓存的情况   sdparm(8)保证安全运行。

这指的是应用程序可以请求的内容。 Fsync是文件系统为应用程序提供的接口,文件系统本身使用其他内容。文件系统使用障碍,或者更明确的刷新和FUA请求来提交日志。看LWN post.