MySQL中Undo-log是什么?有什么作用?

2.6.1. Undo-log撤销日志

Undo即撤销的意思,通常也称为回滚日志,用来给MySQL撤销SQL操作的。

当一条写入类型的SQL执行时,都会记录Undo-log日志,Undo-log并不存在单独的日志文件,InnoDB默认是将Undo-log存储在xx.ibdata共享表数据文件当中,默认采用段的形式存储。

当一个事务尝试写某行表数据时,首先会将旧数据拷贝到xx.ibdata文件中,将表中行数据的隐藏字段:roll_ptr回滚指针指向xx.ibdata文件中的旧数据,然后再写表上的数据。需要回滚时,直接将roll_ptr回滚指针指向的Undo记录,从xx.ibdata共享表数据文件中拷贝到xx.ibd表数据文件,覆盖掉原本改动过的数据。


如果是insert操作,由于插入之前这条数据都不存在,就不会产生Undo记录,因此隐藏字段中的roll_ptr=null,直接用null覆盖插入的新记录即可,就实现了删除数据的效果。

在共享表数据文件中,有一块区域名为Rollback Segment回滚段,每个回滚段中有1024个Undo-log Segment,每个Undo段可存储一条旧数据,而执行写SQL时,Undo-log就是写入到这些段中。

MySQL5.5版本前,默认只有一个Rollback Segment,在MySQL5.5版本后,默认有128个回滚段,支持128*1024条Undo记录同时存在。

2.6.1.1. 基于Undo版本链实现MVCC

Undo-log中记录的旧数据并不仅仅只有一条,一条相同的行数据可能存在多条不同版本的Undo记录,内部会通过roll_ptr回滚指针,组成一个单向链表,而这个链表则被称之为Undo版本链。

2.6.1.2. Undo-log的内存缓冲区

InnoDB在MySQL启动时,会在内存中构建一个BufferPool,这个缓冲池主要存放一类是数据相关的缓冲,如索引、锁、表数据等,另一类则是各种日志的缓冲,如Undo、Bin、Redo....等日志。

一条写SQL执行时,不会直接往磁盘中的xx.ibdata文件写数据,会写在undo_log_buffer缓冲区中,因为工作线程直接去写磁盘太影响效率了,写进缓冲区后会由后台线程去刷写磁盘。

当一个事务提交时,Undo的旧记录不会立马删除Undo记录,对于旧记录的删除工作,InnoDB中会有专门的purger线程负责,purger线程内部会维护一个ReadView,它会以此作为判断依据,来决定何时移除Undo记录。

因为可能会有其他事务在通过快照,读Undo版本链中的旧数据,直接移除可能会导致其他事务读不到数据,因此删除的工作就交给了purger线程。

2.6.1.3. Undo-log相关的参数

在MySQL5.5之前没有太多参数,如:

  • innodb_max_undo_log_size:本地磁盘文件中,Undo-log的最大值,默认1GB。
  • innodb_rollback_segments:指定回滚段的数量,默认为1个。

其他参数基本上是在MySQL5.6才有的,如下:

  • innodb_undo_directory:指定Undo-log的存放目录,默认放在.ibdata文件中。
  • innodb_undo_logs:指定回滚段的数量,默认为128个,也就是之前的innodb_rollback_segments。
  • innodb_undo_tablespaces:指定Undo-log分成几个文件来存储,必须开启innodb_undo_directory参数。
  • innodb_undo_log_truncate:是否开启Undo-log的在线压缩功能,即日志文件超过大小一半时自动压缩,默认OFF关闭。

MySQL5.5版本以后,Undo-log日志支持单独存放,并且多出了几个参数可以调整Undo-log的区域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值