前言
在linux内核中都有缓冲区或者页面高速缓存,大多数磁盘IO都是通过缓冲写的。当你想将数据write进文件时,内核通常会将该数据复制到其中一个缓冲区中,如果该缓冲没被写满的话,内核就不会把它放入到输出队列中。当这个缓冲区被写满或者内核想重用这个缓冲区时,才会将其排到输出队列中。等它到达等待队列首部时才会进行实际的IO操作。在进行数据库开发时,为了避免缓存中的数据还没有写入到磁盘就宕机导致的数据丢失,就需要使用fsync或这fdatasync来保证数据成功写入磁盘。
sync系统调用
函数定义:void sync(void);
我们知道write系统调用只是写入到PageCache,脏页不会立刻写入到磁盘,而是由内核的flusher线程在满足一定阈值(一定时间间隔、脏页达到一定比例),调用sync函数将脏页同步到磁盘上(放入设备的IO请求队列)。
POSIX语义要求sync系统调用只需将脏页提交到块设备IO队列就可以返回。所以我们看到sync函数返回值为void。同时sync函数返回后,并不等于写入磁盘结束,仍然会出现故障,此时sync函数是无法知晓的。对于可靠性要求比较高的应用,write提供的松散的异步语义是不够的,所以我们需要内核提供的同步IO来保证,常用fsync
以及fdatasync
。
sync函数是针对整个PageCache的,对所有的文件更新产生的脏页都会flush。