InnoDB undo log物理结构的初始化

作者按:一直以来,未好好学习 的undo,最近刚好有点时间准备学习一下,本文通过阿里内核月报和自己看代码进行综合总结,如果有误,欢迎拍砖~
水平有限,如果有误请指出 。
一直以来未对 的undo进行好好的学习,最近刚好有点时间准备学习一下,通过阿里内核月报和自己看代码的综合总结一下 。本文环境:
本文描述使用如上参数的设置 。
一、undo 表空间物理文件的建立
本过程调用函数_init进行,栈帧如下:
#0srv_undo_tablespaces_init (create_new_db=true, n_conf_tablespaces=4, n_opened=0x2ef55b0)at /root/mysqlc/percona-server-locks-detail-5.7.22/storage/innobase/srv/srv0start.cc:824#10x0000000001bbd7e0 in innobase_start_or_create_for_mysql () at /root/mysqlc/percona-server-locks-detail-5.7.22/storage/innobase/srv/srv0start.cc:2188#20x00000000019ca74e in innobase_init (p=0x2f2a420) at /root/mysqlc/percona-server-locks-detail-5.7.22/storage/innobase/handler/ha_innodb.cc:4409#30x0000000000f7ec2a in ha_initialize_handlerton (plugin=0x2fca110) at /root/mysqlc/percona-server-locks-detail-5.7.22/sql/handler.cc:871#40x00000000015f9edf in plugin_initialize (plugin=0x2fca110) at /root/mysqlc/percona-server-locks-detail-5.7.22/sql/sql_plugin.cc:1252
本过程主要有如下几个步骤:
for (i = 0; create_new_db && i < n_conf_tablespaces; ++i) //n_conf_tablespaces 为innodb_undo_tablespaces的配置的个数/** Default undo tablespace size in UNIV_PAGEs count (10MB). */const ulint SRV_UNDO_TABLESPACE_SIZE_IN_PAGES =((1024 * 1024) * 10) / UNIV_PAGE_SIZE_DEF;...err = srv_undo_tablespace_create(name, SRV_UNDO_TABLESPACE_SIZE_IN_PAGES); //建立undo文件...
本步骤会有一个注释如下:
/* Create the undo spaces only if we are creating a newinstance. We don't allow creating of new undo tablespacesin an existing instance (yet).This restriction exists becausewe check in several places for SYSTEM tablespaces to be less thanthe min of user defined tablespace ids. Once we implement savingthe location of the undo tablespaces and their space ids thisrestriction will/should be lifted. */
简单的讲就是建立undo 只能在初始化实例的时候,因为space id已经固定了 。
for (i = 0; i < n_undo_tablespaces; ++i) {....err = srv_undo_tablespace_open(name, undo_tablespace_ids[i]); //打开UNDO文件 建立 file node...}
for (i = 0; i < n_undo_tablespaces; ++i) {fsp_header_init( //初始化fsp header 明显 space id 已经写入undo_tablespace_ids[i],SRV_UNDO_TABLESPACE_SIZE_IN_PAGES, &mtr); //SRV_UNDO_TABLESPACE_SIZE_IN_PAGES 默认的undo大小 10MB}
其中部分代码如下:
mlog_write_ulint(header + FSP_SPACE_ID, space_id, MLOG_4BYTES, mtr);mlog_write_ulint(header + FSP_NOT_USED, 0, MLOG_4BYTES, mtr);mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr);mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr);mlog_write_ulint(header + FSP_SPACE_FLAGS, space->flags,MLOG_4BYTES, mtr);mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr);flst_init(header + FSP_FREE, mtr);flst_init(header + FSP_FREE_FRAG, mtr);flst_init(header + FSP_FULL_FRAG, mtr);flst_init(header + FSP_SEG_INODES_FULL, mtr);flst_init(header + FSP_SEG_INODES_FREE, mtr);
这些都是fsp的内容 。
做完这个步骤只是生成了4个大小为10MB的 undo 文件,并且已经加入到文件体系,但是里面没有任何类容 。
二、中的初始化
本步骤调用 ages->进行,本步骤除了初始化以外还会初始化其(page no 5)信息如下:
/* Create the trx sys file block in a new allocated file segment */block = fseg_create(TRX_SYS_SPACE, 0, TRX_SYS + TRX_SYS_FSEG_HEADER,mtr); //建立segmentbuf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);ut_a(block->page.id.page_no() == TRX_SYS_PAGE_NO);page = buf_block_get_frame(block); //获取内存位置mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_TRX_SYS, //写入block 的类型MLOG_2BYTES, mtr);.../* Start counting transaction ids from number 1 up */mach_write_to_8(sys_header + TRX_SYS_TRX_ID_STORE, 1); // 初始化TRX_SYS_TRX_ID_STORE/* Reset the rollback segment slots.Old versions of InnoDBdefine TRX_SYS_N_RSEGS as 256 (TRX_SYS_OLD_N_RSEGS) and expectthat the whole array is initialized. */ptr = TRX_SYS_RSEGS + sys_header;len = ut_max(TRX_SYS_OLD_N_RSEGS, TRX_SYS_N_RSEGS)* TRX_SYS_RSEG_SLOT_SIZE;//TRX_SYS_OLD_N_RSEGS 为256个memset(ptr, 0xff, len); //将slot的信息的全部初始化为ffptr += len;ut_a(ptr