redo、undo的理解

一、redo日志

1.1 基本概念

WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘。一个变更操作,innodb引擎就会先把记录写到redo log,并更新内存记录,这个时候更新就算完成了。这些脏页的刷盘往往是在系统比较空闲的时候才会去做。

redo log的主要功能有两点:
一是崩溃恢复,即使缓冲池中的脏页还没来得及刷盘,这个时候突然发生了crash,也可以通过redo来进行崩溃恢复,找回需要重新刷盘的数据;二是将随机写变成了顺序写,很大程度上提高了数据库处理的写性能。

1.2 相关参数

  • innodb_log_files_in_group

redo log 文件的个数,命名方式如:ib_logfile0,iblogfile1… iblogfilen。默认2个,最大100个。

  • innodb_log_file_size

文件设置大小,默认值为 48M,最大值为512G,注意最大值指的是整个 redo log系列文件之和,即(innodb_log_files_in_group * innodb_log_file_size )不能大于最大值512G。

  • innodb_log_group_home_dir
    redo log文件存放路径

  • innodb_log_buffer_size

Redo Log 缓存区,默认8M,可设置1-8M。延迟事务日志写入磁盘,把redo log 放到该缓冲区,然后根据根据一定的策略flush到redo logfile

  • innodb_flush_log_at_trx_commit

redo日志从缓冲区flush到磁盘的策略,主要有以下3种模式:

0,每次commit都只是把redo log记录在redo log buffer中,fsync到磁盘的操作由系统来调度。
   如果MySQL发生crash,丢失1s内的事务修改操作
1:每次commit都会把redo log从redo log buffer写入到os 缓冲,并fsync刷新到磁盘文件中。
2:每次事务提交时MySQL会把日志从redo log buffer写入到os 缓冲,但fsync操作由依赖系统调度。
   如果MySQLcrash,不会丢失redo log,但是如果OS发生crash,丢失这一部分的数据。

1.3 redo log buffer刷盘的策略

1、当空间不足redo log buffer的1/2

2、每次事务提交(innodb_flush_log_at_trx_commit=1的情况下)

3、后台线程

4、做checkpoint

5、数据库关闭

6、binlog切换

1.4 redo与binlog的区别

1、redo

1)引擎层产物

2)记录格式为物理日志

3)redo logfile循环覆盖去写

4)在数据准备修改前写入缓存中的redo log中,然后才对缓存中的数据执行修改操作;而且保证在发出事务提交指令时,先向缓存中的redo log写入日志,写入完成后才执行提交动作。

2、binlog

1)server层产物

2)记录格式为逻辑日志

3)binlogfile顺序写,只要不删除一直存在

4)只在每次事务提交的时候一次性写入缓存中的日志到binlog file中

二、undo日志

2.1 基本概念

undo log主要用来存储记录修改以及被修改前的值。其功能主要有两点:一是保障事务的回滚;二是实现读不阻塞写、写不阻塞读、多版本并发(MVCC)

内部由128个回滚段(ollback segment)组成,保存在ibdata系统表空间中,分别从resg slot0 - resg slot127,每一个resg slot,也就是每一个回滚段,内部由1024个undo segment 组成。回滚段(rollback segment)分配如下:

slot 0 ,预留给系统表空间;
slot 1- 32,预留给临时表空间,每次数据库重启的时候,都会重建临时表空间;
slot33-127,如果有独立表空间,则预留给UNDO独立表空间;如果没有,则预留给系统表空间;

回滚段中除去32个提供给临时表事务使用,剩下的 128-32=96个回滚段,可执行 96*1024 个并发事务操作,每个事务占用一个 undo segment slot,注意,如果事务中有临时表事务,还会在临时表空间中的 undo segment slot 再占用一个 undo segment slot,即占用2个undo segment slot。如果错误日志中有:Cannot find a free slot for an undo log。则说明并发的事务太多了,需要考虑下是否要分流业务。

回滚段(rollback segment )采用 轮询调度的方式来分配使用,如果设置了独立表空间,那么就不会使用系统表空间回滚段中undo segment,而是使用独立表空间的,同时,如果回顾段正在 Truncate操作,则不分配。

2.2 相关参数

  • innodb_max_undo_log_size

在undo log>=2且打开innodb_undo_log_truncate参数时,undo tablespace 超过innodb_max_undo_log_size 阀值时,purge线程会去尝试truncate超过大小的undo log文件,进行undo log的重新初始化,回收表空间

该值默认大小为1G,truncate后的大小默认为10M。

  • innodb_undo_tablespaces

undo独立表空间个数,默认为0,0表示表示不开启独立undo表空间 且 undo日志存储在ibdata文件中。该参数只能在最开始初始化MySQL实例的时候指定。

  • innodb_undo_log_truncate

在undo log>=2且打开innodb_undo_log_truncate参数时,undo tablespace 超过innodb_max_undo_log_size 阀值时,purge线程会去尝试truncate超过大小的undo log文件,进行undo log的重新初始化,回收表空间

purge线程在truncate undo log file的过程中,需要检查该文件上是否还有活动事务,如果没有,需要把该undo log file标记为不可分配,这个时候,undo log 都会记录到其他文件上,所以至少需要2个独立表空间文件,才能进行truncate 操作,标注不可分配后,会创建一个独立的文件undo_<space_id>trunc.log,记录现在正在truncate 某个undo log文件,然后开始初始化undo log file到10M,操作结束后,删除表示truncate动作的 undo<space_id>_trunc.log 文件,这个文件保证了即使在truncate过程中发生了故障重启数据库服务,重启后,服务发现这个文件,也会继续完成truncate操作,删除文件结束后,标识该undo log file可分配。

  • innodb_purge_rseg_truncate_frequency

用于控制purge回滚段的频度,默认为128。假设设置为n,则说明,当Innodb Purge操作的协调线程 purge事务128次时,就会触发一次History purge,检查当前的undo log 表空间状态是否会触发truncate。

文章参考:

https://www.cnblogs.com/xinysu/p/6555082.html#_lab2_1_0

https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_15

猜你喜欢

转载自blog.csdn.net/weixin_37692493/article/details/106970674