首批通过分布式安全可靠测评,为关键业务系统打造
单表高频做 DDL,MemStore 内存爆以及 OMS 同步链路延迟
更新时间:2026-05-08 08:11
问题现象
单表高频做 DDL(e.g. drop/create/truncate partition/subpartition)的场景下,部分场景消费历史版本 schema 时会 cache miss,需要实时加载 schema,导致获取 schema 慢。
对 OBServer,会导致转储线程卡,进而影响 MemStore 内存释放,最终导致租户内存爆。
对 liboblog,消费历史版本 schema 格式化数据慢,大量数据写入时会导致同步链路延迟。
除此之外,cache miss 后会导致重复加 KVCACHE,导致 SYS 租户 KVCACHE 内存快速上涨。
关键诊断信息
触发条件
单表高频做 DDL(e.g. drop/create/truncate partition/subpartition)。
问题原因
在单表高频做 DDL 的情况下,由于 schema history 缓存的数目有限,会导致 cache miss,cache miss 会触发获取 schema 的逻辑,导致调用方执行逻辑变慢。
OBServer 端问题
单表高频 DDL 主要有以下两个问题。
转储所需的多版本 schema 由于 schema history 过多,无法命中 cache。
cache 失效的情况下,获取多版本 schema 的动作由于 schema history 过多会很耗时。
上述情况如果发生在分区数目很多的表上,风险会被进一步放大。
低版本转储和 MemStore 内存释放共享一组线程,如果转储合并耗时长,会导致 MemStore 内存无法及时释放。转储合并的耗时一方面受分区数目影响,另一方面受获取 schema 的速度的影响。
以实际问题场景为例,客户的表以 1 分钟的频率做 truncate partition 操作,schema_history_expire_time 为 30d 的情况下,单表约有 14W+ history,获取 schema 的耗时约 400ms+。转储的时候由于该表有 6000+ 分区,在 cache miss 的时候,调度一轮该表的所有分区转储至少是小时级别的耗时。
liboblog 端问题
liboblog 会对 DDL 和 DML 定序,根据定序结果使用某个历史版本的 schema 格式化数据并向下游输出。在使用较小版本 schema 格式化大量数据的场景会有类似的 schema cache miss 的问题,格式化每行数据都得获取 schema,导致 OMS 同步链路延迟。
OMS 链路延迟日志排查方式如下。
观察
lioblog.log是否有 schema 模块大量报错,且日志打印较多。grep NEXT_RECORD liboblog.log*发现流量极其低。grep TASK_COUNT liboblog.log* | grep FORMATTER查看待格式化数据堆积严重(说明需要刷新 schema)。
在对应租户下,指定 OMS 同步到位点,查询是否有大量 DDL 变更,如下。
-- 其中 oms_sync_ts 是 OMS 联路同步到的位点,微秒精度 select * from oceanbase.__all_ddl_operation where schema_verison >= oms_sync_ts and ddl_stmt_str!="";
问题的风险及影响
单表的高频 DDL,主要有以下几个风险。
DML 由于 schema 变化,需要频繁地获取 schema,对系统负载以及 SQL 延时都有较大的影响。
转储合并由于 cache 失效需要触发多版本 schema 获取的逻辑,会长时间占住转储合并线程,进而导致 MemStore 内存释放受影响,租户内存爆。
liboblog 消费历史版本 schema 格式化数据,schema 容易
cache miss,导致格式化数据慢,进而导致 OMS 同步链路延迟。cache miss后会导致重复加 KVCACHE,导致 SYS 租户 KVCACHE 内存快速上涨。
影响租户
影响 OceanBase 数据库中的 Oracle 租户和 MySQL 租户,对于 SYS 租户无影响。
影响版本
OceanBase 数据库 V2.2.77 GA(oceanbase-2.2.77-20210508211731)及之后版本、V3.1.2 GA(oceanbase-3.1.2-20210618150922)及之后版本、V3.2.3 GA(oceanbase-3.2.3.0-20220418212020)及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之后版本、V4.1.0 GA(oceanbase-4.1.0.0-100001122023040322)及之后版本。
解决方法及规避方式
解决方法
升级到问题已修复版本,现已有修复版本 OceanBase 数据库 V2.2.77 BP19(oceanbase-2.2.77-119000122024060513)、V3.2.3 BP10(oceanbase-3.2.3.3-110000092023091219)、V3.2.4 BP5(oceanbase-3.2.4.5-105000012023081513)、V4.1.0 BP3(oceanbase-4.1.0.2-103000072023081111)。
规避方式
可以通过以下几种方式缓解。
降低单表 DDL 操作的频率,或者停止相关表的 DDL。
- 对于加分区的 DDL,可以一条 DDL 加多个分区,从而避免单表变更数百次操作(比如中体彩单表加 323 个分区,是通过 323 次 DDL 执行的,每个 DDL 加一个分区,因此有 323 次高频 DDL 操作)。
适当调小
schema_history_expire_time(如:调整为 7d,但需要保证比物理备份周期长,否则无法保证物理恢复能恢复到任意时间点),减少单表 history 量,减少cache miss需要触发 schema 刷新时的构造成本。