MySQL阅读笔记——15.undo日志

  事务执行过程中遇到意外或者手动通过rollback语句执行 回滚 操作,需要记录 撤销日志 ,即:undo日志,只有在一个事务第一次执行 增、删、改 操作时才会为该事务分配一个 事务id,在MySQL5.5之前undo日志是记录在系统表空间(MySQL数据目录下的ibdata1就是系统表空间),长事务占用大量存储空间

事务id生成:

  1. 服务器内存维护全局变量,分配事务id时,将该变量分配给事务并将变量增1

  2. 当变量的值是256的倍数时,将该变量刷新到 系统表空间 5号页面中Max Trx ID位置处,该变量占8字节

  3. 重启时,将Max Trx ID属性加载到内存,该值加256赋值给全局变量(因上次关机,全局变量可能大于Max Trx ID,也就是说在上次关机之前[Max Trx ID,Max Trx ID+256]之间的事务id以今分配给一些事务,如果重启后再在此区间内赋值可能会产生冲突)

  undo日志记录的到FIL_PAGE_UNDO_LOG类型页面,该页面可以从 系统表空间 分配,也可以从 undo日志 表空间分配。

15.1 undo日志写入过程

  没有被重用的undo页面,第一个页面写入undo日志前填充Undo Page HeaderUndo Log Segment HeaderUndo Log Header这三个部分,其他页面只填充Undo Page Header 当链表只有一个undo页面并且已经使用空间小于整个页面的3/4,则该页面可被重用,其中insert undo链表的页面可以直接覆盖之前的undo日志,而update undo链表的页面不能覆盖之前的undo日志

15.2 回滚段

  回滚段只包含一个 Rollback Segment Header 类型的页面,该页面存放当前事务用到的所有undo双向链表的基节点所在页号,这些页号称为 undo solt

  回滚段页面各个属性:

  1. TRX_RSEG_MAX_SIZE:该事务回滚段管理所有undo页面数量总和最大值(默认值0xFFFFFFFF)

  2. TRX_RSEG_HISTORY_SIZEHistorty链表占用页面数量

  3. TRX_RSEG_HISTORYHistorty链表基节点

  4. TRX_RSEG_FSEG_HEADER:回滚段的Segment Header结构(即:INODE Entry 结构所处表空间ID、所在页面页号、所在页面内的偏移量)

  5. TRX_RSEG_UNDO_SLOTS:各双向链表的页号集合,即:undo solt集合(最大存储1024个)

 

  一个回滚段页面(Rollback Segment Header类型页面)存储1024个undo solt(undo双向链表头节点),当undo solt被占满时会报错Too many active concurrent transactions (可能重新执行时有别的事务提交了,该事务就可以被分配Undo页面链表了) 当一个事务被提交,如果它的undo slot能被重用则该链表的 TRX_UNDO_STATE 属性被设置为 TRX_UNDO_CACHED,被重用的页面加入到一个双向链表等待被重用(分为insert、update两种重用链表),如果undo slot指向页面不能被重用,如果是insert undo则将 TRX_UNDO_STATE 属性设置为 TRX_UNDO_TO_FREE 释放页面并且将对应的undo slot设置为 FIL_NULL;如果是update undoTRX_UNDO_STATE 属性被设置为 TRX_UNDO_TO_PRUGE 并且将对应的undo slot设置为 FIL_NULL,然后将对应的undo写入到 History链表

MySQL中有128个回滚段,每个回滚段只有一个 Rollback Segment Header 类型页面,每个回顾i页面有1024个 undo slot,也就是可以保存1024个undo链表(即如果每个事务只分配一个undo页面链表,最大可以同时执行1024*128个事务),这128个 Rollback Segment Header 类型页面存储在系统表空间5号页面 0号、33~127号回滚段记录普通表的undo链表(0号回滚段必须在系统表空间,33~127可以在系统表空间也可以在用户定义undo表空间),1~32号回滚段记录临时表的undo链表,必须在临时表空间 通过启动参数innodb_undo_directory指定undo表空间所在目录如果没有配置则默认undo表空间就是系统表空间,通过innodb_undo_tablespaces指定undo表空间数量,如果指定了undo表空间则0号回滚段处于不可用状态,undo表空间当文件增大到一定程度会自动截断成一个小文件,而系统表空间只能不断增长

15.7 分配undo页面过程

  1. 首先到系统表空间5号页面获取一个Rollback Segment Header页面的地址(获取回滚段)

  2. 如果回滚段两个cached链表有可重用的undo slot则分配给事务

  3. 如果没有可重用的undo slot则找一个可用的空闲undo slot(即:undo slot值为 FIL_NULL

  4. 如果undo slotcached链表获取则不用分配Undo Log Segment,否则需要重新分配一个Undo Log Segment

  5. 并发执行不同的事务也可以在相同的回滚段,只要undo slot不同即可

原文地址:https://www.cnblogs.com/leon618/p/13783364.html