白天稳如狗半夜就抖:OceanBase 合并转储把读写延迟顶了上去

业务白天 RT 很稳,一到凌晨 2 点(或某个固定时段)延迟突然拉高、慢 SQL 变多,可应用没发版、流量也没涨------这多半是 OceanBase 的合并(Major Freeze)在跑。云贝教育在帮客户做 OB 上线压测时,这道"半夜合并抖动"几乎必踩,下面把定位动作理一遍,照着查就行。

OB 基于 LSM-Tree,会定时把增量 SSTable 合并成基线。合并过程要重读重写全量数据,吃 CPU 和磁盘 IO,单分区大表合并时更容易把读写延迟顶上去。按"先确认、再调参"的思路过一遍即可。

先确认:抖动是不是合并引起的

|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
| -- 看正在进行的合并任务 SELECT * FROM gvmerge_info WHERE merge_status = 'MERGING'; -- 看合并历史与耗时,对齐抖动时段 SELECT \* FROM gvmerge_info ORDER BY start_time DESC LIMIT 20; |

如果抖动时段正好有 MERGING 任务,且和下面的 major_freeze_duty_time 对得上,基本就坐实了。

第 1 类:自动合并撞上业务高峰

OB 默认每天在 major_freeze_duty_time(默认 '02:00')做一轮自动合并。如果你们 02:00 还有跑批、同步或清算,就被撞了。

|----------------------------------------------------------------------------------------------------------------------------------------------|
| -- 看当前合并时间配置(在对应租户下执行) SHOW PARAMETERS LIKE 'major_freeze_duty_time'; -- 改到真正的低峰,比如 04:30 ALTER SYSTEM SET major_freeze_duty_time = '04:30'; |

不想被自动合并"偷袭",也可以关掉自动、改手动在维护窗口触发:

|---------------------------------------------------------------------------------------------------------|
| -- 关掉租户自动合并 ALTER SYSTEM SET enable_auto_major_freeze = FALSE; -- 维护窗口手动触发一次 ALTER SYSTEM MAJOR FREEZE; |

第 2 类:转储太频繁,IO 被反复打满

MemTable 占用内存达到 freeze_trigger_percentage(默认 20)就会触发 minor freeze(转储)。阈值太低,写入稍多就频繁转储,IO 一直不闲。

|--------------------------------------------------------------------------------------------------------------------------------|
| SHOW PARAMETERS LIKE 'freeze_trigger_percentage'; -- 适当抬高冻结阈值,减少转储频率(按机器内存权衡) ALTER SYSTEM SET freeze_trigger_percentage = 40; |

注意:别为了"少转储"去调小 MemStore 比例,那只会让 MemTable 更快到阈值、转储更频繁,反而更糟。

第 3 类:大分区合并,单点 IO 尖峰

单表 / 单分区过大,合并时这个分区的 IO 会集中爆发。OB 默认有轮转合并(把查询流量切到未合并副本、提前预热 Cache)来缓冲突变,但副本自身合并仍占资源,大表单分区尖峰难以完全抹平。

从设计上把热点大表按时间 / 范围拆成多个分区,合并时 IO 就能分散到不同分区并行推进。

|----------------------------------------------------------------------------------------------------------------------|
| SHOW PARAMETERS LIKE 'merge_thread_count'; -- 机器紧张时限制合并线程,给业务留余量(默认 0 为自适应) ALTER SYSTEM SET merge_thread_count = 8; |

合并抖动排查六步

1. gv$merge_info 查 MERGING 任务,对齐抖动时段;

2. SHOW PARAMETERS 看 major_freeze_duty_time 是否撞业务高峰;

3. 把 duty_time 挪到真低峰,或关自动合并改手动低峰触发;

4. 抬高 freeze_trigger_percentage,平滑转储、减少频次;

5. 大表做分区化,必要时限 merge_thread_count 给业务留资源;

6. 低峰手动 ALTER SYSTEM MAJOR FREEZE 验证合并窗口是否避开高峰。

写在最后

OceanBase 的"半夜抖动"十有八九是合并。别一上来就加机器,先 gv$merge_info 看一眼,把合并时间挪开业务高峰、把转储参数磨平,抖动基本就消了。真要根治,还得从大表分区设计上把合并 IO 打散。

------ 云贝教育,专注 IT 运维实战。

相关推荐
羑悻的小杀马特7 小时前
Redis持久化三剑客:RDB二进制快照、AOF文本日志、混合模式如何守护你的数据安全?
数据库·redis·缓存·aof·持久化存储·rdb
小呆爱发呆7 小时前
第三章 MySQL 库表操作
数据库·mysql·adb
时间的拾荒人8 小时前
Redis 进阶实战:渐进式遍历、持久化机制与事务详解
数据库·redis·缓存
普通人69 小时前
MySQL_FIND_IN_SET函数详解
android·数据库·mysql
真上帝的左手9 小时前
4. 关系型数据库-MySQL-Canal 进阶
数据库·mysql·canal
xiaoye-duck9 小时前
《C++ 项目:手写大模型接入 SDK》DataManager数据管理模块:SQLite持久化存储
开发语言·数据库·c++·sqlite
codeejun9 小时前
每日一Go·MySQL-14、慢 SQL 产生原因全解
sql·mysql·golang
唐老板10 小时前
uuidv7 来了:为什么别再拿 uuidv4 当主键了
数据库
SelectDB1 天前
让变更流出 Doris:Apache Doris 5.0 基于增量计算的 CDC 技术解析
数据库