1、背景
之前讲过undo日志类型,本篇文章再来具体讲解一下undo日志页结构。
2、undo日志页结构
【1】fil_page_undo_log页
innodb中最基本的存储单位是页,undo日志也是存储在页上的,页的类型为fil_page_undo_log,其页面结构如下:
其中undo page header是undo日志所特有的,其结构如下:
字段含义为:
字段 | 字节大小 | 含义 |
---|---|---|
trx_undo_page_type | 2 | 本页存储undo日志类型,分为两大类:trx_undo_inset和trx_undo_update,一个页面只能存储一种类型 |
trx_undo_page_start | 2 | 本页中第一条undo日志地址 |
trx_undo_page_free | 2 | 本页可以写入undo日志的空闲地址 |
trx_undo_page_node | 12 | 链表节点 |
【2】undo页面组成的链表
通过undo page header的trx_undo_page_node属性能让undo页组成一个链表,链表中的第一个页被称为first undo page,第二个页被称为normal undo page,上面讲过有两大类undo日志类型,一个页只能存储相同的页类型,所以一个事务的所有插入操作可以组成一个insert undo链表,所有删除和更新操作可以组成一个update undo链表,临时表也需要记录undo日志,所以一个事务可能产生四个undo页组成的链表,这些链表是用到的时候再分配。
【3】undo log segment
每个undo日志页组成的链表都对应一个段,叫undo log segment,这个段存储在链表的第一个页也就是first undo page页中,其结构如下:
其中undo log segment header用来存储段结构信息,其结构如下:
字段含义如下:
字段 | 字节大小 | 含义 |
---|---|---|
trx_undo_state | 2 | 链表对应的段状态: trx_undo_active:活跃状态,一个活跃的事务正在往这个段里面写入undo日志 trx_undo_cached:被缓存的状态,该undo页面对应的来吧等待被其它实物重用 trx_unod_to_free:对insert undo链表来说,在它对应的事务提交之后,该链表不能被重用就处于这种状态 trx_undo_to_purge:对update undo链表来说,在它对应的事务提交之后,该链表不能被重用就处于这种状态 trx_undo_prepared:包含处于prepare阶段的事务产生的undo日志 |
trx_undo_last_log | 2 | 本undo页面链表中最后一个undo log header的位置 |
trx_undo_fseg_header | 10 | 本undo页链表对应的段信息 |
trx_undo_page_list | 16 | undo页链表基节点,这个基节点就存在于first undo page页中 |
【4】undo log header
同一个事务向同一个undo页面链表中写入的undo日志算一个组,组信息存储在链表第一个页的undo log header属性中,first undo page页可以这样表示:
undo log header结构如下:
字段含义如下:
字段 | 字节大小 | 含义 |
---|---|---|
trx_undo_trx_id | 8 | 生成本组undo日志的事务id |
trx_undo_trx_no | 8 | 事务提交后生成的序号,用来标记事务的提交顺序 |
trx_undo_del_marks | 2 | 标记本组undo日志是否包含由于delete mark操作产生的undo日志 |
trx_undo_log_start | 2 | 本组undo日志第一条undo日志在页面中的地址 |
trx_undo_xid_exists | 1 | 本组undo日志是否包含xid信息 |
trx_undo_dict_trans | 1 | 标记本组undo日志是不是由ddl语句产生 |
trx_undo_table_id | 8 | ddl语句操作的表table_id |
trx_undo_next_log | 2 | 下一组undo日志在页面中开始的偏移量 |
trx_undo_prev_log | 2 | 上一组undo日志在页面中开始的偏移量 |
trx_undo_history_node | 12 | history链表的节点 |
【5】重用undo页面
为了节省空间就有了重用undo页面,重用undo页面需要满足以下条件:
- 1、undo页面链表只包含一个undo页面
- 2、该undo页面链表使用空间超过该页面空间的3/4
- 3、insert undo链表是覆盖写入
- 4、update undo链表是追加写入
3、总结
通过undo日志能保证事务回滚,也就是原子性,上面讲过insert操作对应的undo日志可以直接删除,update和delete操作的不能,就是为了mvcc,多版本并发控制,后面再来讲解mvcc。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论