Undo Log

MySQL版本: 8.0

InnoDB使用MVCC来解决事务的并发控制,而其中Undo Log是MVCC的重要组成部分。一条Undo Log对应一个事务中的一条读写语句,而Undo Log了被修改的记录的旧版本数据,当其他的事务需要读取该记录的旧版本时,通过Undo Log可以回溯到需要的版本的数据.

这里我们仅仅介绍Undo Log的相关数据结构和设计,后面的博文会介绍MVCC和InnoDB其他事务细节.

Undo Log数据结构

Undo Tablespace

Undo tablespace定义了回滚数据结构innodb_rollback_segments用来存放Undo Log,Undo tablespace默认的最小数量是2个,在MySQL启动的时候被创建: storage/innobase/srv/srv0start.cc:srv_start()调用srv_undo_tablespaces_init().

Undo Tablespace数据结构

storage/innobase/include/trx0purge.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct Tablespace {
/*
* ...
*/
private:
/** Undo Tablespace ID. */
space_id_t m_id;

/** Undo Tablespace number, from 1 to 127. This is the
7-bit number that is used in a rollback pointer.
Use id2num() to get this number from a space_id. */
space_id_t m_num;

/*
* ...
*/

/** List of rollback segments within this tablespace.
This is not always used. Must call init_rsegs to use it. */
Rsegs *m_rsegs; /* 回滚段 */
};

回滚段

回滚段的数据结构是trx_rseg_t,Undo Tablespace中的Rsegs仅仅是trx_rseg_tstd::vector封装:

每个Undo Tablespace中有128个回滚段. 每个回滚段用来管理Undo Log信息,一个回滚段的Undo Log数量由InnoDB的Page Size决定,在默认16KB的情况下,一个回滚段有1024个Undo Slots.

Undo Log

事务的四种操作会产生Undo Log:

  1. INSERT operations on user-defined tables
  2. UPDATE and DELETE operations on user-defined tables
  3. INSERT operations on user-defined temporary tables
  4. UPDATE and DELETE operations on user-defined temporary tables

Undo Log各数据结构关系

undo_log

Undo Log的Record格式

Update操作的Record格式

undo_update_record

Insert操作的Record格式

undo_insert_record