基础知识
Linux
先来看下linux os提供的文件操作方式,open文件的几种模式:
O_DIRECT,O_SYNC,O_DSYNC以及default模式。
default每次读写都会使用os缓冲,写时不保证数据落入磁盘
O_DIRECT每次读写文件时是直接向磁盘写入,绕过os缓冲,但是返回的时候不保证数据和元数据信息已经完全刷入磁盘
O_SYNC仍然会使用os的缓冲,只不过在每次写的时候强制将缓冲刷入磁盘(包括所有元数据信息)
O_DSYNC仍然会使用os的缓冲,只不过在每次写的时候强制将缓冲刷入磁盘(包括部分元数据信息) O_DSYNC相较于O_SYNC,可能会减少磁盘操作次数,因为元数据和文件数据可能在磁盘的不同区域,O_DSYNC可以减少这部分元数据的磁盘操作。
上面是open打开文件的系统调用,linux还有一种专门用于刷入磁盘的系统调用fsync,用于将某个文件的os缓冲数据全部刷入磁盘。
MySQL
innodb_flush_method
Defines the method used to flush data to InnoDB data files and log files, which can affect I/O throughput.
innodb_flush_method与open文件的模式不是一一对应,因为innodb_flush_method同时指定了data files和log files的刷盘方式,这两者的刷盘方式可能不一致。
举个例子,innodb_flush_method为O_DIRECT,以O_DIRECT模式open data files,数据绕过缓存直接写入硬盘,log files仍然需要过操作系统缓冲。
image.png
注意:
innodb_flush_method为O_DIRECT时
用O_DIRECT打开数据文件,那为什么还要fsync,因为需要刷新为了把directory cache和inode cache元数据也刷新到存储设备上。
日志文件还是要过文件系统缓存,所以也需要fsync。
innodb_flush_log_at_commit
控制着redo日志在commit时的刷盘行为,参考上文,因为日志仍然需要过操作系统缓冲,所以数据安全性要求高的需要设置为1,每次事务commit都把redo日志fsync到硬盘上。
图。
innodb_flush_log_at_commit的可选值为0,1,2。
当值为0时,
image.png
sync_binlog
控制着刷新binlog到磁盘的频率。
一致性
如果未开启binlog,仅仅通过Redo日志保证数据的一致性。
开启binlog问题就复杂了一些,即需要通过Redo日志与binlog一起保证数据的一致性。
这里面就牵扯出两个问题:
一、Redo日志与binlog的数据一致性。
二、Redo日志与binlog的数据顺序一致性。
所以在开启Binlog后,如何保证binlog和InnoDB redo日志的一致性呢?
二阶段提交,xid。
如何保证binlog与redo的顺序一致性?