1、抛出我的观点
首先我们应该很清楚的知道,undo日志用来保证事物的C一致性,redo保证事物的A原子性和D持久性,锁保证事物的隔离性。今天我们就来谈谈事物的D持久性。
2、redo
1、基本概念
redo由两部分组成:一是MySQL实例内存中的redo log buffer, 二是磁盘上的redo log file。
InnoDB通过Force Log at Commit机制实现事物的持久性,即当事物commit时,必须先将该事物的redo log buffer中的数据 write 到文件系统的缓存中,然后再将文件系统中的缓存数据fsync到磁盘上的redo log file中。只有这两步都完成,才完成真正意义上的持久化。参数innodb_flush_log_at_trx_commit就是用来控制将文件系统缓存中的数据fsync到磁盘上的redo log file的策略。
其中,innodb_flush_log_at_trx_commit的可选值是0, 1, 2。现在我们来分析这三种情况。下面的图截自官网。
官网地址: innodb_flush_log_at_trx_commit
第一种情况:
如果innodb_flush_log_at_trx_commit设置为0,当事务commit的时候,MySQL并不会将redo log buffer中的数据write到文件系统的缓存中,那么自然也不会将文件系统缓存中的数据fsync到磁盘上面的redo log file中。而是由master线程每秒一次的将redo log buffer中的数据write到文件系统的缓存中,并且将文件系统缓存中的数据flush到磁盘上面的redo log file中。
第二种情况:
如果innodb_flush_log_at_trx_commit设置为1,当事务commit的时候,MySQL都会把redo log buffer的数据write 到文件系统的缓存中,并且将文件系统缓存中的数据flush到磁盘上面的redo log file中。
第三种情况:
如果innodb_flush_log_at_trx_commit设置为2,当事务commit的时候,MySQL都会把redo log buffer的数据write到文件系统的缓存中,但是并不会将文件系统缓存中的数据fsync到磁盘上面的redo log file中。而是由MySQL每秒执行一次文件系统缓存中的数据flush到磁盘上面的redo log file中。
注意:
由于进程调度策略问题,这个“每秒执行一次”并不是保证100%的“每秒。
在这里我们提到“每秒执行一次”,其实说的是默认的情况下,那么到底多长时间执行,是由innodb_flush_log_at_timeout参数控制的。
Write and flush the logs every N seconds. innodb_flush_log_at_timeout allows the timeout period between flushes to be increased in order to reduce flushing and avoid impacting performance of binary log group commit. The default setting for innodb_flush_log_at_timeout is once per second.
我们需要注意的是:
Log flushing frequency is controlled by innodb_flush_log_at_timeout, which allows you to set log flushing frequency to N seconds (where N is 1 … 2700, with a default value of 1). However, any mysqld process crash can erase up to N seconds of transactions.
从这句话很清楚的知道,当mysqld process crash的时候,我们将会丢失N秒的事务数据。
For durability and consistency in a replication setup that uses InnoDB with transactions:
If binary logging is enabled, set sync_binlog=1.
Always set innodb_flush_log_at_trx_commit=1.
上面的话摘自官方,说的是,当我们使用InnoDB的时候,为了保证事务的持久性和一致性,必须设置:
sync_binlog=1 , innodb_flush_log_at_trx_commit=1.
参考文章: