前言?
最近看到了 何登成 大佬的 "深入MySQL源碼 -- Step By Step" 的 pdf 呵呵 似乎是找到了一些 方向?
之前對于 mysql 方面的東西, 更多的僅僅是簡單的使用[業務中的各種增刪改查], 以及一些面試題的背誦?
這里會參照?MySQL Internals Manual?來大致的看一下 innodb 里面的 record 的存儲相關, 這些是深入了解 mysql 的基礎?
我們這里主要是會了解一下兩種?RowFormat : Redundant 和 Compact?
本文內容對應的是?mysql調試的一些基礎方法 里面的?查看一下 rec 的數據信息
MySQL Internals Manual?-?22.1?InnoDB Record Structure
以下截圖參照自?MySQL Internals Manual?
這里的說明是基于?RowFormat -?Redundant?
總的來說一個 record 分成了三個部分 : 各個字段的偏移(Field Start Offsets), 元數據信息(Extra Bytes), 記錄信息(Field Contents)?
Field Start Offsets : 描述的是 record 中的各個字段在?Field Contents 中的偏移, 以此偏移可以確認各個字段的數據信息?
Extra Bytes : 描述的是?record 的元數據, 包括了 刪除標記, minRecord標記, 字段數量, "Field Start Offsets" 的單位, 記錄編號, 下一個記錄的偏移 等等信息?
Field Contents : 里面存儲的是具體的數據信息?
22.1.1.3?FIELD CONTENTS 里面介紹了一個實例的案例, 剖析一個實際的記錄在內存中的數據分布情況, 以及拆解每一個字節的邏輯意義, 可以移步文檔看一下, 這里就不截圖了, 請自行查閱文檔?
源碼中的說明 remOrec.cc |?remOrec.ic |?remOrec.h
我們再來根據源碼中的注釋結合 來看一下?
里面注釋寫的相當詳盡, 因此 建議多讀注釋, 以方便理解?
"深入MySQL源碼 -- Step By Step" 里面也提到了 "不放過源碼中的每一處注釋"?
RowFormat -?Redundant?
注釋里面描述的內容 和 上面 MySQL Internals Manual?-?22.1?InnoDB Record Structure 一致?
Extra Bytes 的結構信息?
RowFormat -?Compact?
注釋里面描述的內容 就是 Compact 的 RowFormat 的格式了,?MySQL Internals Manual?上面我沒有找到?
總的來說一個 record 分成了三個部分 : 各個字段的偏移(Field Start Offsets), 元數據信息(Extra Bytes), 記錄信息(Field Contents)?
Field Start Offsets : 描述的是 record 中的各個長度可變字段在?Field Contents 中的偏移, table元數據中固定字段偏移 結合 此偏移 可以確認所有字段的偏移, 進而可以確認各個字段的數據信息?
Extra Bytes : 描述的是?record 的元數據, 包括了 null字段標記, 刪除標記, minRecord標記, 記錄編號, 下一個記錄的偏移?等等信息?
Field Contents : 里面存儲的是具體的數據信息?
Extra Bytes 的結構信息?
RowFormat -?Redundant 實際案例剖析?
# ROW_FORMAT = Redundant 的內存情況
(lldb) x 0x12c694000 -c 0x100
0x12c694000: 1c 18 8c aa 00 00 00 03 ff ff ff ff ff ff ff ff ...�....��������
0x12c694010: 00 00 00 00 00 1a b2 d5 45 bf 00 00 00 00 00 00 ......��E�......
0x12c694020: 00 00 00 00 00 07 00 02 00 c6 00 04 00 00 00 00 .........�......
0x12c694030: 00 ad 00 02 00 01 00 02 00 00 00 00 00 00 00 00 .�..............
0x12c694040: 00 00 00 00 00 00 00 00 00 17 00 00 00 07 00 00 ................
0x12c694050: 00 02 00 f2 00 00 00 07 00 00 00 02 00 32 08 01 ...�.........2..
0x12c694060: 00 00 03 00 88 69 6e 66 69 6d 75 6d 00 09 03 00 .....infimum....
0x12c694070: 08 03 00 00 73 75 70 72 65 6d 75 6d 00 1a 15 11 ....supremum....
0x12c694080: 0a 04 00 00 10 0b 00 ad 80 00 00 01 00 00 00 00 .......�........
0x12c694090: 3b 07 87 00 00 01 3a 01 10 80 00 00 1c 6a 65 72 ;.....:......jer
0x12c6940a0: 72 79 19 15 11 0a 04 00 00 18 0b 00 74 80 00 00 ry..........t...
0x12c6940b0: 02 00 00 00 00 3b 08 88 00 00 01 3e 01 10 80 00 .....;.....>....
0x12c6940c0: 00 16 6c 75 63 79 00 00 00 00 00 00 00 00 00 00 ..lucy..........
0x12c6940d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x12c6940e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x12c6940f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................# 0x12c694050
0x12c694050: 00 02 00 f2 00 00 00 07 00 00 00 02 00 32 08 01 ...�.........2..
0x12c694060: 00 00 03 00 88 69 6e 66 69 6d 75 6d 00 09 03 00 .....infimum....
0x12c694070: 08 03 00 00 73 75 70 72 65 6d 75 6d 00 1a 15 11 ....supremum....
0x12c694080: 0a 04 00 00 10 0b 00 ad 80 00 00 01 00 00 00 00 .......�........
0x12c694090: 3b 07 87 00 00 01 3a 01 10 80 00 00 1c 6a 65 72 ;.....:......jer
0x12c6940a0: 72 79 19 15 11 0a 04 00 00 18 0b 00 74 80 00 00 ry..........t...
0x12c6940b0: 02 00 00 00 00 3b 08 88 00 00 01 3e 01 10 80 00 .....;.....>....
0x12c6940c0: 00 16 6c 75 63 79 00 00 00 00 00 00 00 00 00 00 ..lucy..........# infimum = PAGE_OLD_INFIMUM = 0x65
08 : offset of `infimum`
01 : deleted_flag = 0, min_rec_flag = 0, n_owned = 1
00 00 03 : heap_no = 0, n_fields = 1, 1byte_offs_flag = 1
00 88 : next record pointer -> jerry
69 6e 66 69 6d 75 6d 00 : infimum# supremum = PAGE_OLD_SUPREMUM = 0x74
09 : offset of `supremum`
03 : deleted_flag = 0, min_rec_flag = 0, n_owned = 3
00 08 03 : heap_no = 1, n_fields = 1, 1byte_offs_flag = 1
00 00 : next record pointer -> self
73 75 70 72 65 6d 75 6d 00 : supremum# record jerry : 0x12c694088 # 格式為 redundant row format
1a 15 11 0a 04 : field offset of id, trx_id, poll_ptr, age, name
00 : deleted_flag = 0, min_rec_flag = 0, n_owned = 0
00 10 0b : heap_no = 2, n_fields = 5, 1byte_offs_flag = 1
00 ad : next record offset -> record lucyid = 80 00 00 01 = 1
trx_id = 00 00 00 00 3b 07 = 15111
poll_ptr = 87 00 00 01 3a 01 10
age = 80 00 00 1c = 28
name = 6a 65 72 72 79 = jerry# record lucy : 0x12c6940ad # 格式為 redundant row format
19 15 11 0a 04 : field offset of id, trx_id, poll_ptr, age, name
00 : deleted_flag = 0, min_rec_flag = 0, n_owned = 0
00 18 0b : heap_no = 3, n_fields = 5, 1byte_offs_flag = 1
00 74 : next record offset -> supremumid = 80 00 00 02 = 2
trx_id = 00 00 00 00 3b 08 = 15112
poll_ptr = 88 00 00 01 3e 01 10
age = 80 00 00 16 = 22
name = 6c 75 63 79 = lucy
RowFormat - Compact?實際案例剖析?
# user 對應的數據 當前頁的數據信息, 拆解
(lldb) x 0x1286cc000 -c 0x120
0x1286cc000: 10 aa fb 30 00 00 00 03 ff ff ff ff ff ff ff ff .��0....��������
0x1286cc010: 00 00 00 00 00 1a a2 7d 45 bf 00 00 00 00 00 00 ......�}E�......
0x1286cc020: 00 00 00 00 00 06 00 02 00 b9 80 04 00 00 00 00 .........�......
0x1286cc030: 00 a0 00 02 00 01 00 02 00 00 00 00 00 00 00 00 .�..............
0x1286cc040: 00 00 00 00 00 00 00 00 00 16 00 00 00 06 00 00 ................
0x1286cc050: 00 02 00 f2 00 00 00 06 00 00 00 02 00 32 01 00 ...�.........2..
0x1286cc060: 02 00 1c 69 6e 66 69 6d 75 6d 00 03 00 0b 00 00 ...infimum......
0x1286cc070: 73 75 70 72 65 6d 75 6d 05 00 00 00 10 00 21 80 supremum......!.
0x1286cc080: 00 00 01 00 00 00 00 2b 07 04 00 00 01 56 04 7b .......+.....V.{
0x1286cc090: 80 00 00 1c 6a 65 72 72 79 04 00 00 00 18 ff d0 ....jerry.....��
0x1286cc0a0: 80 00 00 02 00 00 00 00 35 04 83 00 00 01 36 01 ........5.....6.
0x1286cc0b0: 10 80 00 00 16 6c 75 63 79 00 00 00 00 00 00 00 .....lucy.......
0x1286cc0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x1286cc0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x1286cc0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x1286cc0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x1286cc100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x1286cc110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................# 0x1286cc050
0x1286cc050: 00 02 00 f2 00 00 00 06 00 00 00 02 00 32 01 00 ...�.........2..
0x1286cc060: 02 00 1c 69 6e 66 69 6d 75 6d 00 03 00 0b 00 00 ...infimum......
0x1286cc070: 73 75 70 72 65 6d 75 6d 05 00 00 00 10 00 21 80 supremum......!.
0x1286cc080: 00 00 01 00 00 00 00 2b 07 04 00 00 01 56 04 7b .......+.....V.{
0x1286cc090: 80 00 00 1c 6a 65 72 72 79 04 00 00 00 18 ff d0 ....jerry.....��
0x1286cc0a0: 80 00 00 02 00 00 00 00 35 04 83 00 00 01 36 01 ........5.....6.
0x1286cc0b0: 10 80 00 00 16 6c 75 63 79 00 00 00 00 00 00 00 .....lucy.......# infimum = PAGE_NEW_INFIMUM = 0x63
# infimum : 0x1286cc063
0x0 : delete_flag & min_rec_flag
0x1 : number of records owned by the record
0b 0000 0000 0000 0 = 0 = order number of this record
0b 010 = infimum
0x 00 1c = next record offset -> jerry
69 6e 66 69 6d 75 6d 00 = infimum# supremum = PAGE_NEW_SUPREMUM = 0x70
# supremum : 0x1286cc070
0x0 : delete_flag & min_rec_flag
0x3 : number of records owned by the record
0b 0000 0000 0000 1 = 1 = order number of this record
0b 011 = supremum
0x 00 00 = next record offset -> self
73 75 70 72 65 6d 75 6d = supremum# record jerry : 0x1286cc07f # 格式為 compact row format
0x05 : lengthOf('jerry')
0x00 = nulls
0x0 : delete flag
0x0 : number of records owned by the record
0b 0000 0000 0001 0 = 2 = order number of this record
0b 000 = conventional
0x 00 21 : next record offset -> record lucyrec = 0x80
id = 0x 80 00 00 01 = 1
trx_id = 0x 00 00 00 00 2b 07 = 11015
poll_ptr = 0x 04 00 00 01 56 04 7b
age = 0x 80 00 00 1c = 28
name = 6a 65 72 72 79 = jerry# record lucy : 0x1286cc0a0 # 格式為 compact row format
0x04 : lengthOf('lucy')
0x00 = nulls
0x0 : delete flag
0x0 : number of records owned by the record
0b 0000 0000 0001 1 = 3 = order number of this record
0b 000 = conventional
0x ff d0 : next record offset -> supremumrec = 0x80
id = 0x 80 00 00 02 = 2
trx_id = 0x 00 00 00 00 35 04 = 13572
poll_ptr = 0x 83 00 00 01 36 01 10
age = 0x 80 00 00 16 = 22
name = 6c 75 63 79 = lucy
完?
參考
MySQL Internals Manual
深入MySQL源碼 -- Step By Step
mysql調試的一些基礎方法