进行rollback segment header的初始化
Posted liyanyan665
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进行rollback segment header的初始化相关的知识,希望对你有一定的参考价值。
调用 trx_sys_create_rsegs进行:
说明一下关于innodb_undo_logs参数和innodb_rollback_segments参数,他们作用就是设置rollback segment 的个数,本文以128为例。
根据注释和代码innodb_undo_logs已经是个淘汰的参数,应该用innodb_rollback_segments代替。
这两个参数默认是就是TRX_SYS_N_RSEGS及 128 其实不用设置的。本文也用128进行讨论。
参数 innodb_rollback_segments
static mysql_SYSVAR_ULONG(rollback_segments, srv_rollback_segments,
PLUGIN_VAR_OPCMDARG,
"Number of rollback segments to use for storing undo logs.",
NULL, NULL,
TRX_SYS_N_RSEGS, /* Default setting */
1, /* Minimum value */
TRX_SYS_N_RSEGS, 0); /* Maximum value */
参数 innodb_undo_logs
static MYSQL_SYSVAR_ULONG(undo_logs, srv_undo_logs,
PLUGIN_VAR_OPCMDARG,
"Number of rollback segments to use for storing undo logs. (deprecated)",
NULL, innodb_undo_logs_update,
TRX_SYS_N_RSEGS, /* Default setting */
1, /* Minimum value */
TRX_SYS_N_RSEGS, 0); /* Maximum value */
TRX_SYS_N_RSEGS 就是128
下面是注释和代码
/* Deprecate innodb_undo_logs. But still use it if it is set to
non-default and innodb_rollback_segments is default. */
if (srv_undo_logs < TRX_SYS_N_RSEGS)
ib::warn() << deprecated_undo_logs;
if (srv_rollback_segments == TRX_SYS_N_RSEGS)
srv_rollback_segments = srv_undo_logs;
初始化rollback segments 段
n_noredo_created = trx_sys_create_noredo_rsegs(n_tmp_rsegs); //创建 32个 临时rollback segments
我们这里不准备考虑临时rollback segments
建立 95个(33-128) 普通rollback segments
ulint new_rsegs = n_rsegs - n_used; //eg:128 -33 = 95
for (i = 0; i < new_rsegs; ++i) //对每个rollback segment进行初始化
ulint space_id;
space_id = (n_spaces == 0) ? 0
: (srv_undo_space_id_start + i % n_spaces); //获取 undo space_id 采用 取模的方式循环初始化 1 2 3 4
ut_ad(n_spaces == 0
|| srv_is_undo_tablespace(space_id));
if (trx_rseg_create(space_id, 0) != NULL)
我们能够注意到这里是i % n_spaces的取模方式n_spaces为我们innodb_undo_tablespaces参数设置的值,因此每个rollback segment 是轮序的方式分布到4个不同的undo tablespace中的。
具体的rollback segment header初始化过程
如上是trx_rseg_create调用trx_rseg_header_create完成的。步骤大概如下:
1、建立rollback segment
block = fseg_create(space, 0, TRX_RSEG + TRX_RSEG_FSEG_HEADER, mtr); //建立一个回滚段,返回段头所在的块
2、初始化TRX_RSEG_MAX_SIZE和TRX_RSEG_HISTORY_SIZE信息
/* Initialize max size field */
mlog_write_ulint(rsegf + TRX_RSEG_MAX_SIZE, max_size,
MLOG_4BYTES, mtr);
/* Initialize the history list */
mlog_write_ulint(rsegf + TRX_RSEG_HISTORY_SIZE, 0, MLOG_4BYTES, mtr);
flst_init(rsegf + TRX_RSEG_HISTORY, mtr);
3、初始化每个undo segment header所在的page no
for (i = 0; i < TRX_RSEG_N_SLOTS; i++) //TRX_RSEG_N_SLOTS 为1024 初始化每个槽 值为 4字节指向 undo segment header的page no
trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
初始化的情况下我们看到指向的page no都是 FIL_NULL,说明没有分配任何实际的undo segment。
4、整个rollback segment 初始化完成后将space id和page no 写回到 transaction system segment header中。
sys_header = trx_sysf_get(mtr); //获取 5号 block指针 跳过 FIL_PAGE_DATA 38U
trx_sysf_rseg_set_space(sys_header, rseg_slot_no, space, mtr); //设置space
trx_sysf_rseg_set_page_no(sys_header, rseg_slot_no, page_no, mtr); //设置 no
下面是 rollback segment header的结构
/* Transaction rollback segment header */
/*-------------------------------------------------------------*/
#define TRX_RSEG_MAX_SIZE 0 /* Maximum allowed size for rollback
segment in pages */
#define TRX_RSEG_HISTORY_SIZE 4 /* Number of file pages occupied
by the logs in the history list */ //history 链表大小
#define TRX_RSEG_HISTORY 8 /* The update undo logs for committed
transactions */ //链表头base node 他们通常调用include/fut0lst.ic中的函数进行更改
#define TRX_RSEG_FSEG_HEADER (8 + FLST_BASE_NODE_SIZE)
/* Header for the file segment where
this page is placed */
#define TRX_RSEG_UNDO_SLOTS (8 + FLST_BASE_NODE_SIZE + FSEG_HEADER_SIZE)
/* Undo log segment slots */ //
/*-------------------------------------------------------------*/
作为 base node的 TRX_RSEG_HISTORY,我们可以看到定义如下:
/* We define the field offsets of a base node for the list */
#define FLST_LEN 0 /* 32-bit list length field */
#define FLST_FIRST 4 /* 6-byte address of the first element
of the list; undefined if empty list */
#define FLST_LAST (4 + FIL_ADDR_SIZE) /* 6-byte address of the
last element of the list; undefined(http://www.my516.com)
if empty list */
#define FIL_ADDR_PAGE 0 /* first in address is the page offset */
#define FIL_ADDR_BYTE 4 /* then comes 2-byte byte offset within page*/
#endif /* !UNIV_INNOCHECKSUM */
#define FIL_ADDR_SIZE 6 /* address size is 6 bytes */
多了一个长度
到这里128 rollback segment已经初始化完成,并且,每个都包含1024个 undo segment slots。
以上是关于进行rollback segment header的初始化的主要内容,如果未能解决你的问题,请参考以下文章
整个rollback segment 初始化完成后将space id和page no 写回到 transaction system segment header中。
_OFFLINE_ROLLBACK_SEGMENTS 和 _CORRUPTED_ROLLBACK_SEGMENTS的区别
Rollback Segment Configuration & Tips (Doc ID 69464.1)