- 积分
- 1533
- UID
- 3
- 阅读权限
- 200
- 注册时间
- 2007-4-1
- 精华
- 在线时间
- 小时
- 最后登录
- 1970-1-1
- 职业
- 1
|
py_innodb_page_info.py可以用来统计innodb数据文件的每个页面类型和偏移等信息,但在使用该脚本时,偶尔会出现如下错误。
$> ./py_innodb_page_info.py /data1/mysqldata/4444/data/db_felix/tbAccount_99.ibd
Traceback (most recent call last):
File "./py_innodb_page_info.py", line 3, in ?
import mylib
File "/home/mysql/mysql_tools/py_innodb_page_info/mylib.py", line 3, in ?
import include
UnicodeDecodeError: 'utf8' codec can't decode bytes in position 12-13: unexpected end of data
由于不懂python,没想去深入解决这个问题。鉴于之前看过InnoDB的物理页面结构,刚好可以用熟悉一点的perl来重写这个页面统计的逻辑,把这个报错的问题解决。
简单原理:
InnoDB 16KB一个页面,页面格式如下:
38B文件头 + 56B页头 + 最大最小值 + 用户记录 + 空闲空间 + 页目录 + 文件结尾信息
只需顺序遍历数据文件,按照页面格式来读取页面,最后列举出每个页面的偏移、页面类型、所属的表空间ID即可;如果是数据页(B-Tree页),也把页面的层级展现出来。
其中,页面偏移、类型、所属表空间等信息,在文件头:
而B-Tree页的页面层级,在页头部分:
下面是所有的InnoDB页面类型:
用perl重写后的代码,执行情况如下:
$> perl innodb_page_info.pl --file=/data1/mysqldata/4444/data/db_felix1/t_202.ibd -v
page_offset[00000000], page_type[File Space Header], space_id[000000cc]
page_offset[00000001], page_type[Insert Buffer Bitmap], space_id[000000cc]
page_offset[00000002], page_type[File Segment inode], space_id[000000cc]
page_offset[00000003], page_type[B-tree Node], space_id[000000cc], page_level[0000]
page_offset[00000000], page_type[Freshly Allocated Page], space_id[00000000]
page_offset[00000000], page_type[Freshly Allocated Page], space_id[00000000]
----------------- innodb page info ----------------
File /data1/mysqldata/4444/data/db_felix1/t_202.ibd, Total Page is 6
Type File Space Header, Cnt: 1
Type Freshly Allocated Page, Cnt: 2
Type Insert Buffer Bitmap, Cnt: 1
Type File Segment inode, Cnt: 1
Type B-tree Node, Cnt: 1
这里需要注意,InnoDB存储采用大端存储,使用perl的unpack去读取时,如果需要转化为整数,需要使用unpack("n*", $_) 或 unpack("N*", $_) ,其中,n代表大端存储的unsigned short整型,N代表大端存储的unsigned long整型,具体可以perldoc –f pack看下。
最后,如果对实现代码有兴趣的tx,可以下载附件。
innodb_page_info.zip
(1.86 KB, 下载次数: 1534)
转载自:http://tencentdba.com/blog/innodb_stat_tool/
|
|