Mysql innodb b树中的内部节点是如何物理存储的?
innodb中的非叶b树节点是如何物理表示的 回想一下,b-树(更具体地说是b+树)既有叶节点也有非叶节点。在b+树中,所有叶节点都位于非叶节点树或“内部”节点树下,并指向实际包含行数据的页面Mysql innodb b树中的内部节点是如何物理存储的?,mysql,tree,innodb,b-tree,Mysql,Tree,Innodb,B Tree,innodb中的非叶b树节点是如何物理表示的 回想一下,b-树(更具体地说是b+树)既有叶节点也有非叶节点。在b+树中,所有叶节点都位于非叶节点树或“内部”节点树下,并指向实际包含行数据的页面 我知道非叶节点存储在非叶节点段中,并使用类似于数据页的页面。我已经找到了大量关于数据页如何物理存储的文档,但是我还没有找到任何关于非叶索引页的内容。在《学习InnoDB:核心之旅》中,我介绍了InnoDB_图表项目来记录InnoDB内部,它提供了本文中使用的图表。稍后,在对innodb_ruby的快速介绍
我知道非叶节点存储在非叶节点段中,并使用类似于数据页的页面。我已经找到了大量关于数据页如何物理存储的文档,但是我还没有找到任何关于非叶索引页的内容。在《学习InnoDB:核心之旅》中,我介绍了InnoDB_图表项目来记录InnoDB内部,它提供了本文中使用的图表。稍后,在对innodb_ruby的快速介绍中,我介绍了innodb_space命令行工具的安装和一些快速演示 InnoDB索引页的物理结构在InnoDB索引页的物理结构中进行了描述。现在,我们将使用一些实际示例来研究InnoDB如何逻辑地构造其索引 术语旁白:B+树、根、叶和层 InnoDB的索引使用B+树结构。当数据不适合内存并且必须从磁盘读取时,B+树特别有效,因为它确保访问任何请求的数据都需要固定的最大读取次数,仅基于树的深度,可以很好地扩展 索引树从“根”页面开始,其位置是固定的(并永久存储在InnoDB的数据字典中),作为访问树的起点。该树可能与单个根页面一样小,也可能与多级树中数百万个页面一样大 页面被称为“叶”页面或“非叶”页面(在某些上下文中也称为“内部”或“节点”页面)。叶页包含实际的行数据。非叶页面仅包含指向其他非叶页面或叶页面的指针。树是平衡的,因此树的所有分支都具有相同的深度 InnoDB为树中的每个页面分配一个“级别”:叶页面被分配为级别0,级别向上递增。根页面级别基于树的深度。如果区分很重要,那么所有既不是叶页也不是根页的页面也可以称为“内部”页面 叶页和非叶页 对于叶页和非叶页,每条记录(包括下确界和上确界系统记录)都包含一个“下一条记录”指针,该指针存储到下一条记录的偏移量(在页面内)。链表从下确界开始,按键升序链接所有记录,以上确界结束。记录在页面内没有物理排序(插入时占用任何可用空间);它们唯一的顺序来自它们在链表中的位置 叶页包含非键值,作为每个记录中包含的“数据”的一部分: 非叶页具有相同的结构,但它们的“数据”不是非键字段,而是子页的页码,而不是确切的键,它们表示它们指向的子页上的最小键: 同一级别的页面 大多数索引包含多个页面,因此多个页面按升序和降序链接在一起: 每一页都包含“上一页”和“下一页”的指针(在FIL标题中),对于索引页,指针用于在同一级别上形成页面的双链接列表(例如,叶页,在0级上形成一个列表,在1级上形成一个单独的列表,等等) 单页表格的详细查看 让我们看一下在单个索引页中与B+树相关的大部分内容: 创建并填充表格 上图中使用的测试表可以创建并填充(确保您使用的是innodb_file_per_table并使用Barracuda文件格式): 虽然这个表非常小而且不现实,但它确实很好地演示了记录和记录遍历的工作原理 验证空间文件的基本结构 该表应该与我们之前检查过的内容相匹配,三个标准开销页(FSP_HDR、IBUF_BITMAP和INODE)后面是索引根的一个索引页,在本例中是两个未使用的分配页 $innodb_space-f t_btree.ibd空间页类型区域 space index pages summary(空间索引页面摘要)模式将为我们提供每页中的记录计数,并显示预期的3条记录: $innodb_空间-f t_btree.ibd空间索引页摘要 (请注意,space index pages summary还将分配的空页面显示为零记录的空页面,因为这通常是出于打印目的而感兴趣的。) “空间索引”模式将显示主键索引的统计信息,主键索引消耗其内部文件段上的单个页面: $innodb_space-f t_btree.ibd空间索引 设置记录描述符 为了让innodb_ruby解析记录的内容,我们需要提供一个记录描述符,它只是一个ruby类,提供一个返回索引描述的方法: 类SimpleTBTreeDescriber
CREATE TABLE t_btree (
i INT NOT NULL,
s CHAR(10) NOT NULL,
PRIMARY KEY(i)
) ENGINE=InnoDB;
INSERT INTO t_btree (i, s)
VALUES (0, "A"), (1, "B"), (2, "C");
start end count type
0 0 1 FSP_HDR
1 1 1 IBUF_BITMAP
2 2 1 INODE
3 3 1 INDEX
4 5 2 FREE (ALLOCATED)
page index level data free records
3 18 0 96 16156 3
4 0 0 0 16384 0
5 0 0 0 16384 0
id root fseg used allocated fill_factor
18 3 internal 1 1 100.00%
18 3 leaf 0 0 0.00%
{:format=>:compact,
:offset=>125,
:header=>
{:next=>157,
:type=>:conventional,
:heap_number=>2,
:n_owned=>0,
:min_rec=>false,
:deleted=>false,
:field_nulls=>nil,
:field_lengths=>[0, 0, 0, 0],
:field_externs=>[false, false, false, false]},
:next=>157,
:type=>:clustered,
:key=>[{:name=>"i", :type=>"INT", :value=>0, :extern=>nil}],
:transaction_id=>"0000000f4745",
:roll_pointer=>
{:is_insert=>true, :rseg_id=>8, :undo_log=>{:page=>312, :offset=>272}},
:row=>[{:name=>"s", :type=>"CHAR(10)", :value=>"A", :extern=>nil}]}
ROOT NODE #3: 3 records, 96 bytes
RECORD: (i=0) -> (s=A)
RECORD: (i=1) -> (s=B)
RECORD: (i=2) -> (s=C)
ROOT NODE #3: 2 records, 26 bytes
NODE POINTER RECORD >= (i=252) -> #36
INTERNAL NODE #36: 1117 records, 14521 bytes
NODE POINTER RECORD >= (i=252) -> #4
LEAF NODE #4: 446 records, 9812 bytes
RECORD: (i=1) -> ()
RECORD: (i=2) -> ()
RECORD: (i=3) -> ()
RECORD: (i=4) -> ()
NODE POINTER RECORD >= (i=447) -> #1676
LEAF NODE #1676: 444 records, 9768 bytes
RECORD: (i=447) -> ()
RECORD: (i=448) -> ()
RECORD: (i=449) -> ()
RECORD: (i=450) -> ()
NODE POINTER RECORD >= (i=891) -> #771
LEAF NODE #771: 512 records, 11264 bytes
RECORD: (i=891) -> ()
RECORD: (i=892) -> ()
RECORD: (i=893) -> ()
RECORD: (i=894) -> ()
{:format=>:compact,
:offset=>125,
:header=>
{:next=>11877,
:type=>:node_pointer,
:heap_number=>2,
:n_owned=>0,
:min_rec=>true,
:deleted=>false,
:field_nulls=>nil,
:field_lengths=>[0],
:field_externs=>[false]},
:next=>11877,
:type=>:clustered,
:key=>[{:name=>"i", :type=>"INT UNSIGNED", :value=>252, :extern=>nil}],
:child_page_number=>4}
Height Non-leaf pages Leaf pages Rows Size in bytes
1 0 1 468 16.0 KiB
2 1 1203 > 563 thousand 18.8 MiB
3 1204 1447209 > 677 million 22.1 GiB
4 1448413 1740992427 > 814 billion 25.9 TiB