mysql undo详谈
1 简介:undo是MVCC机制的基础部分之一
2 作用:为了实现可重复性读,存储历史数据
3 存储:5.6以前undo都存储在内存和ibdata1中,5.6以后undo可以独立成单独的文件,更可以进行truncate表空间,减少磁盘容量
4 处理过程
1 针对于 update/delete操作.会进行记录快照数据.统称为update_undo.针对insert操作,会进行记录但是随后会删除,毕竟没人关注这个。
2 本文不考虑对临时表的undo段操作
5 回滚段三阶段
1 事务开始后,针对读写事务,会预先在内存中分配一个回滚段
2 事务进行中,将历史数据写入undo page中
1 事务commit
2 事务rollback
1:对于标记删除的记录清理标记删除标记;
2:对于in-place更新,将数据回滚到最老版本;
3:对于插入操作,直接删除聚集索引和二级索引记录(row_undo_ins)。
6 purge清理undo段
1 清理事务提交后不需要的undo信息 从回滚段的HISTORY 文件链表上开始遍历释放Undo log segment,由于history 链表是按照trx no有序的,因此遍历truncate直到完全清除,或者遇到一个还未purge的undo log(trx no比当前purge到的位置更大)时才停止。
2 清理已经被打上delete标记的数据实现物理删除
相关参数变量 innodb_purge_threads=1(默认值)
7 相关 innodb status信息
Purge done for trx's n:o < 219761368 undo n:o < 0 state: running but idle
History list length 3228
purge done 代表已经完成的事务量
n:0< 代表正在执行的purge
state:代表线程是否繁忙
history-list-length 代表存在的undo个数 16KX3228 代表使用的undo大小 一页是16K
8 关于ibdata1暴涨的原因
1 共享表空间=>改用独立表空间
2 大量undo暴涨了ibdata的空间
1 存在未完成的事务,可以通过hsitory list观察计算
2 执行过大事务(一般都是这种原因造成的)
9 补充
当我们delete数据行时,是对数据页中要删除的数据行做标记“deleted”,事务提交(速度快);
10 undo的构成和布局
1 128个回滚段构成,32个回滚段用于系统的临时表空间,96个回滚段用于事务
2 每个回滚段维护了一个段头页,在该page中又划分了1024个slot,每个slot又对应到一个undo log对象,因此理论上InnoDB最多支持 96 * 1024个普通事务。
3 独立表空间的space id都是从1 开始,0被预留在ibdata中.space id必须是连续分配的,不能断档
4 8.0之前的版本默认只能创建128个回滚段