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详见下节分析)