首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >[MYSQL] mysql 5.7 溢出页 FIL_PAGE_TYPE_BLOB

[MYSQL] mysql 5.7 溢出页 FIL_PAGE_TYPE_BLOB

原创
作者头像
大大刺猬
发布2025-02-21 11:17:10
发布2025-02-21 11:17:10
4390
举报
文章被收录于专栏:大大刺猬大大刺猬

导读

昨天发现之前为了支持超多字段的时候, 给sdi传递了个filename参数, 但是忘记5.7环境传递这个参数了...

于是修复之后, 再对5.7环境做测试, 又又又发现了, 5.7环境的溢出页(overflow pages)和8.0不一样....

所以本次来修改5.7环境的溢出页问题. 其实代码里面存在 if (page_type == FIL_PAGE_TYPE_BLOB || page_type == FIL_PAGE_SDI_BLOB) 之类的代码

基本上就能说明5.7的溢出页(FIL_PAGE_TYPE_BLOB) 和 SDI溢出页处理方式一样了. ~但是还是水一篇~

FIL_PAGE_TYPE_BLOB

FIL_PAGE_TYPE_BLOB 的结构和FIL_PAGE_SDI_BLOB基本上一样, 只不过前者记录的是这一页存在多少数据, 而后者记录的是 这一行的这一列的大小(总大小,每个page都一样). 不知道为啥这么设计, 没发现它两的优势.

好了, 还是来看看FIL_PAGE_TYPE_BLOB的结构吧

SIZE: 这个溢出页在本页中记录的大小.

PAGENO: 下一页的pageno, 如果是4294967295, 则表示这就是最后一页了.

DATA: 溢出页的数据, 大小就是上面的SIZE,

代码实现的话可参考如下:

代码语言:python3
复制
SPACE_ID,PAGENO,BLOB_HEADER,REAL_SIZE = struct.unpack('>3LQ',self.read(20))
if self.table.mysqld_version_id > 50744: # 8.0环境
	_tdata = first_blob(self.f,PAGENO)
else:
	_tdata = b''
	while True:
		self.f.seek(16384*PAGENO)
		_ndata = self.f.read(16384)
		REAL_SIZE,PAGENO = struct.unpack('>LL',_ndata[38:46])
		_tdata += _ndata[46:46+REAL_SIZE]
		if PAGENO == 4294967295:
			break

测试

修复完成之后, 我们来测试一波.

代码语言:sql
复制
-- 构造数据
create table db1.t20250221_overflow_pages(id int, aa varchar(9000), bb text);
insert into db1.t20250221_overflow_pages values(1,repeat('v',9000),repeat('t',10000));
代码语言:shell
复制
-- 下载最新版ibd2sql并测试
wget https://github.com/ddcw/ibd2sql/archive/refs/heads/main.zip
unzip main.zip
cd ibd2sql-main
python3 main.py /data/mysql_3308/mysqldata/db1/t20250221_overflow_pages.ibd --sql | more

太长了, 后面个text字段看不到了...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • FIL_PAGE_TYPE_BLOB
  • 测试
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档