undo log记录的内容是逻辑的(基于每条记录),redo log记录的是物理的(基于page),rollback是逻辑上的回滚
innodb_undo_tablespaces 5.6可以将undo设为多个表空间
innodb_undo_logs 可以设置有多少个undo,默认128,5.7是96,前面32个留给临时表(ibtmp1),其实也无所谓,通常用不到
Ⅰ、UNDO对象
从底层来看非常复杂
对象 | 说明 |
---|---|
rollback segment | 回滚段 |
undo log segment undo | undo日志段 |
undo page | 组成了undo日志段 |
undo log | 存在于undo page中 |
undo log record | 存在于undo log中 |
上面这个太底层,这里只分析回滚段和undo log内容,其他自己看书
1.1 rollback segment(回滚段)
- 5.5之前只有1个rollback segment
- 5.5之后有128个
- 不保存任何undo log,只保存undo log segment的位置
- 含有1024个undo slot
Rollback undo log
Segment segment
+-----------+ +---------+ +------+
| segment 1 | | 1 +------------> undo |
+-----------+ +---------+ +------+
| segment 2 +------------> 2 |
+-----------+ +---------+
| segment 3 | | ... |
+-----------+ +---------+ +------+
| | | 1024 +------------> undo |
| . | +---------+ +------+
| . |
| . |
| |
+-----------+
| segment127|
+-----------+
| segment128|
+-----------+
5.5只有一个rollback segment,即只有1024个undo log segment,就表示只能有1024个并发事务(线程)去执行undo
如果用不到undo,其实可以超过1024个线程
在5.6中支持128*1024个并发执行undo线程
1.2 undo log的保存
undo默认保存在ibdata,即系统表空间中
再回顾下,ibdata1中有哪些东西?
double Write
元数据信息(数据字典)
undo信息(5.6后可分离),分开放可避免竞争
innodb_undo_directory
innodb_undo_logs
innodb_undo_tablespaces
insert buffer/change buffer
在MySQL5.7以后,Rollback Segment从128个小到96个,剩余的32个rollback segment预留给临时表空间(ibtmp1)使用
1.3 undo log的内容
undo log header
undo log records(两种)
1、insert undo log record 记录insert
2、update undo log record, 记录update和delete(trx_undo_upd_exist_rec,trx_undo_del_mark_rec,trx_undo_upd_del_rec)
undo是逻辑日志,记录了每一行修改的值(前后项)
之前说的redo写prepare,就是把上图中红色框框部分修改为prepare状态(redo记录页的变化,undo也是一种页)
tips;
- 一个undo log是由很多undo log record组成,因为一个undo包含很多记录
- insert和update两种undo处理方式不一样,存放在不同段里面,是因为undo的回收对于insert操作,只要被插入了就可以被回收,而update操作,即使事物提交了,这个undo也不能马上被回收(mvcc详见下节分析)