MySQL数据库服务工作机制-重做日志应用(redo log)
redo log 日志概念介绍
redo log 日志是在数据库事务提交后生成的,如果此时服务宕掉了,后期重启服务可以用redo log日志恢复数据,从而保证事务的持久性(事务提交操作后永久生效);
redo log 日志生成流程

结合图示信息,redo日志生成的详细流程步骤为:
步骤01:先将原始数据从磁盘中读入到内存中来,从而修改内存中的数据信息;
步骤02:生成一条重做日志信息并先写入redo log buffer,记录的是数据被修改后的值;
步骤03:当事务被提交时(commit),将redo log buffer中的内容刷新到redo log file,对redo log file采用追加写人的方式;
步骤04:最后定期将内存中修改的数据刷新到磁盘中,以段、区、页方式进行数据信息的存储;
redo log 日志内存层面
在服务器启动时就向操作系统申请了一大片称之为redo log buffer的连续内存空间,翻译成中文就是redo日志缓冲区,这片内存空间被划分成若干个连续的redo log block,一个redo log block占用512字节大小;

redo log buffer默认大小是16M,可以修改范围是:1M ~ 4096M
redo log buffer配置信息查看:
mysql> select @@innodb_log_buffer_size;
+--------------------------+
| @@innodb_log_buffer_size |
+--------------------------+
| 16777216 |
+--------------------------+
1 row in set (0.03 sec)
redo log 日志磁盘层面
redo log 物理文件存放在数据库程序的数据目录中,文件名称一般为:ib_logfileN
[root@oldboyxiaoq data]# ll -h ib_logfile*
-rw-r----- 1 mysql mysql 48M Nov 16 18:17 ib_logfile0
-rw-r----- 1 mysql mysql 48M Nov 7 08:52 ib_logfile1
redo log 日志刷盘策略
redo log的写入并不是直接写入磁盘的。InnoDB引擎会在写redo log的时候先写redo log buffer,之后再以一定的频率刷新到真正的redo log file中;这里的一定频率怎么来理解呢?这就是要讲解介绍的刷盘策略;

需要注意的是redo log buffer刷盘到redo log file的过程并不是真正的刷到磁盘中去,只是输入到文件系统缓存(page cache)中去(这是现代操作系统为了提高文件写入效率做的一个优化),真正的写入会交给系统自己来决定(比如page cahe足够大了)。
那么对于InnoDB引擎来说就存在一个问题,如果交个系统来同步,同样如果系统宕机,那么数据也会丢失(虽然整个系统宕机的概率还是比较小的)。
针对这种情况,InnoDB给出了Innodb_flush_log_at_trx_commit参数,该参数可以控制commit提交事务时。如何将redo log buffer中的日志信息刷新到redo log file中,主要支持三种刷新策略:
mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------+
| 1 |
+----------------------------------+
1 row in set (0.00 sec)
刷盘策略总结:
策略 0:表示每次事务提交时不进行刷盘操作,系统默认master thread每个1s进行一次重做日志的同步;
策略 1:表示每次事务提交时将进行刷盘操作;(属于默认配置)
策略 2:表示每次事务提交时只是把redo log buffer写入到page cache,不进行同步,由OS自己决定什么时候同步到磁盘文件;
配置参数详细解读说明:
01:innodb_flush_log_at_trx_commit=1
配置参数为1时,只要事务提交成功,redo log记录就一定在硬盘里,不会有任何数据丢失;
如果事务执行期间MySQL挂了或宕机了,这部分日志丢了,但是事务并没有提交,所以日志丢了也不会有损失,可以保证ACID的D,数据绝对不会丢失,但是效率是最差的;
建议使用默认值,虽然操作系统宕机的概率理论小于数据库宕机的概率,但是一般既然使用了事务,那么数据的安全相对来说更重要些。
02:innodb_flush_log_at_trx_commit=2
配置参数为2时,只要事务提交成功,redo log buffer中的内容只写入文件系统缓存( page cache );
如果仅仅只是MySQL挂了不会有任何数据丢失,但是操作系统宕机可能会有1秒数据的丢失,这种情况下无法满足ACID中的D,但是效率是最高的;
03:innodb_flush_log_at_trx_commit=0
配置参数为0时,master thread中每1秒进行一次重做日志的fsync操作,因此实例crash最多丢失1秒钟内的事务。( master thread是负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性)
数值0的话,是一种折中的做法,它的IO效率理论是高于1的,低于2的,这种策略也有丢失数据的凤险,也无法保证D。
redo log 日志配置参数
01. innodb_log_files_in_group
用于指明redo log file的个数,命名方式如: ib_logfile0,iblogfile....iblogfilen。默认2个,最大100个。
mysql> select @@innodb_log_files_in_group;
+-----------------------------+
| @@innodb_log_files_in_group |
+-----------------------------+
| 2 |
+-----------------------------+
1 row in set (0.00 sec)
02. innodb_log_file_size
用于指明单个redo log文件设置大小,默认值为48M。最大值为512G;
mysql> select @@innodb_log_file_size;
+------------------------+
| @@innodb_log_file_size |
+------------------------+
| 50331648 |
+------------------------+
1 row in set (0.00 sec)
注意:最大值指的是整个redo log.系列文件之和,即innodb_log_files_in_group * innodb_log_file_size 不能大于最大值512G
redo log 日志刷盘过程
每次刷盘redo log记录到日志文件组中,write pos位置就会后移更新;
每次MySQL加载日志文件组恢复数据时,会清空加载过的redo log,并把checkpoint后移更新;
write pos和checkpoint之间的还空着的部分可以用来写入新的redo log记录;
如果write pos追上checkpoint,表示日志文件组满了,这时候不能在写入新的redo log记录,MySQL需要停下来,清空一些记录,把checkpoint推进一下;
· Wirte Pos:表示写入位置
· Check Point:表示刷盘位置
· check Point->Write Pos:待落盘数据


浙公网安备 33010602011771号