innodb_flush_log_at_trx_commit:
主要控制了innodb 将 log buffer 中的数据写入日志文件并 flush 磁盘的时间点,取值分别为 0 、 1 、 2 三个。 0 ,表示当事务提交时,不做日志写入操作,而是每秒钟将 log buffer 中的数据写入日志文件并 flush 磁盘一次; 1 ,则在每秒钟或是每次事物的提交都会引起日志文件写入、 flush 磁盘的操作,确保了事务的 ACID ;设置为 2 ,每次事务提交引起写入日志文件的动作,但每秒钟完成一次 flush 磁盘操作。显然,设置为 0 或 2 可以减小系统的 io 压力,特别是 0 时,速度最快,提高 mysql 写操作的吞吐量,但 mysql 或操作系统的崩溃、断电都可能会引起数据的丢失,设置为 2 时 os 的崩溃和断电可能会引起数据的丢失。
innodb_flush_method:
影响了服务器 flush 数据或日志文件的方法。具体有三个选值:默认的 default , innodb 使用 fsync() 函数 flush 数据和日志文件; O_DIRECT , innodb 使用 O_DIRECT 的方式打开数据文件,并使用 fsync() 函数 flush 数据和日志文件; O_DSYNC , innodb 使用 O_SYNC 打开并 flush 日志文件,使用 fsync() 函数 flush 数据文件。
注: 在类unix 操作系统中,文件的打开方式为 O_DIRECT 会最小化缓冲对 io 的影响 ,该文件的io 是直接在用户空间的 buffer 上操作的,并且 io 操作是同步的,因此不管是 read() 系统调用还是 write() 系统调用,数据都保证是从磁盘上读取的 ;O_SYNC 方式表示以同步 io 的方式打开文件,任何写操作都将阻塞到数据写入物理磁盘后才返回。 f sync( int filedes) 函数只对由文件描述符 filedes 指定的单一文件起作用,并且等待写磁盘操作结束,然后返回。 fdatasync(int filedes) 函数类似于 fsync ,但它只影响文件的数据部分。而除数据外, fsync 还会同步更新文件的元信息到磁盘 。
sync_binlog:
影响了 binary log 的 fllush ,当为 1 时,每个事物提交后, mysql 将用 fdatasync() 函数将二进制日志同步到磁盘上;当为 0 时, mysql 不会做额外的 flush ,而是依靠 os 的 flush 。
做过一些相应的测试,获得一些以上三参数搭配使用的结论:
1) O_DIRECT的 flush_method 更适合于操作系统内存有限的情况下(可以避免不必要的对交换空间的读写操作),否则,它会由于禁用了 os 的缓冲降低对数据的读写操作的效能。
2) Sync_binlog为 1 时, 每个含有修改操作的事物提交后,mysql 将 把 二进制日志同步到磁盘上 ,增大了io 压力,引起相应瓶颈,会降低对数据写操作的效率。而 select 操作不写入 binary log ,所以不受任何影响。
3) 对于innodb_flush_log_at_trx_commit 与 innodb_flush_method 的不同组合( 0|1|2 , default|O_DSYNC )(对于 O_DIRECT 的情况特殊,已经在 1 )中单独做了总结在此不累述)分析得:
① (0 , default ) 每秒钟调用fsync() 同步一次 innodb logfile , io 压力小,性能高,但可能损失数据;
② (1 , default )每秒钟和每次 commit 调用 fsync() 同步一次 innodb logfile ,保证数据完整的同时,加大了 io 压力,吞吐量相对低;
③ (2 , default )速度介于前两者之间,也不能完全保证数据的安全;
④ (0 , O_DSYNC)每秒同步日志及数据文件,吞吐量等情况应与( 0 , default )基本一致;
⑤ (1 , O_DSYNC) 每秒钟和每次commit 同步数据及日志文件,相应于( 1 , default )情况一致;
⑥ (2 , O_DSYNC)虽然 innodb_flush_log_at_trx_commit 设置为2 , innodb被告知 每次事务提交引起写入日志文件的动作,每秒钟完成一次flush 磁盘操作 ,但由于O_DSYNC 的设置使得 os 对日志自动做了同步工作,所以吞吐量等情况与 (1 , default )和( 1 , O_DSYNC)相一致。