共計(jì) 2226 個(gè)字符,預(yù)計(jì)需要花費(fèi) 6 分鐘才能閱讀完成。
本篇內(nèi)容主要講解“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指針”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓丸趣 TV 小編來帶大家學(xué)習(xí)“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指針”吧!
一、引入
我們知道每一條記錄在聚集索引上都有如下的分布:
rowid(主鍵)+DB_TRX_ID+DB_ROLL_PTR+ 其他字段
這樣格式其中 DB_TRX_ID+DB_ROLL_PTR 作為一致性讀的關(guān)鍵信息存儲(chǔ)下來,其中 DB_TRX_ID 在存儲(chǔ)上占用 6 字節(jié),DB_ROLL_PTR 在存儲(chǔ)上占用 7 字節(jié)。那么 DB_ROLL_PTR 是如何解析到 undo 上的呢,這也是一位朋友問的問題。
下面是 trx0types.h 中對(duì)這部分的定義
/** 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 實(shí)際上都是 64 位非負(fù)整數(shù)
typedef unsigned __int64 ib_uint64_t;
二、函數(shù)流程
我大概看了一下流程如下:
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 作為傳出參數(shù)。傳出訪問到的 undo
- trx_undo_decode_roll_ptr // 做 roll_ptr 的解析工作獲取 segment id\page no\offset
- 開 MTR 獲取 latch 準(zhǔn)備拷貝
- 拷貝 trx_undo_rec_copy
- 提交 MTR
實(shí)際上解析工具由 trx_undo_decode_roll_ptr 完成。
三、實(shí)際解析
其實(shí)解析挺簡單,都是寫死了的。
/***********************************************************************//**
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 */// 最后一位}
到此,相信大家對(duì)“怎么理解 MySQL 中 Innodb DB_ROLL_PTR 指針”有了更深的了解,不妨來實(shí)際操作一番吧!這里是丸趣 TV 網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!