innodb中的undolog 详解

2021/06/05 1098点热度 0人点赞 0条评论

5ycode
5ycode

被管理耽误的架构师。工作、学习过程中的知识总结与分享,jvm,多线程,架构设计,经验分享等。
28篇原创内容

公众号

mysql事务-innodb中的redolog详解

继上一篇redo log之后详解下 undo log.

什么是undolog? 是为了保证数据库的原子性,增加的增删改逻辑记录日志。

  • undo log是逻辑日志

  • redo log记录的是物理日志 有两个作用:

  • 事务回滚

  • 多个行版本控制(MVCC)

undo log的存储方式

undo 日志链表

一共有四种undo日志链表,在生成undo日志的过程中按需生成

  • 普通表 insert undo 链表

  • 普通表 update undo 链表

  • 临时表 insert undo 链表

  • 临时表 update undo 链表

innodb对undo的管理采用段的方式来管理undo日志,rollback segment 称为回滚段,每个回滚段中有1024个 undo log segment。

  • 默认分配在系统表空间第5号页面上维护回滚段

  • 5.5之前的innodb只有一个回滚段

  • 5.5开始支持128个回滚段

  • 通过innodb_rollback_segments 或 innodb_undo_logs 自定义回滚段的个数;

  • 0 以及33~127号回滚段对应的普通表,默认分配在系统表空间

  • 1~32 号回滚段在临时表空间,对临时表操作;

  • 可以通过innodb_undo_directory 指定undo表空间所在的目录

  • 可以通过innodb_undo_tablespaces定义undo表空间的数据

  • 一个事务最多占用4个槽位,128*1024/4=32768 最少能开启的事务数量(粗略),要根据普通表和临时表的占比来推算

  • 当事务过多,回滚段中的槽位被占满后报 too many active concurrent transactions

基础

表的table_id:

  • innodb中每个表在创建的时候,会将元数据保存在information_schema中,其中innodb_sys_tables中保存了表的table_id,表示这个表在该实例里唯一的标识; 

  • 图片

事务ID(trx_id):

  • 事务id通过聚簇索引和记录关联(在聚簇索引对应记录的隐藏列里);

  • 事务id在增删改时生产;

  • 通过事务id将对应undo链表串起来

  • mysql中的一个全局变量,先使用后+1;

  • 存储在系统表空间页号为5页面中的名为MaxTrxId的里;

  • 这个值在内存中操作,每当为256的倍数时,刷新到系统表空间的文件里;

  • 系统重启,会从系统表空间加载该值,并+256 初始化到内存中(防止未刷新到磁盘丢失,不加256容易造成重启后重复);

undo no :

  • 每个事务中都是从0开始递增; 

    图片

  • TRX_UNDO_STATE: 本undo页面链表处于什么状态

  • TRX_UNDO_ACTIVE:活跃状态,一个活跃的事务正在向这个undo页面链表写入undo日志,等到崩溃重启时,会识别这个状态,进行事务的回滚操作;

  • TRX_UNDO_CACHED: 被缓存状态,此时该页面链表可以被重用;

  • TRX_UNDO_TO_FREE: 等待被释放状态

  • TRX_UNDO_TO_PURGE: 等待被purge状态,提交后不能被重用,处于此状态

  • TRX_UNDO_PREAPARED: 处于准备使用阶段

图片

undo日志流程

insert undo日志流程

图片

delete undo日志流程

图片

update undo 日志流程

图片

崩溃恢复流程

图片

yxkong

这个人很懒,什么都没留下

文章评论