天天看点

mysql事务-innodb中的undolog 详解

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,表示这个表在该实例里唯一的标识;
  • mysql事务-innodb中的undolog 详解

事务ID(trx_id):

  • 事务id通过聚簇索引和记录关联(在聚簇索引对应记录的隐藏列里);
  • 事务id在增删改时生产;
  • 通过事务id将对应undo链表串起来
  • mysql中的一个全局变量,先使用后+1;
  • 存储在系统表空间页号为5页面中的名为MaxTrxId的里;
  • 这个值在内存中操作,每当为256的倍数时,刷新到系统表空间的文件里;
  • 系统重启,会从系统表空间加载该值,并+256 初始化到内存中(防止未刷新到磁盘丢失,不加256容易造成重启后重复);

undo no :

  • 每个事务中都是从0开始递增;
    mysql事务-innodb中的undolog 详解
  • TRX_UNDO_STATE: 本undo页面链表处于什么状态
  • TRX_UNDO_ACTIVE:活跃状态,一个活跃的事务正在向这个undo页面链表写入undo日志,等到崩溃重启时,会识别这个状态,进行事务的回滚操作;
  • TRX_UNDO_CACHED: 被缓存状态,此时该页面链表可以被重用;
  • TRX_UNDO_TO_FREE: 等待被释放状态
  • TRX_UNDO_TO_PURGE: 等待被purge状态,提交后不能被重用,处于此状态
  • TRX_UNDO_PREAPARED: 处于准备使用阶段
mysql事务-innodb中的undolog 详解

undo日志流程

insert undo日志流程

mysql事务-innodb中的undolog 详解

delete undo日志流程

mysql事务-innodb中的undolog 详解

update undo 日志流程

mysql事务-innodb中的undolog 详解

崩溃恢复流程

mysql事务-innodb中的undolog 详解

如果觉得对你有帮助,请关注公众号:5ycode,后续会不断更新哦

mysql事务-innodb中的undolog 详解

继续阅读