暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

OceanBase 里的 Queuing(BUFFER) 表

IT那活儿 2023-06-05
1728
点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!



背景介绍



在OceanBase 中,对表的 DML 操作都是只打标记(比如 UPDATE ,变为 DELETE 打标记+INSERT),后台再慢慢异步清理旧的数据。所以必然会在更新频率过快并且后台线程清理数据不及时导致的严重读写放大问题、或者统计信息严重不准确(OceanBase 统计信息在合并时触发)导致的执行计划非最优的问题,最终影响检索性能。

在 LSM Tree 架构下,对数据行的删除并不是原地删除,而是通过写入一行 Delete 操作(tombstore)来标记删除,如果某个用户业务表主要操作为频繁的插入与删除,从绝对数据量上来看可能并不大,但是由于 LSM Tree 的架构特征,会导致对这类表的增量数据中存在大量的 Delete 标记, 即使用户的实际扫描范围很小,但是 SSTable 内部无法快速识别这些数据是否删除,仍然要扫描大量包含删除标记的数据,导致一个小查询的响应时间可能远远超过用户预期。

为了解决这类表的查询性能问题,OceanBase 数据库为用户特别提供了一种支持自定义的表模式,称为 Queuing 表 (从业务角度有时候也会称为 Buffer 表 )

对于 queuing 表具体来说,OceanBase 数据库引入一种自适应的 buffer 表转储策略,由存储层在每次转储时根据转储的统计信息来自主判断是否需要对该表采用 buffer 表转储策略,当发现一个表存在类似 buffer 表行为时,接下来会尝试对这个表做 buffer minor merge 的调度,对这个表基于 Major SSTable 和最新的增量数据以当前的读快照时间生成一个 Buf Minor SSTable,这次 Compaction 动作会消除掉增量数据里的所有 Delete 标记,后续查询基于新生成的 Buf Minor SSTable 就可以避免原有的大量无效扫描动作。



使用场景



Buffer表实际的数据量不大,但有大比例的更新或者增删。

对于设计阶段已经明确的Queuing 表场景,推荐开启该特性作为长期解决方案。

ALTER TABEL user_table TABLE_MODE = 'queuing';



前置条件



前置条件一:表属性table_mode='queuing'

当一个表被指定为Buffer表时( TABLE_MODE = ‘queuing‘),其自适应的Buffer表转储策略可以根据表中增删数据的比例来触发转储。

该属性是 OceanBase 专门为 queuing表做的优化,当 BUFFER 表更新记录数超过一定阈值时,自动对这张表进行单独转储以消除大量无效检索,从而实现对 BUFFER 表的快速检索。

前置条件二:触发条件

其转储的频率主要有以下参数控制:

_ob_queuing_fast_freeze_min_threshold:

租户级配置项,默认值为10,即当表中删除的记录数达到基表记录数的10%时,触发Buffer表的快速冻结。

_ob_queuing_fast_freeze_min_count:

租户级配置项,默认值500000,即当表中删除的记录数至少达到50万时,才能触发Buffer表的快速冻结。

两个控制条件都满足后才可以触发Buffer表的快速冻结。

1. 创建Queuing表

create table tab_queue(id int primary key, name varchar(10), 
contact varchar(20),

addr varchar(100)) table_mode='queuing';

2. Queuing表插入数据

insert into tab_queue select level,

case mod(level,5)

when 0 then '张一'

when 1 then '李一'

when 2 then '王一'

when 3 then '赵一'

when 4 then '钱一'

else null

end

, '1234567890','Asia-China-Sichuan-Chengdu'

from dual where mod(level,5)=3 connect by level <=20000;

commit;

3. 执行一次表和租户级别的转储

MySQL [oceanbase]> ALTER SYSTEM MINOR FREEZE TENANT=(obcp_t3);

Query OK, 0 rows affected (0.09 sec)

4. 修改隐含参数ob_queuing_fast_freeze_min_count

obclient [SYS]> alter system set "_ob_queuing_fast_freeze_min_count"=2000;

Query OK, 0 rows affected (0.551 sec)

obclient [SYS]>

5. 更新表数据

obclient [SYS]> update tab_queue set name = 'wang';

Query OK, 4000 rows affected (0.123 sec)

Rows matched: 4000  Changed: 4000  Warnings: 0

obclient [SYS]> update tab_queue set name = 'wang000';

Query OK, 4000 rows affected (0.180 sec)

Rows matched: 4000  Changed: 4000  Warnings: 0

obclient [SYS]> commit;

Query OK, 0 rows affected (0.031 sec)

经验结论:

tab_queue 在update语句满足隐含参数设定的阈值时,立刻发生自动转储,随即执行了queuing 表独有的buf minor merge,把刚刚转储生成的mini sstable与major sstable 合并成一个minor sstable,有利于对queuing 表的全表扫描效率。


END


本文作者:韦宝军(上海新炬中北团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论