Bootstrap

[翻译] 使用 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。