[翻译] 使用 innodb_ruby 探索 InnoDB 的页面管理
本系列文章翻译自 中的 文章 。共 16 篇,本文为第 5 篇。原文链接:
因翻译水品有限,为了避免对读者造成误解,一些专有名词的翻译会在其后用标记出原文。
使用 innodb_ruby 探索 InnoDB 的页面管理
在 ()一文中,我提到了 项目以及其中的命令行工具。在后续 ()一文中,我介绍了 命令行工具的安装和一些快速演示。
在上一篇文章 ()中,我描述了 的区段、文件段以及空闲空间管理相关的结构。接下来,我会提供一些使用 检查真实的表中这些结构的示例。
一个最小化的空表
我创建了一个空表(表结构不重要)来说明 页面管理结构的“最小化”状态。 命令会汇总出同一类型页面的所有连续区域:
$ innodb_space -f test/e.ibd space-page-type-regions
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)
通过输出可以看到,这张表已经在 文件中分配了“标准”页面: 页面、 页面、 页面、 页面(用于空索引的根),还有两个未使用的 页面 。
命令会汇总空间中的区段描述符链表和 链表:
$ innodb_space -f test/e.ibd space-lists
name length f_page f_offset l_page l_offset
free 0 0 0 0 0
free_frag 1 0 158 0 158
full_frag 0 0 0 0 0
full_inodes 0 0 0 0 0
free_inodes 1 2 38 2 38
只有 区段描述符链表中有条目,并且其中只有一个区段。 链表中有一个 页面。
可以使用 命令检查 链表的内容,该命令将打印一个图形,说明在区段列表中所有区段内页面的使用情况(表示该页面已使用, 表示页面是空闲的) :
$ innodb_space -f test/e.ibd -L free_frag space-list-iterate
start_page page_used_bitmap
0 ####............................................................
译者注:实际上由上文的 命令输出可以看出, 目前只分配了个页面, 的输出中第一个区段中不应该有个或者。如果你使用最新版本的运行上述命令会发现,只会输出,表示有4个页面已使用,2个页面未使用。
可以将空间中所有索引的文件段进行汇总:
$ innodb_space -f test/e.ibd space-indexes
id root fseg used allocated fill_factor
16 3 internal 1 1 100.00%
16 3 leaf 0 0 0.00%
只有“内部”文件段分配了页面,并且只分配了一个页面。 模式将汇总“内部”文件段中的区段链表:
$ innodb_space -f test/e.ibd -p 3 index-fseg-internal-lists
name length f_page f_offset l_page l_offset
free 0 0 0 0 0
not_full 0 0 0 0 0
full 0 0 0 0 0
这三个列表都是空的,因为这个空表没有分配任何完整的区段。那么,已使用的一个页面在哪里呢?这是一个“碎片”页面,可以使用 模式列出:
$ innodb_space -f test/e.ibd -p 3 index-fseg-internal-frag-pages
page index level data free records
3 16 0 0 16252 0
这是表的“最小化”状态———空间文件中大部分是空白的簿记[]结构,只有一个 页面。接下来让我们来看一个包含一些实际数据的表。
一个有一百万行的表
在 ()一文中,我创建了一个包含 行的表。我们将在下文的示例中使用相同的表。
通过 命令可以看到总共有 个 类型的页面:
$ innodb_space -f test/t.ibd space-page-type-regions
start end count type
3 37 35 INDEX
38 63 26 FREE (ALLOCATED)
64 2188 2125 INDEX
2189 2239 51 FREE (ALLOCATED)
2240 2240 1 INDEX
2241 2303 63 FREE (ALLOCATED)
2304 2304 1 INDEX
2305 2367 63 FREE (ALLOCATED)
2368 2368 1 INDEX
2369 2431 63 FREE (ALLOCATED)
2432 2432 1 INDEX
2433 2495 63 FREE (ALLOCATED)
2496 2496 1 INDEX
2497 2687 191 FREE (ALLOCATED)
译者注:上面的输出只展示了 类型和 类型的页面,如果你实际执行这个命令,应该还会输出其他类型的页面,比如 页面、 页面、 页面。
注意,在 页面的连续区域中间有一些 页面组成的间隙。这是因为 不能保证按顺序使用空闲页面,而且有关批量数据加载的许多优化也会导致页面无序使用。(更多关于页面拆分和这些优化的内容将在以后的文章中介绍)
再来看看看空间中的链表,有一些区段在 链表中,也有一些区段在 链表中:
$ innodb_space -f test/t.ibd space-lists
name length f_page f_offset l_page l_offset
free 2 0 1758 0 1798
free_frag 1 0 158 0 158
full_frag 0 0 0 0 0
full_inodes 0 0 0 0 0
free_inodes 1 2 38 2 38
如预期的一样, 区段描述符链表中的区段 所有页面都是空闲的:
$ innodb_space -f test/t.ibd -L free space-list-iterate
2560 ................................................................
2624 ................................................................
区段描述符链表中的区段有一些“碎片”页面被使用:
$ innodb_space -f test/t.ibd -L free_frag space-list-iterate
start_page page_used_bitmap
0 ######################################..........................
通过 命令可以看出大量已使用的页面被分配给叶文件段,也正如预期的一样,只有个“内部”页面来管理 中的个(译者注:原文为,但结合下文输出应该为)“叶”页面:
$ innodb_space -f test/t.ibd space-indexes
id root fseg used allocated fill_factor
15 3 internal 3 3 100.00%
15 3 leaf 2162 2528 85.52%
你还可以看到叶文件段分配的页面比实际使用的多,(“填充因子”)为 。这是由于 的 段填充因子[] 在 中固定为 。不过现在在 中是可以进行配置的,这要归功于 提交的 。
因为内部文件段只有 个页面,所以文件段列表都是空的:
$ innodb_space -f test/t.ibd -p 3 index-fseg-internal-lists
name length f_page f_offset l_page l_offset
free 0 0 0 0 0
not_full 0 0 0 0 0
full 0 0 0 0 0
个已使用的页面被分配为碎片页:
$ innodb_space -f test/t.ibd -p 3 index-fseg-internal-frag-pages
page index level data free records
3 15 2 26 16226 2
36 15 1 14521 1401 1117
37 15 1 13585 2341 1045
而叶子索引文件段的链表则非常“繁忙”,有 (译者注:原文这里为,结合下文输出,应为)个 区段和 个 区段:
$ innodb_space -f test/t.ibd -p 3 index-fseg-leaf-lists
name length f_page f_offset l_page l_offset
free 0 0 0 0 0
not_full 6 0 1518 0 1718
full 33 0 198 0 1478
此外,叶文件段已经分配了所有可以分配的 个碎片页面(在分配完整区段之前会先分配碎片页面):
$ innodb_space -f test/t.ibd -p 3 index-fseg-leaf-frag-pages
page index level data free records
4 15 0 9812 6286 446
5 15 0 15158 860 689
6 15 0 10912 5170 496
7 15 0 10670 5412 485
8 15 0 12980 3066 590
9 15 0 11264 4808 512
10 15 0 4488 11690 204
11 15 0 9680 6418 440
12 15 0 9306 6800 423
13 15 0 9658 6434 439
14 15 0 10032 6062 456
15 15 0 9988 6108 454
16 15 0 9570 6530 435
17 15 0 9130 6978 415
18 15 0 8844 7266 402
19 15 0 11770 4300 535
20 15 0 9020 7092 410
21 15 0 8646 7462 393
22 15 0 9746 6354 443
23 15 0 11066 5014 503
24 15 0 8910 7204 405
25 15 0 11748 4322 534
26 15 0 10978 5094 499
27 15 0 11132 4940 506
28 15 0 9350 6750 425
29 15 0 13508 2526 614
30 15 0 14938 1082 679
31 15 0 14520 1506 660
32 15 0 9086 7016 413
33 15 0 9724 6368 442
34 15 0 10978 5102 499
35 15 0 9504 6592 432
正如预期的那样,区段都是“满”的:
$ innodb_space -f test/t.ibd -p 3 -L full index-fseg-leaf-list-iterate
start_page page_used_bitmap
64 ################################################################
128 ################################################################
192 ################################################################
256 ################################################################
320 ################################################################
384 ################################################################
448 ################################################################
512 ################################################################
576 ################################################################
640 ################################################################
704 ################################################################
768 ################################################################
832 ################################################################
896 ################################################################
960 ################################################################
1024 ################################################################
1088 ################################################################
1152 ################################################################
1216 ################################################################
1280 ################################################################
1344 ################################################################
1408 ################################################################
1472 ################################################################
1536 ################################################################
1600 ################################################################
1664 ################################################################
1728 ################################################################
1792 ################################################################
1856 ################################################################
1920 ################################################################
1984 ################################################################
2048 ################################################################
2112 ################################################################
区段都是部分空闲的,正如预期的那样:
$ innodb_space -f test/t.ibd -p 3 -L not_full index-fseg-leaf-list-iterate
start_page page_used_bitmap
2176 #############...................................................
2240 #...............................................................
2304 #...............................................................
2368 #...............................................................
2432 #...............................................................
2496 #...............................................................
你可以在这里看到 页面拆分优化的一点“影子”: 为了在磁盘上按顺序排列数据, 多次从 区段的第一个页面分配页面(页码是最可疑之处)。未来我们将对这种行为进行更深入的研究。
译者注:这里的“可疑之处”指的是上述 区段链表的 之间的间隔都是相同的64。