前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >A quick introduction to innodb_ruby (2.对innodb_ruby的简单介绍)

A quick introduction to innodb_ruby (2.对innodb_ruby的简单介绍)

作者头像
冬天里的懒猫
发布2020-08-17 17:00:41
7930
发布2020-08-17 17:00:41
举报

本文基于2014年3月innodb_ruby的0.8.8版本。 在前文《学习innoDB核心之旅》中,我在innodb_ruby的项目中引入了一个新的库和命令行工具。现在我来展示一下他的一些功能。我不会尝试解释所有公开的innoDB结构,因为那会让演示偏离我的本意。我们稍后会再来介绍这些结构。

安装 innodb_ruby

如果你熟悉ruby和gems或者你恰好有一个良好配置的ruby环境。我会定期讲innodb_ruby gems推送到RubyGems中,所以你只需要执行:

gem install innodb_ruby

如果这还不起作用,你肯能需要检查下RubyGems手册,重试你的安装工作。或者放弃一切希望。 当你有一个可以工作的安装,你应该有一个innodb_space命令在你的路径中:

 innodb_space 
Error: File must be provided with -f argument

Usage: innodb_space -f <file> [-p <page>] [-l <level>] <mode> [<mode>, ...]

生成数据

对于这些示例,我们需要更多的行,以便正确的检查不同的数据结构。确保运行了一个足够新的服务器,mysql5.5就很好。并启用了Barracuda表。启用innodb_file_per_table。用一点Ruby创建并填充一个非常简单的表。

#!/usr/bin/env ruby

require "mysql"

m = Mysql.new("127.0.0.1", "root", "", "test")

m.query("DROP TABLE IF EXISTS t")

m.query("CREATE TABLE t (i INT UNSIGNED NOT NULL, PRIMARY KEY(i)) ENGINE=InnoDB")

(1..1000000).to_a.shuffle.each_with_index do |i, index|
  m.query("INSERT INTO t (i) VALUES (#{i})")
  puts "Inserted #{index} rows..." if index % 10000 == 0
end

这讲生成一个包含100万行的表,为了让这个事情更加有趣,采用了随机插入的方式。大约有48M,共计3071个16KB的数据页。 请注意,如果你想在家里尝试做这个,你会想看显示全球的状态,像innodb_buffer_pool_pages_dirty邓所有脏页在刷新之前,因为下面的工具将访问磁盘上的表空间文件。没有配合innoDB运行的实例。

检查表空间文件

innodb_space最高级的概述之一space-page-type-regions,他对给定的页面类型每个相邻的块打印一行。

$ innodb_space -f test/t.ibd space-page-type-regions
start       end         count       type                
0           0           1           FSP_HDR             
1           1           1           IBUF_BITMAP         
2           2           1           INODE               
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内部实现细节的情况下,你可以看到一些InnoDB的存储结构(FSP_HDR, IBUF_BITMAP, and INODE pages)。实际表索引页和空闲空间分配的页。 列出每个索引实际上是每个文件段或者每个索引的FSEG,在页面中消耗的空间也相当有趣:

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

每个索引都有一个内部的文件段,用于non-leaf页,和另外一个leaf文件段。用于leaf页。页面可能被分配给一个文件段,但是当前未使用(类型为FREE (ALLOCATED))。因此,fill_factor将显示以使用与未使用的比率。记住,这与索引页有多满没有关系,那是另外一回事。

检查单个页

页面转储模式转储他所直到的关于单个页面的内容,他目前严重依赖于典型的Ruby的pretty-printer模块来打印。这是未来需要清理的一件大事。innodb_ruby库首先使用最小的innodb:Page累来解析文件。然后使用公共标提中的类型字段 可选地将不同的页面类型交给专门的类进行进一步的解析。如innodb::Page::index用于类型索引。 一个好的开始页面应该是第一个索引页面,它是上面创建的测试表的索引树的根节点,位于第三页:

$ innodb_space -f test/t.ibd -p 3 page-dump

