标签:MySQL
标签:MySQL结构
标签:MySQL undo
一、undo结构:
rseg0预留在系统表空间ibdata中;
rseg 1~rseg 32这32个回滚段存放于临时表的系统表空间中;
rseg33~ 则根据配置存放到独立undo表空间中(如果没有打开独立Undo表空间,则存放于ibdata中)
1. trx_sys->rseg_array
表空间的第4个page(page-3)内主要存储该表空间内的每个回滚段的header page no,构成一个数组,数组大小为回滚段数量,数组的每一项占据4B.
所有回滚段都记录在trx_sys->rseg_array,数组大小为128,用于维护回滚段相关信息;
2. purge_sys->purge_queue
事务提交后,需要purge的回滚段会被放到purge队列上(purge_sys->purge_queue)。
3. 回滚段的管理结构,Header Page
Rollback Segment的Header Page内有undo log slot数组,该数组大小为1024,数组的每一项代表一个undo log。
事务运行需要记录undo log时会寻找当前空闲slot分配undo log。
4. trx_undo_t的管理结构UNDO PAGE HEADER,还有几个负责分配资源的list
TRX_UNDO_STATE:标记事务状态,有TRX_UNDO_ACTIVE/TRX_UNDO_PREPARED等状态
TRX_UNDO_LAST_LOG:最后一个undo日志的在undo page中的偏移,通过该字段可快速定位最新undo日志的位置
TRX_UNDO_FSEG_HEADER:header page内的TRX_UNDO_FSEG_HEADER为undo page链表的头部,每个undo page通过其TRX_UNDO_PAGE_NODE将自身串联在链表中。
TRX_UNDO_PAGE_LIST:该trx_undo_t所有的PAGE构成的双向链表头部。占据16个字节。通过它就可以遍历该trx_undo_t的所有undo page,进而找到所有的undo log内容,设计得还是很巧妙的.
5. UNDO_PAGE_HDR (undo log链表的节点)
TRX_UNDO_PAGE_TYPE:该undo page记录的undo类型,占据2个字节,目前有TRX_UNDO_INSERT、TRX_UNDO_UPDATE两种类型
TRX_UNDO_PAGE_START:该undo page记录的数据起始位置,undo log从page内的该偏移处写入,就是指图中的Data Region的起始偏移
TRX_UNDO_PAGE_FREE:该undo page记录的数据起始位置,undo log从page内的该偏移处写入,就是指图中的Data Region的起始偏移
TRX_UNDO_PAGE_NODE:这里是前后向指针,用于串联一个trx_undo_t内的所有UNDO PAGE,每个指针大小为6B,总大小12B
6. UNDO LOG格式
二、事务回滚段分配和使用:
1.分配回滚段
根据操作类型决定分配哪种类型的回滚段,采用round-robin的轮询方式来赋予回滚段给事务。
临时表回滚段被赋予trx->rsegs->m_noredo,普通读写操作的回滚段被赋予trx->rsegs->m_redo。
2.在回滚段中分配undo slot
(1).判断类型选择对应的list ,insert 和 delete/update 分开记录undo,因此需要从回滚段单独分配Undo slot。
(2).总是从cahced list上分配trx_undo_t,如果没有cache的trx_undo_t,则需要从回滚段上分配一个空闲的undo slot(trx_undo_create),并创建对应的undo页,进行初始化;
(3).已分配给事务的trx_undo_t会加入到链表trx_rseg_t::insert_undo_list或者trx_rseg_t::update_undo_list上;
(4).初始化trx_undo_t相关信息(trx_undo_mem_init_for_reuse),将trx_undo_t::state设置为TRX_UNDO_ACTIVE;
三、修改过程:
1. 将原状态信息写undo log buffer
2. 写undo log对应的redo log buffer -> redo log file
3. 修改db buffer中的data block,通过回滚指针指向undo log构建一致性视图
4. 写data block对应的redo log buffer -> redo log file
5. undo log写入undo表空间
6. 刷脏data block 到 double write buffer
7. double write buffer 写入到ibdata文件
8. 刷脏data block写入表空间文件
四、事务Commit:
如果当前的undo log只占一个page,且占用的header page大小使用不足其3/4时(TRX_UNDO_PAGE_REUSE_LIMIT),则状态设置为TRX_UNDO_CACHED,该undo对象会随后加入到undo cache list上;
如果是Insert_undo(undo类型为TRX_UNDO_INSERT),则状态设置为TRX_UNDO_TO_FREE;
如果不满足a和b,则表明该undo可能需要Purge线程去执行清理操作,状态设置为TRX_UNDO_TO_PURGE。
五、前滚和回滚的恢复:
事务系统初始化(回滚段初始化)
从最近的Checkpoint 往后扫描到的Redo Log记录将被应用到各个数据文件中
从Undo Log中恢复处于'ACTIVE'状态的事务,重新生成read view
使用Undo Log回滚未提交的'ACTIVE'状态的事务
处于PREPARE状态的事务,如果打开了binlog且在binlog有找到对应事务的日志则重新提交,否则回滚