在写入到系统的日志文件中有两个步骤,write和fsync。wirte是写入操作系统的缓存,fsync是持久化到磁盘文件,这个操作会占用系统的IOPS,而它们操作的时机是通过参数sync_binlog控制。
l sync_binlog=0,事务提交时,只做write操作,由操作系统自己控制fsync操作。这个是最危险的,一旦操作系统宕机,binlog cache中的变更内容全部会丢失。
l sync_binlog=1,事务提交时,都会做write和fsync操作。安全性最高,但是性能损耗也是最大的。
l sync_binlog=N,事务提交时,会做write操作,累积N个事务时做fsync操作。一旦操作系统宕机,会丢失binlog cache中部分变更内容。
redo log写入机制
事务执行过程中,也是先写入内存redo log buffer中,然后再写入到磁盘文件。其中redo log buffer是所有线程共用的。与binlog写到文件一样,写redo log也有write和fsync两个操作,它们操作的实际是通过参数innodb_flush_log_at_trx_commit控制。
l innodb_flush_log_at_trx_commit=0,事务提交时,只将变更内容写到redo log buffer,由后台Master线程每秒write和fsync到磁盘文件。
l innodb_flush_log_at_trx_commit=1,事务提交时,执行write和fsync操作。这是最安全的配置。
l innodb_flush_log_at_trx_commit=2,事务提交时,只执行write操作,即只写到操作系统的缓存中,由后台Master线程每秒fsync到磁盘文件。
关于这个参数与数据可靠性之间的关系如下表所示:
innodb_flush_log_at_trx_commit
数据库进程异常
操作系统异常
0
丢失最多1s的数据
丢失最多1s的数据
1
不丢数据
不丢数据
2
不丢数据
丢失最多1s的数据
参数sync_binlog=1与innodb_flush_log_at_trx_commit=1就是DBA常说的“双1”配置,也是线上环境数据最安全最可靠的配置。
再对比下binlog和redo log的不同之处:
binlog
redo log
记录者
MySQL server
Innodb引擎
记录时间
事务commit的时候
多种条件触发,随时记录
记录内容
逻辑日志
row格式或者statement格式
物理日志
数据页的变化,幂等的
两阶段提交
binlog和redo log是如何配合起到数据可靠性的作用呢,就不得不提到两阶段提交。它可以保证binlog和redo log的数据一致性。