用innodb_ruby分析InnoDB的页管理

时间:2022-07-23
本文章向大家介绍用innodb_ruby分析InnoDB的页管理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一个最小的空表

我创建了一个空表(模式无关紧要)来说明InnoDB页面管理结构的“最小”状态。space-page-type-regions模式将汇总同一页面类型的所有相邻区域的类型:

$ 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)  

该表为IBD空间文件分配了标准页:FSP_HDR、IBUF_BITMAP、INODE和(空)索引的根索引页。还有两个未使用的空闲(已分配)页面。 space-lists模式可以用于汇总空间中的区段描述符和inode列表:

$ 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         

只有free_frag区段描述符有全部的列,并且其中只有一个区段。free_inodes列表中只有一个INODE页面。 free_frag列表的内容可以使用space-list-iterate模式进行检测,该模式将打印输出一个图形,说明一个区段列表中所有区段内页面的使用情况("#“表示该页面已被使用,”."表示该页面是空闲的):

$ innodb_space -f test/e.ibd -L free_frag space-list-iterate
start_page  page_used_bitmap                                                
0           ####............................................................

空间中所有索引中的文件段可以用space-indexes模式进行汇总:

$ 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%       

只有内部文件段分配了页,并且它只有一个分配的页。index-fseg-internal-lists模式将汇总内部文件段中的区段列表:

$ 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           

这三个列表都是空的,因为这个空表没用分配任何完整的区段,那么使用过的page去哪了呢?那是一个片段页面,可以通过index-fseg-internal-frag-pages 列出。

$ 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    

这是一个最小的状态,大部分情况下是空的账簿结构和一个索引页。让我们看看一个包含一些真实数据的表:

一个有100万行的表

在对innodb_ruby的简要介绍中,我创建了一个包含100万行的表。我们将在这里的示例中使用相同的表。 总共有2,165页,其中大多数类型索引作为一个典型的表将是:

$ 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的列表,实际上有一些区段是空闲的,通常也有一个区段是free_frag:

$ 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        ................................................................

free_frag范围描述符列表显示了一些“片段”页面被使用:

$ innodb_space -f test/t.ibd -L free_frag space-list-iterate
start_page  page_used_bitmap                                                
0           ######################################..........................

索引文件段显示了分配给叶文件段的页面,这也是预期的(B+树中只有3个非叶内部页面来管理2,137个叶页面):

$ 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%      

你还可以看到,叶的索引文件段分配的页面多余它实际使用的页,显示了85.52%的填充因子,这是由于InnoDB的片段填充因子。他在库存MySQL中固定为87.5%,现在这个值你可以自行配置,这要归功于FackeBook的MysqlBug 64673。 由于内部索引文件段只有3个页面,正如预期的那样,文件段列表都是空的:

$ 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

叶索引文件段列表显示非常繁忙,有32个完整的区段和6个不完整的区段:

$ 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        

此外,叶索引文件段已经分配了所有可能的32个片段页(在以上任何完整区段之前):

$ 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        ################################################################

正如预期的那样,not_full区段全部被部分填充:

$ 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        #...............................................................

你可以在这里看到InnoDB的页面分割优化:为了在磁盘上按顺序排列数据,它已经多次将第一个页面移出(这是由于页号的“暗示”,这是不确定的)。未来将对这种行为进行更深入的研究。