共计 2226 个字符,预计需要花费 6 分钟才能阅读完成。
本篇内容主要讲解“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指针”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指针”吧!
一、引入
我们知道每一条记录在聚集索引上都有如下的分布:
rowid(主键)+DB_TRX_ID+DB_ROLL_PTR+ 其他字段
这样格式其中 DB_TRX_ID+DB_ROLL_PTR 作为一致性读的关键信息存储下来,其中 DB_TRX_ID 在存储上占用 6 字节,DB_ROLL_PTR 在存储上占用 7 字节。那么 DB_ROLL_PTR 是如何解析到 undo 上的呢,这也是一位朋友问的问题。
下面是 trx0types.h 中对这部分的定义
/** Row identifier (DB_ROW_ID, DATA_ROW_ID) */typedef ib_id_t row_id_t;/** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */typedef ib_id_t trx_id_t;/** Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR) */ typedef ib_id_t roll_ptr_t;
而 ib_id_t 实际上都是 64 位非负整数
typedef unsigned __int64 ib_uint64_t;
二、函数流程
我大概看了一下流程如下:
trx_undo_prev_version_build //Build a previous version of a clustered index record
- roll_ptr = row_get_rec_roll_ptr(rec, index, offsets); // 获取 rollback 指针
- rec_trx_id = row_get_rec_trx_id(rec, index, offsets); // 获取 TRX_ID
- trx_undo_get_undo_rec(roll_ptr, rec_trx_id, heap, is_redo_rseg,index- table- name, undo_rec))// 此处获取前版本, 获取后放到 undo_rec 中
- trx_undo_get_undo_rec_low(roll_ptr, heap, is_redo_rseg); //undo_rec 作为传出参数。传出访问到的 undo
- trx_undo_decode_roll_ptr // 做 roll_ptr 的解析工作获取 segment id\page no\offset
- 开 MTR 获取 latch 准备拷贝
- 拷贝 trx_undo_rec_copy
- 提交 MTR
实际上解析工具由 trx_undo_decode_roll_ptr 完成。
三、实际解析
其实解析挺简单,都是写死了的。
/***********************************************************************//**
Decodes a roll pointer. */ // 从高位到低位依次是 第 1 位是否是 insert // 第 2 到 8 位是 segmentid// 第 9 到 40 位为 page no // 第 41 位到 56 位为 OFFSETUNIV_INLINEvoidtrx_undo_decode_roll_ptr(/*=====================*/
roll_ptr_t roll_ptr, /*! in: roll pointer */
ibool* is_insert, /*! out: TRUE if insert undo log */
ulint* rseg_id, /*! out: rollback segment id */
ulint* page_no, /*! out: page number */
ulint* offset) /*! out: offset of the undo
entry within page */{#if DATA_ROLL_PTR_LEN != 7# error DATA_ROLL_PTR_LEN != 7 #endif#if TRUE != 1# error TRUE != 1 #endif
ut_ad(roll_ptr (1ULL 56));
*offset = (ulint) roll_ptr 0xFFFF; // 获取低 16 位 为 OFFSET
roll_ptr = 16; // 右移 16 位
*page_no = (ulint) roll_ptr 0xFFFFFFFF;// 获取 32 位为 page no
roll_ptr = 32;// 右移 32 位
*rseg_id = (ulint) roll_ptr 0x7F;// 获取 7 位为 segment id
roll_ptr = 7;// 右移 7 位
*is_insert = (ibool) roll_ptr; /* TRUE==1 */// 最后一位}
到此,相信大家对“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指针”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
正文完