注册 登录
  • 欢迎访问"运维那点事",推荐使用Google浏览器访问,可以扫码关注本站的"微信公众号"。
  • 如果您觉得本站对你有帮助,那么可以扫码捐助以帮助本站更好地发展。

使用innodb_ruby分析Innodb内部结构

MySQL InnoDB 彭东稳 424次浏览 已收录 0个评论

一、innodb_ruby介绍

如果你想了解MySQL InnoDB内部结构,不好意思,官方在5.7版本之前并没有什么好的工具。所以你只能自己写一个工具去分析表空间文件或使用别人开源的工具,比如innodb_ruby。在MySQL 5.7版本,官方加强了innochecksum工具,使之也可以简单分析表空间,比如查看页类型统计信息等。但跟Jeremy Cole大神带来的Innodb格式化分析工具innodb_ruby相比还是弱了点(可以对比一下相同的功能)。innodb_ruby工具的强大之处在于可以将Innodb内部存储的信息多方位格式化的解释给大家,让人更清晰的理解InnoDB的内部结构。它是一款非常轻量级的应用,同时存在bug风险,不建议给生产环境使用。但是我们在测试环境就可以很好的了解该工具和该工具带来的便利。

README中是这样说的:

  • 一款学习工具,让你很轻松的理解InnoDB架构。
  • 一款教学工具,通过ruby的irb的交互式界面,可以看到InnoDB的架构与发生的变化。
  • 一款调查工具,InnoDB引擎不会告诉你它在磁盘正在做那些任务或者做过那些任务。例如,我们可以获取页的饱和度,每页具体含有多少记录,B+Tree的具体架构等详细内容。
  • 一款调试工具,当一些行为或操作会影响到数据结构的时候,可以通过innodb_ruby工具直观的审查,确保与期望的结果相同。

二、innodb_ruby安装

此工具是使用Ruby写的,所以自然要安装Ruby环境。然后使用RubyGems进行安装innodb_ruby,所以自然也要安装RubyGems。我这里在CentOS下,直接就是用YUM安装了。

以root身份安装:

以指定用户身份安装:

运行:

RubyGems(简称 gems)是一个用于对 Ruby 组件进行打包的 Ruby 打包系统。 它提供一个分发 Ruby 程序和库的标准格式,还提供一个管理程序包安装的工具。RubyGems的功能类似于Linux下的yum工具,使用它可以方便的从远程服务器下载并安装Rails。

三、使用方法

有两种方式运行innodb_space。

针对单个空间文件(ibdata或.ibd):

选项 参数 描述
-F <文件名> 加载表空间文件(系统表空间或独立表空间)

针对将自动加载每个文件的表空间文件的系统表空间:

选项 参数 描述
-s <文件名> 加载系统表空间文件(例如ibdata1)
-T <表名> 使用给定的表名,格式DB_NAME/TABLE_NAME。
-I <索引名称> 使用给定的索引名称。

四、功能介绍

先创建一些测试数据。

在这个表中,插入b列长度为7000,因此可以人为的方式使目前每个页(每页16k)只能存放两条记录。

  • Space File Structure(表空间文件结构)

system-spaces

在该模式下,innodb_space列出所有物理对象的数量。

space-indexes

列出表空间中所有索引统计信息(系统空间或每个文件表空间)

name:索引的名称,PRIMARY代表的就是聚集索引,因为InnoDB表是聚集所以组织表,行记录就是聚集索引;idx_c就是辅助索引的名称。

root:索引中根节点的page号;可以看出聚集索引的根节点是第3个page(为什么是从第三个page开始,看下文space-page-type-regions),辅助索引的根节点是第4个page。

fseg:page的说明,internal表示非叶子节点或属于根节点,leaf表示叶子节点(也就是数据页)。

used:索引使用了多少个page,可以看出聚集索引的根节点点使用了1个page,叶子节点使用了3个page;辅助索引idx_c的叶子节点使用了1个page。

allocated:索引分配了多少个page,可以看出聚集索引的根节点分配了1个page,叶子节点分配了3个page;辅助索引idx_c的叶子节点分配了1个page

