sync、fsync与fdatasync函数详解

在研究mysql配置文件中sync_binlog=N参数之中,发现该参数的含义是在N个SQL之后,调用了fdatasync()函数刷新binlog到磁盘,所以就好好研究了下sync、fsync和fdatasync这三个函数,也记录下来分享一波。

名词解释:

脏页:当进程修改了缓存中的数据时,该页就被标记为脏页

内存映射:一个文件到一块内存的映射

延迟写(delayed write): 传统的UNIX实现在内核中设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓冲进行。 当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则 并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时, 再将该缓冲排入到输出队列,然后待其到达队首时,才进行实际的I/O操作。


延迟写减少了磁盘读写的次数,但是降低了文件内容的更新速度,所以就会在一段时间内文件数据没有写到磁盘上,为了保证磁盘上实际文件系统与缓冲区中内容保持一致,unix提供了sync、fsync、fdatasync三个函数


sync函数:

只是将所有修改过的块缓冲区排入写队列,然后就返回,并不等待实际写磁盘操作结束

如:update的系统守护进程会周期性的调用sync函数(一般每30s),保证定期冲洗内核的块缓冲区

sync函数原型:


fsync函数:

只对由文件描述符filedes(与打开文件相对应)指定的单一文件起作用,且等待写磁盘操作结束,然后返回。该调用会阻塞等待直到设备报告IO完成。

可用于数据库(因为数据库需要确保修改过的块立即写到磁盘上)


fdatasync函数:

类似于fsync,只影响文件的数据部分,而除数据外,fsync还同步更新文件的属性

如:对于提供事务支持的数据库,在事务提交时,要确保事务日志(该事务所有的修改操作和一个提交记录)完全写到硬盘上,才认定事务提交成功并返回给应用层

fsync和fdatasync函数原型:

说明:fd:要操作的文件描述符


 fsync与fdatasync区别:

除了同步文件的修改内容(脏页),fsync还会同步文件的描述信息(metadata,包括size、访问时间等等),因为文件的数据和metadata通常存在硬盘的不同地方,因此fsync至少需要两次IO写操作


总结

1、如果是对所有的缓冲区发出写硬盘的命令,应该使用sync函数,但应该注意该函数仅仅只是把该命令放入队列就返回了。

2、如果是要把一个已经打开的文件所做的修改提交到硬盘,应调用fsync函数,该函数会在数据实际写入硬盘后才返回,因此是最安全最可靠的方式。

3、如果是针对一个已经打开的文件流操作,则应该首先调用fsync函数把修改同步到内核缓冲区,然后再调用fsync把修改真正的同步到硬盘。


译者介绍:家华,从事mysqlDBA的工作,记录自己对mysql的一些总结

你可能感兴趣的:(sync,fsync,fdatasync,sync_binlog,mysql)