初始行回告诉你哪个类正在处理这个页面:

#<Innodb::Page::Index:0x007fe304855360>:

接下来打印FIL标题:

fil header:
{:checksum=>621772966,
 :offset=>3,
 :prev=>nil,
 :next=>nil,
 :lsn=>102947976,
 :type=>:INDEX,
 :flush_lsn=>0,
 :space_id=>1}

FIL的页眉和页脚对所有页面类型都是通用的,并且主要包含关于页面本身的信息。 以下是根据页面类型提供的其他信息,对于索引页,以下信息被转储:

  • 页眉,关于索引页的信息
  • fseg头信息,与此索引所使用的文件段的空间管理相关的信息
  • 页面不同部分大小的汇总,以字节为单位,空闲空间,数据空间,记录大小等。
  • 系统记录,infimum和supremum
  • 页目录内容,用来使记录搜索更有效
  • 用户记录,用户存储的实际数据,除非加载了记录describer,否则不会解析其中的字段

查看索引空间的消耗情况

通过使用space-index-pages-summary模式,可以看到所有的索引中一些最有用的空间消耗相关的数据:

$ innodb_space -f test/t.ibd space-index-pages-summary | head -n 10
page        index   level   data    free    records 
3           15      2       26      16226   2       
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    

这允许您查看数据量和可用空间,以及表的记录数。 如果有一个工作的gnuplot并且安装了gnuplot gem,也可以很容易地制作一个有用的虽然不是很漂亮的信息散点图:

$ innodb_space -f test/t.ibd space-index-pages-free-plot
Wrote t_free.png

space-index-free-plot生成的图如下: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNxhbhBl-1597373920913)(1076193C84654D49A9E38D64E21C9D5B)] Free Space图标:Y轴表示每个页面中的空闲的空间量,X轴是页码,也表示文件偏移量。

解读行数据

为了在检查真正的表的时候真正有用,需要为innodb_ruby提供一些理解表模式的方法。这事通过一个可以动态加载describer的类来实现的,这事innodb_ruby库的一个方面,他还没有得到很好的文档激励,或者还没有得到很好的设计,一个简单的描述类为上面的表如下:

class SimpleTDescriber < Innodb::RecordDescriber
  type :clustered
  key "i", :INT, :UNSIGNED, :NOT_NULL
end

如果这个类保存在simple_t_describer.rb文件中。它可以加载在innodb_space -r <文件>,启动 -d <类>参数:

$ innodb_space -f test/t.ibd -r /path/to/simple_t_describer.rb -d SimpleTDescriber <mode>

加载一个工作记录描述器主要做两件事:

  • 在页面转储模式下启用记录解析和转储。这将导致:key和:row被填充到转储的记录中。并使得事务ID和滚动指针kkey可用,他们存储在key字段和非key字段之间,因此至少不知道如何解析字段的情况下是不可访问的。
  • 允许使用所有的索引递归函数,包括索引递归模式。解析记录的能力是唯利解析innoDB内部的B+树节点指针记录,他将B+树页面链接在一起。

可以使用一些带有完整记录的示例页面转储,test_t_page_3_page_dump.txt(索引根页面)和test_t_page_4_page_dump.txt索引页面。

递归一个索引

一旦记录描述可用,索引可以使用index-recurse进行递归:

$ innodb_space -f test/t.ibd -r /path/to/simple_t_describer.rb -d SimpleTDescriber -p 3 index-recurse
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) -> ()
      RECORD: (i=5) -> ()

这实际上将按升序遍历B+树,基本上是一个全表扫描。同时打印遇到的每个节点的一些信息,并将用户记录转储到叶子页面上,这里有一个更大的示例输出:test_t_page_3_index_recurse.txt

结束语

希望这事一个有用的第一次介绍,未来还会有更多介绍。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 安装 innodb_ruby
  • 生成数据
  • 检查表空间文件
  • 检查单个页
  • 查看索引空间的消耗情况
  • 解读行数据
  • 递归一个索引
  • 结束语
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档