近期在几个现场发现gbase8s数据膨胀问题,无论是同构或者异构迁移到gbase8s中,都存在此问题。
后经过排查发现为gbase8s数据库配置参数MAX_FILL_DATA_PAGES 导致。
官方描述为
如果启用了 MAX_FILL_DATA_PAGES,服务器将 在最近修改的页面中添加一个新行,其中包含现有行(如果添加) 该行至少留出 10% 的页面空间,以便将来扩展 页面中的所有行。如果未设置 MAX_FILL_DATA_PAGES,则仅当页面上有足够的空间时,服务器才会添加该行以允许新行增长到其最大长度。
实际验证如下
pagesize =2k
当MAX_FILL_DATA_PAGES=0 时
drop table xx1;
create table xx1 (c1 varchar(1500));
insert into xx1 values(
'${__RandomString(100,abcdefghigklmnopqrstuvwxyz1234567890,)}'
);
当插入四条数据时
此时 free size 大于 表定义的varchar(1500)
当再插入一条数据后
计算方式为 2048 页大小 - 5 * 100 (varchar100) - 4 (尾部时间戳大小) - 5 * 2 (varchar标识位) - 5*4 (slot偏移量大小) =1490
此时free size 已经小于 varchar(1500),因此 当下一条数据插入是,将写入下一个页面
当MAX_FILL_DATA_PAGES=1 时
drop table xx1;
create table xx1 (c1 varchar(1500));
insert into xx1 values(
'${__RandomString(1500,abcdefghigklmnopqrstuvwxyz1234567890,)}'
);
经多次验证发现 ,当 free szie 小于 202 时 插入的数据将写入到下一个页面
计算方式为
[2048 (pagesize) -24 (头部信息) -4 (尾部时间戳)] * 10%=202
总结
如果将 MAX_FILL_DATA_PAGES 配置参数设为 1,数据库服务器将可向具有可变长度行的表中每个页面插入更多行。
优势:
减少存储数据所需的磁盘空间
使服务器对缓冲池的使用更有效
减少表扫描时间
缺点:
服务器可能以不同物理顺序存储行。
当页已满时,对行中可变长度列的更新可导致行扩展以至于在页面中不再适合。这将导致服务器将行划分到两页中,从而增加了该行的访问时间。