首批通过分布式安全可靠测评,为关键业务系统打造
Memtable 长时间未释放
更新时间:2024-07-03 10:01
内存中的 Memtable 在冻结后经过 Mini Compaction 即转储,生成磁盘上的一个 Mini SSTable,正常情况下转储完成后对应的 Memtable 就可以被回收,内存被释放掉。 Memtable 长时间未释放有两种原因:
- Memtable 转储比较慢。
- Memtable 在转储后也无法释放。
oceanbase 数据库 V3.2 版本后请优先查看 __all_virtual_compaction_diagnose_info 内部表,查询是否有该分区的诊断信息,如果没有则按下列步骤排查。
如何判断是哪种原因
通过 Memtable 释放的日志,或者通过 SQL 可以查询的到释放较慢的 Memtable,拿到以下信息:
- pkey。
- Memtable 冻结的时间。
- Memtable 的 log_ts_range / version_range。
grep "memtable destroyed" observer.log.xxxx其中 Memtable 的 snapshot_version 和 end_log_ts 就和 Memtable 冻结的时刻相近。

得到 Memtable 转储成功的时间
查询内部表
- 在 OceanBase 数据库 V3.1 版本,可查询内部表
__all_virtual_partition_sstable_merge_info获得,merge_version 表示右边界。 - 在 OceanBase 数据库 V3.2 版本,可查询内部表
__all_virtual_partition_compaction_history获得,merge_version 表示右边界。 - 在 OceanBase 数据库 V4.x 版本,可查询内部表
__all_virtual_tablet_compaction_historycompaction_scn 表示右边界。 - 其他版本不支持内部表获取
- 在 OceanBase 数据库 V3.1 版本,可查询内部表
通过日志搜索
grep "sstable merge finish.*pkey_info.*log_ts_range" observer.log.xxxx // 假设 table_id 为 200129 // log_ts_range:{start_log_ts:1, end_log_ts:1660884009514492571} grep "sstable merge finish.*200129.*start_log_ts:1, end_log_ts:1660884009514492571" observer.log.xxxx | vi -- 如果转储成功的时间与 Memtable 释放的时间较近,说明是转储调度或执行得太慢导致释放慢。
- 如果转储成功实践与 Memtable 释放时间较远,说明转储成功之后有其他原因导致 Memtable 不释放。
转储成功不释放
有几种特殊情况会导致 Memtable 在转储后也无法释放:
在 OceanBase 数据库 V2.2.7 版本及之前是可能出现,Memtable 被查询持有引用计数,查询没有结束之前 Memtable 都不能释放。
开启预热,Memtable 会在老版本的 table_store 中被持有引用计数,预热结束前,Memtable 不能释放。
默认预热时间为 30s,可以通过配置项
minor_warm_up_duration_time查询。show parameters like "minor_warm_up_duration_time";
转储比较慢
调度比较慢
在 OceanBase 数据库 V3.2 版本之前,转储任务是由后台调度线程遍历所有分区,为每个分区创建调度任务。所有转储比较慢有可能是分区数多导致调度线程遍历比较慢、或遍历线程被卡住等原因。
OceanBase 数据库 V3.2 及之前版本
grep "partition_scheduler.cpp" observer.log.xxxOceanBase 数据库 V4.x 版本
grep "tablet_scheduler.cpp" observer.log.xxx通过调度的日志可以观察 Compaction 调度线程创建的调度任务,可以查询是否有调度报错。
其中错误码对应的情况如下:
- -4023 / OB_EAGAIN:表示队列中已经有该分区的 Compaction 任务,不可重复调度。
- -4019 / OB_SIZE_OVERFLOW:表示 Compaction 任务队列已经满了,只能等待下次遍历再调度 Compaction 任务。
等待执行比较慢
后台执行 Compaction 任务的队列是一个 FIFO 形式的队列,每个队列中存一种 Compaction 类型的任务。 同一时间,一个分区只会有一个 MINI Compaction 的任务。 若任务数量多,新加入的 MINI Compaction 任务会等待前序任务依次执行结束之后才可执行,因此等待时间长。
OceanBase 数据库 V3.2 版本之前,通过下面的语句可以得到近期成功的 MINI Compaction 的情况。
grep "sstable merge finish.*merge_type:2" observer.log.xxx | wc -l也可以通过内部表得到 Compaction 的一个时间打点情况。
- OceanBase 数据库 V3.2 之前版本没有打点功能。
- OceanBase 数据库 V3.2 版本可通过内部表
__all_virtual_partition_compaction_history查询。 - OceanBase 数据库 V4.x 版本可通过内部表
__all_virtual_tablet_compaction_history查询。
查看表内 comment 字段,字段内容为
time_guard=EXECUTE=993us|(0.15)|UPDATE_TABLET=3.34ms|(0.51)|DAG_FINISH=1.81ms|(0.28)|total=6.49ms;wait_schedule_time=1.04s;其中wait_schedule_time表示等待调度的时间,若等待时间非常长,应该是任务堆积或者有长任务。- 任务堆积:任务数量多 (提升转储线程)。
- 长任务:有total时间较长的任务 (开启并行转储)。