进行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)

ibdata中system segment header的初始化

事务嵌套问题总结-rollback-only异常

oralce11G导出备份时空表无法导出