如何查看ocenabase的冻结、转储、合并?
在OceanBase数据库中,有多种维护操作用于确保数据的一致性和提高性能,其中包括冻结(Freeze)、转储(Dump)和合并(Merge)。这些操作对于数据库的健康运行至关重要。下面分别介绍如何查看这些操作的状态和相关信息。
冻结
冻结是指将 Active MEMTable 转化为 Frozen MEMTable 的过程。指将某个租户(Tenant)的分区组(Partition Group,简称PG)的最新快照标记为不可修改的状态,以便进行数据一致性检查或其他维护操作。
冻结的触发方式
- 1, 手动触发:alter system minor freeze;
- 2, 某个租户的占用内存超过阈值(freeze_trigger_percentage)后,会自动触发这个租户下所有 MEMTable 的冻结。
如何看 MEMTable 有没有冻结
select * from __all_virtual_table_mgr where table_type = 0 and is_active = 0 limit 10;
查看 METable 的情况:
当 MEMTable 的 is_active 字段为 1,表示是 Active MEMTable。
当 MEMTable 的 is_active 字段为 0,表示是 Frozen MEMTable,表示正在等待转储和释放。
如果 MEMTable 发生了冻结,但是一直没有转储,日志中有 MEMTable cannot be minor merged now 的 WARN 报错
如何看一个租户冻结了多少次
select * from __all_server_event_history where event like "%freeze%";
距离上一次冻结过去的小时数
上次冻结的时间戳存放在表 __all_zone 里,执行以下 SQL 即可。
SELECT zone,name,date_format(usec_to_time(value),'%Y-%m-%d %H:%i:%S') as value, now(), timestampdiff(hour,date_format(usec_to_time(value),'%Y-%m-%d %H:%i:%S'),now()) as diff_hour FROM __all_zone WHERE name='frozen_time';
转储
转储是将内存中 Frozen MEMTable 持久化到磁盘上生成 mini sstable 的过程,在生成 mini sstable 后会释放掉 Frozen MEMTable,是系统释放内存的重要手段。
如何判断转储结束
通过 SQL 查询当前系统中是否有冻结的 MEMTable。
select count(*) from __all_virtual_table_mgr where table_type = 0 and is_active=0;
查看正在执行中的任务
select * from __all_virtual_sys_task_status;
冻结和转储是什么关系
- 冻结:当 Active MEMTable 占用内存达到阈值(freeze_trigger_percentage)的时候或执行了 alter system minor freeze; 命令,Active MEMTable 会冻结,变成一个 Frozen MEMTable,后续的写入会写到新创建的 Active MEMTable 上。
- 转储:Frozen MEMTable 转储后会变成磁盘上的 SSTable;可能会同时拿到多个冻结 MEMTable 一起执行转储操作。所以冻结和转储不是 1:1 的关系,并不是一次冻结后,一定对应一次转储。另外,冻结和转储是独立的,如果有冻结生成了 Frozen MEMTable,才会创建转储任务。
分层转储
不使用分层转储时,OceanBase 数据库在同一时刻只会维护一个转储 SSTable,当 MemTable 需要进行转储时,会将 MemTable 中的数据与转储 SSTable 中的数据进行归并。随着转储次数不断增多,转储 SSTable 的大小也越来越大,而一次转储需要操作的数据量也越来越多,导致转储速度越来越慢,进而可能导致 MemTable 内存不足 。OceanBase 数据库引入了分层转储的结构
L0 层(Mini SSTable):
- 被冻结的 MemTable 会直接 flush 为 Mini SSTable。
- OceanBase 数据库内部可以同时存在多个 Mini SSTable。
L1 层(Minor SSTable):
- 大多数情况下仅有一个 Minor SSTable。
- 每次下压都会在 L1 层生成新的 Minor SSTable,代替原有的 Minor SSTable。
L2 层(Major SSTable):
- 基线数据,在合并时产生。
- 一般情况下仅有一个。
如何查看分区级转储任务的执行情况?
merge_percentage 列表示某分区的转储进度。
SELECT table_id,partition_id,merge_type,merge_percentage FROM __all_virtual_partition_sstable_merge_info WHERE partition_id=$partition_id AND table_id=$table_id; +---------------+--------------+-------------+------------------+ | table_id | partition_id | merge_type | merge_percentage | +---------------+--------------+-------------+------------------+ | xxxxxxxxxxxxx | x | major merge | 0 | +---------------+--------------+-------------+------------------+
如何查询租户级转储调度情况?
可以通过查询 gv$minor_merge_info 视图来查询租户级转储调度情况,其中 FREEZZE_SNAPSHOT 表示转储的版本号。
SELECT * FROM gv$minor_merge_info WHERE finish_time!='';
合并
合并(major freeze)是将全局指定时间点之前的所有数据都合成一个 major sstable 的过程,耗时较长也,触发方式可以手动(alter system major freeze;)或自动(阈值major_compact_trigger 默认为 2)及定时(配置项 major_freeze_duty_time 指定)。之外还有mini minor merge和buffer minor merge。实现方式启动合并 RS 发起合并之后,通过心跳发送到 observer,observer 在收到心跳后查询 __all_zone
表判断是否能做合并,然后开始 observer 的合并流程。合并中 observer 遍历所有的 partition,依次发起合并任务并交由后台线程池执行。合并结束 observer 周期地遍历所有的 partition 来判断是否合并完成,对于完成的 partition 更新其 meta 信息和 checksum 信息到内部表。
mini minor merge 或 minor merge 是将多个 mini/minor SSTable 合成一个的 compaction 方式,是减少 mini SSTable 数量的重要手段,由内部后台调度线程触发,当转储 SSTable 的数量超过 minor_compact_trigger,就会尝试触发 minor merge,合并多个sstable到1上sstable,并将作为输入的所有 SSTable 回收掉;同一个 partition 的 mini/minor/major 可能同时在执行。mini minor merge 是将多个 L0 层的 Mini SSTable 合成一个 L0 层的 Mini SSTable。minor merge 是将多个 L0 层的 Mini SSTable 和 L1 层的 Minor SSTable 合成一个 L1 层的 Minor SSTable。该做 mini minor merge 还是做 minor merge,与 SSTable 的行数和 table 大小相关,不可指定。除了minor_compact_trigger,参数_minor_compaction_amplification_factor
同样影响是做 mini minor merge 还是做 minor merge,当选择转储的 mini SSTable 与 minor SSTable 总行数比值超过该值时,选择将多个 mini 和 minor 合成一个 minor,否则将多个 mini 合成一个 mini。默认为 25%。
buffer minor merge 是一种特殊的 compaction 类型,是将某个指定时间点之前的数据合成一个 buffer minor SSTable,其数据格式和 major SSTable 的一样,不包含多版本数据和未提交事务数据。在频繁插入删除的场景中,SSTable 中数据量会比较大,查询会变得很慢,buffer minor SSTable 可以去掉 SSTable 中已经被删掉的数据,加速查询,缓解写放大的问题。major merge 是一个全局的快照,是一个比较重的操作,每个 zone 生成的 major SSTable 是一模一样的;buffer minor merge 是可以随时触发的,不受全局的影响,每个 zone 生成的 buffer minor SSTable 可以不一样。使用方法 将表的 table_mode
指定为 queuing:
ALTER TABLE table_name TABLE_MODE = 'queuing';
buffer minor merge 和 mini minor merge 的区别
两种 minor merge 都是将多个 SSTable 合成一个 SSTable。mini minor merge 输出的 SSTable 是 mini SSTable 或 minor SSTable,包含多版本数据和未提交事务信息,主要是为了减少 SSTable 数量;buf minor merge 输出的是 buffer minor SSTable,不包含多版本数据和未提交事务信息,主要是为了解决用户频繁插入删除时,导致 SSTable 数据膨胀影响查询性能的问题。
合并增强方式
- 轮转合并:为了规避每日合并对业务的影响。借助 OceanBase 数据库的 多副本分布式架构,当一个数据副本在进行合并时,会将这个副本上的查询流量切到其他没在合并的集群上面,为了避免流量切过去后,cache 较冷造成的RT波动,在流量切换之前,OceanBase 数据库还会做 cache 的预热。
- 并行合并:并行合并是默认开启,按照 Major SSTable 来进行拆分,将一个 compaction 任务按照 key_range 拆成若干的子任务,将任务交给不同的线程执行,加快 compaction 的速度。
- 渐进合并:OceanBase 数据库在设计之初就考虑到了 Online DDL 的需求,在OceanBase 数据库中加列、减列、建索引等 DDL 操作都是不阻塞读写的,也不会影响到多副本间的 Paxos 同步。加减列的 DDL 变更是实时生效的,对存储数据的变更延后到每日合并的时候来做。和 MySQL 一样,对于某些 DDL 操作如加减列等,我们是需要将所有数据重写一遍的,如果在一次每日合并过程中完成对所有数据的重写,那么对存储空间和合并时间都会是一个比较大的考验。为了解决这个问题,引入了渐进合并,会将 DDL 变更造成的数据重写分散到多次每日合并中去做,数据就被整体重写了一遍。渐进合并减轻了 DBA 做 DDL 操作的负担,同时也使得 DDL 变更更加平滑。渐进合并的参数progressive_merge_num属性来决定渐进的轮次,progressive_merge_round 表示本次合并所处的渐进合并轮次(major SSTable),当 progressive_merge_num=1 时会发生全量合并.
全量合并与非全量合并
- 全量合并:所有宏块不重用,全部打开重写。
- 非全量合并:宏块会重用,只打开有数据变更的宏块。
- 当执行渐进合并时,只有本次渐进轮次相关的宏块会做全量合并,其他部分做非全量合并。
为什么全量合并会较慢?
合并会将有修改的数据宏块打开重写(速度慢),没有修改的数据宏块则直接重用(将老的数据宏块直接刷盘,速度快) 全量合并,即所有的宏块都打开重写,所以速度会较慢。
如何加快或放慢合并速度?
可以通过调整合并的线程数的方式调整合并速度。merge_thread_count
用于设置每日合并工作的线程数,默认为 0,表示取 10 与 CPU 数量 * 0.3 的较小值。取值范围为 0 ~ 64。有关该配置项的详细信息,请参见 OceanBase 数据库《参考指南》中的 系统配置项 章节。 注意
无论 merge_thread_count
设置为何值,OceanBase 数据库用于合并的线程数都不会超过 48。
相关SQL
查看合并状态
-- v2 v3 SELECT * FROM __ALL_ZONE WHERE INFO LIKE ‘%IDLE%’; -- v4 SELECT * FROM CDB_OB_MAJOR_COMPACTION where status LIKE ‘%IDLE%’; SELECT * FROM DBA_OB_MAJOR_COMPACTION where status LIKE ‘%IDLE%’; -- v4.1 系统租户可以通过查询oceanbase.CDB_OB_ZONE_MAJOR_COMPACTION
和oceanbase.CDB_OB_MAJOR_COMPACTION
视图来观察所有租户的合并信息。 SELECT * FROM oceanbase.CDB_OB_ZONE_MAJOR_COMPACTION\G 用户租户可以通过查询DBA_OB_ZONE_MAJOR_COMPACTION
和DBA_OB_MAJOR_COMPACTION
来观察本租户的合并过程。 SELECT * FROM oceanbase.DBA_OB_MAJOR_COMPACTION\G -- for mysql SELECT * FROM sys.DBA_OB_MAJOR_COMPACTION\G -- for oracle
Compaction 历史记录/进度/当前执行状态的内部表和视图
版本 | V3.2 版本之前 | V3.2 版本 | V4.0 版本 |
---|---|---|---|
zone 合并情况 | __all_zone |
__all_zone |
CDB_OB_MAJOR_COMPACTION |
server 合并进度 | NA | __all_virtual_server_compaction_progress |
__all_virtual_server_compaction_progress \ GV$OB_COMPACTION_PROGRESS |
分区合并进度 | NA | __all_virtual_partition_compaction_progress |
__all_virtual_tablet_compaction_progress \ GV$OB_TABLET_COMPACTION_PROGRESS |
分区合并历史 | __all_virtual_partition_sstable_merge_info |
__all_virtual_partition_compaction_history |
__all_virtual_tablet_compaction_history \ GV$OB_TABLET_COMPACTION_HISTORY |
宏块信息 | __all_virtual_partition_sstable_macro_info |
__all_virtual_partition_sstable_macro_info |
__all_virtual_tablet_sstable_macro_info |
诊断视图 | NA | __all_virtual_compaction_diagnose_info |
__all_virtual_compaction_diagnose_info \ GV$OB_COMPACTION_DIAGNOSE_INFO |
建议视图 | NA | __all_virtual_compaction_suggestion |
__all_virtual_compaction_suggestion \ GV$OB_COMPACTION_SUGGESTIONS |
dag 虚拟表 | NA | __all_virtual_dag |
__all_virtual_dag |
dag scheduler 虚拟表 | NA | __all_virtual_dag_scheduler |
__all_virtual_dag_scheduler |
失败 dag 记录 | NA | __all_virtual_dag_warning_history |
__all_virtual_dag_warning_history |
查看合并进度
SELECT zone, svr_ip, major_version, macro_block_count, use_old_macro_block_count, merge_start_time, merge_finish_time, merge_process, ( merge_finish_time - merge_start_time ) AS cost_time, ( macro_block_count - use_old_macro_block_count ) AS merge_macro_block_count, ( macro_block_count - use_old_macro_block_count ) / ( merge_finish_time - merge_start_time ) AS avg_per_sec FROM __all_virtual_partition_sstable_image_info ORDER BY zone, svr_ip, major_version;
如何暂停或继续合并?
OceanBase 数据库提供了暂停与继续的 SQL 语句接口,可以通过以下 SQL 暂停或继续合并。
通过以下 SQL 语句暂停合并。
obclient> ALTER SYSTEM SUSPEND MERGE;
通过以下 SQL 语句继续合并。
obclient> alter system resume merge;
查找没有合并到指定 major 版本的 partition
-- v2 v3 select * from __all_virtual_meta_table where data_version != xxx limit 10; -- v4 select * from __all_tablet_meta_table where tenant_id = xxx and compaction_scn < xxx;
内部表 __all_tablet_meta_table 的 compaction_scn 字段是从 OceanBase 数据库 V4.1.0 版本开始,在 OceanBase 数据库 V4.0.0 版本,请使用snapshot_version。
References
https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000209910
https://www.oceanbase.com/knowledge-base/null-20000000112
https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000000034003
对不起,这篇文章暂时关闭评论。