fill_factor:索引的填充度,所有的填充度都是100%。

space-page-type-regions

遍历空间中的所有页面,统计每个类型的页共占用了多少页。

start:从第几个page开始。

end:从第几个page结束。

count:占用了多少个page。

type:page的类型。

从上面的结果可以看出:“FSP_HDR”、“IBUF_BITMAP”、“INODE”是分别占用了0,1,2号的page,从3号page开始才是存放数据和索引的页(Index),占用了3~7号的page,共5个page。

接下来,根据得到的聚集索引和辅助索引的根节点来获取索引上的其他page的信息。

space-page-type-summary

遍历所有页面并按类型打印总页数总计。

space-extents-illustrate

统计所有的页在表空间的饱和度信息,每个页面显示彩色块(按index/purpose着色),根据页面中的数据量调整大小。

space-lsn-age-illustrate

统计所有的页在表空间的饱和度信息,每个页面显示彩色块 (按页面修改LSN的年龄着色)。

  • Page Structure(页结构)

page-account

解释单个页面的用途。

page-dump

打印页结构信息,需要了解InnoDB页结构。

page-records

汇总页面内的所有记录。

上面的结果是解析聚集索引根节点页的信息,1行就代表使用了1个page。所以,叶子节点共使用了3个page,根节点使用了1个page,这是一棵高度为2的B+树,跟space_indexes的解析结果一致。

Record 126: (a=1) → #5

a = 1,代表的就是表中a为1的记录,因为a是主键。

-> #5,代表的是指向5号page。

Record 126: (a=5) → #5,整行的意思就是5号page的a最小值是1,包含了1~2的行记录。

注意:page号并不是连续的。如果想打印出具体行数据,直接“-p 5”就可以打印出具体记录,聚集索引的叶子节点是包含了行记录的所有数据。

同理,解析辅助索引idx_c,但是需要注意的是,在解析辅助索引是,需要加上“-I idx_c”。

从上面可以看出,辅助索引idx_c的key是c列,对应主键。叶子节点共使用了1个page,这棵B+树高度为1。你可以多构造一点数据,这样,这里显示的信息与3号page类似,比如“(c=1) -> #9”,然后在9号页面会显示“(c=1) → (a=1)”。

page-directory-summary

页目录字典记录。

从owned可以看出,每个字典一般包含4~8个数据记录,这里的infimum和supremum是page的下(上)确界。

page-illustrate

详细说明一个页面的内容,并且根据类型进行着色显示。

  • Index Structure(索引结构)

index-recurse

通过递归整个B+树(通过递归扫描所有页面,而不仅仅是按列表的叶子页面)来执行索引扫描(执行完整索引扫描):

可以看到主键(这里是a)与记录的对应关系。

查看辅助索引,可以看到辅助索引是直接索引他对应的主键。

index-record-offsets

将索引作为索引递归进行递归处理,但在索引页中打印每条记录的偏移量。

index-level-summary

打印给定级别的所有索引页面的摘要信息。一般level 0就是叶子节点、大于level 0的就是非叶子节点(可能是非叶子节点或根节点,要看B+树高度)。

  • Record Structure(记录结构)

record-dump

给定记录偏移量,打印记录的详细说明及其包含的数据。

  • Record History(记录历史)

record-history

显示给定记录的unod日志。

undo-history-summary 

显示所有变动过的记录。

  • Additional exploration(额外探索)

space-lists

显示表空间列表统计信息(free, free_frag, full_frag, free_inodes, and full_inodes),包括列表中的第一个和最后一个页面的列表长度和列表节点信息。

space-list-iterate

迭代列表中的所有范围,并在列表中显示范围或inode。

space-inodes-summary

打印表空间中每个inode的摘要信息。

<参考>

https://github.com/jeremycole/innodb_ruby/wiki

https://blog.csdn.net/chuck_perry/article/details/64441289


如果您觉得本站对你有帮助,那么可以支付宝扫码捐助以帮助本站更好地发展,在此谢过。
喜欢 (0)or分享 (0)
关于作者:

您必须 登录 才能发表评论!