OceanBase 生产环境出现「大量慢查询 + TPS 骤降 + 磁盘 IO 飙升」,请分析可能原因、排查步骤与解决方案

感谢分享!

实践案例很有参考价值

OceanBase 生产:大量慢SQL + TPS暴跌 + 磁盘IO打满 完整排查方案

一、核心现象统一归因

三类现象是连锁反应:磁盘IO飙高是根因之一,IO等待导致SQL执行堆积、RT拉长,表现为大量慢查询;连接池打满、事务提交变慢,业务吞吐量TPS直接断崖下跌。
整体分四大类根因:存储合并Compaction异常、SQL执行引发IO风暴、数据倾斜/热点、集群资源故障。

二、全部可能根因分类

类别1:LSM-Tree合并异常(OB最高发,IO飙升头号元凶)

OB底层LSM架构,数据写入MemStore,转储生成SSTable;多层SSTable过多就会触发合并Compaction,大量磁盘读写。

  1. Minor合并风暴
    写入量突增,MemStore快速打满,频繁dump转储,产生海量小SSTable,持续触发小合并,随机IO打满磁盘。
  2. Major大合并阻塞/堆积
    • 长期未合并,SSTable层数超过阈值,强制大合并;
    • 磁盘带宽不足、IO性能差,合并进度缓慢,大量IO占用;
    • 业务高峰自动触发major,读写与合并争抢IO资源。
  3. 删除/更新堆积大量删除标记(Buffer表场景)
    队列、临时缓冲表高频INSERT/DELETE,产生大量墓碑,每次查询扫描多层SSTable,读IO暴涨;同时后台合并清理墓碑加剧写IO。
  4. 分区转储均衡度差,少数Tablet集中触发dump,单点磁盘IO跑满。

类别2:SQL问题引发读写IO爆炸(慢查询同步爆发)

  1. 分区裁剪失效,全分区扫描
    查询不带分区键、分区键函数包裹、隐式转换,SQL扫描全部分区,大量随机读IO。
  2. 优化器选错执行计划
    无索引、全表扫描、笛卡尔积、未使用NLJ改用Hash Join,单次查询扫描几十万行数据,读IO持续走高。
  3. 冷热未隔离,大报表/离线分析混在线业务
    统计类SQL长时间扫描历史冷分区,占用磁盘IO,挤压在线读写。
  4. 未使用绑定变量,高频硬解析+大量重复全表扫描SQL叠加。
  5. 大小账号数据倾斜:大账号SQL扫描超大分区,单Tablet IO打满。

类别3:数据/分区热点倾斜(单节点磁盘IO瓶颈)

  1. 分片键设计不合理,热点商户、热点日期全部落在同一个Tablet;该分区所有读写集中单台磁盘,IO打满,所有关联SQL变慢。
  2. 副本不均衡,多热点Tablet集中同一台OBServer,磁盘IO资源耗尽。
  3. 读写分离未开启,全部读请求压主副本,主盘IO过载。

类别4:集群/硬件/参数故障类

  1. 磁盘硬件故障、SSD掉速、raid卡异常,单次IO延迟大幅升高;少量请求就会IO等待堆积。
  2. 时钟偏移、网络波动,副本同步Clog日志积压,日志刷盘IO持续拉高。
  3. Memstore内存参数过小,频繁dump转储;
  4. ODP连接池配置不合理,并发堆积,大量SQL同时下发加剧IO竞争;
  5. 备份任务、数据校验、OMS迁移同步任务高峰抢占磁盘IO。

三、标准化排查步骤(从上到下,先定位再深挖)

步骤1:OCP大盘快速确认基础指标,锁定大方向

  1. 查看磁盘指标:磁盘IO util、读/写吞吐量、IO延迟、await(IO等待时间)
    • await持续>20ms:磁盘IO饱和,所有SQL卡在IO等待;
  2. 观测租户指标:
    MemStore水位、SSTable层数、合并次数、转储dump次数;
  3. 业务指标:TPS/QPS下降曲线是否和IO飙升曲线完全重合;
  4. 慢SQL面板:导出Top耗时SQL,看特征(全表扫描、全分区扫描、大行数扫描);
  5. 节点负载:是否单台节点IO跑满(热点倾斜),还是所有节点同时冲高(全局合并风暴)。

步骤2:排查Compaction合并状态(OB特有优先查)

登录sys租户查询视图:

-- 查看所有分区SSTable层数、合并任务
SELECT zone, tablet_id, partition_id, sstable_count, minor_merge_cnt, major_merge_cnt 
FROM oceanbase.gv$ob_tablet_meta;

-- 查询正在执行的合并任务
SELECT * FROM oceanbase.gv$ob_compaction_task WHERE status='RUNNING';

-- 查看转储dump统计
SELECT * FROM oceanbase.gv$ob_dump_stat;

判断:

  • sstable_count普遍超过10:小文件过多,合并堆积;
  • 大量RUNNING合并任务、持续新增dump任务 → 合并风暴。

步骤3:定位慢SQL,验证是否SQL导致IO上涨

  1. 抓取gv$ob_sql_audit中逻辑读/物理读极高的SQL(物理读=磁盘IO来源);
  2. EXPLAIN PARTITIONS 查看执行计划:
    • 是否扫描全部分区(分区裁剪失效);
    • 是否走全表扫描、缺失索引;
    • 是否扫描百万级数据行;
  3. 区分两类慢查询:
    离线报表SQL(定时执行、大批量读) / 在线业务SQL(高频短查询)。

步骤4:排查数据热点倾斜

-- 查看各分区行数,定位超大分区
SELECT partition_id, tablet_id, row_count 
FROM oceanbase.gv$ob_partition_stat ORDER BY row_count DESC;

单分区行数远超其他分区 → 大小账号热点,单点IO瓶颈。

步骤5:排查后台抢占IO任务

  1. 查看备份任务是否正在执行;
  2. OMS数据迁移、回放校验任务是否高峰期运行;
  3. 是否手动执行过truncate、大批量delete触发大量墓碑合并。

步骤6:底层服务器硬件校验

  1. 服务器iostat查看%util、r_await/w_await;
  2. 检查SSD磁盘告警、磁盘坏道、raid告警;
  3. 网络流量:跨Zone同步流量是否打满,clog同步积压。

四、分场景解决方案(紧急止血 + 长期根治)

场景1:合并/转储风暴导致IO飙升(最常见)

紧急止血(立刻执行,快速恢复TPS)

  1. 手动限流写入:业务临时降峰,减少INSERT/UPDATE流量;
  2. 手动触发均衡Major合并,一次性清理多层SSTable:
ALTER SYSTEM MAJOR FREEZE TENANT tenant_name;
  1. 临时调大租户memstore内存,减少频繁dump转储;
  2. 临时调低合并并发参数,避免合并吃光磁盘IO:
    _minor_merge_concurrent_num_major_merge_concurrent_num

长期优化

  1. 合理配置Unit内存,保证memstore充足;
  2. 错开Major合并时间,配置业务低峰期自动合并;
  3. Buffer队列表建表指定 TABLE_MODE='queuing',优化墓碑清理逻辑;
  4. 分区拆分,单分区控制行数,避免单分区海量SSTable。

场景2:劣质SQL引发大量物理读、IO打满

紧急止血

  1. 临时kill超高物理读慢SQL,释放磁盘IO;
  2. 加Hint强制分区裁剪、强制走索引、限制并行度;
  3. 离线报表、统计SQL迁移至只读备副本,分离读写IO。

长期根治

  1. 改写SQL,WHERE条件带上原生分区键,保证分区裁剪生效;
  2. 缺失索引批量创建复合索引;
  3. 业务使用绑定变量,减少硬解析,缓存高效执行计划;
  4. 大查询增加资源组限流,避免抢占在线资源;
  5. 定时收集统计信息,防止优化器选错计划。

场景3:数据热点/大小账号倾斜,单节点磁盘IO跑满

紧急止血

  1. 读写分离,ODP配置读请求路由至备副本,分流主盘IO;
  2. 大账号SQL添加LOCAL HINT,减少跨节点IO交互;
  3. 手动触发rebalance,打散热点Tablet到多节点。

长期根治

  1. 优化分区键,采用复合分区键(商户ID+日期)拆分大账号数据;
  2. 热点大账号单独分表、分租户隔离资源;
  3. 扩容集群节点,提升整体磁盘IO带宽;
  4. 按业务冷热分区,冷数据归档降低扫描量。

场景4:后台任务抢占IO(备份/迁移/校验)

  1. 临时暂停备份、OMS同步、数据校验任务;
  2. 调整定时任务至凌晨低峰时段执行;
  3. 备份存储分离,不占用业务数据盘IO。

场景5:磁盘硬件性能不足/故障

  1. 故障磁盘立刻隔离,切换副本,迁移分区至正常节点;
  2. 升级高性能SSD,提升磁盘IO带宽;
  3. 优化系统磁盘参数:关闭atime、调整IO调度策略。

五、应急处理操作顺序(生产故障标准流程)

  1. 紧急Kill超高IO慢SQL,暂停抢占IO的后台任务,快速缓解磁盘压力;
  2. 判断是否合并风暴:是则手动major freeze合并,临时调大memstore;
  3. 观测TPS、IO指标是否恢复;
  4. 若单点IO跑满,开启读写分离分流读请求;
  5. 业务侧临时限流,降低写入吞吐量,给合并留出IO资源;
  6. 故障恢复后,定位根因输出优化方案,长期改造SQL、分区、参数。

六、预防手段(避免重复发生)

  1. OCP配置磁盘IO、慢SQL、合并任务告警,提前预警;
  2. 上线前流量回放验证,提前发现全扫描劣质SQL;
  3. 容量规划预留30%以上磁盘IO余量;
  4. 规范分区设计,避免超大热点分区;
  5. 区分在线业务与离线分析负载,资源物理隔离;
  6. 定期巡检SSTable层数、分区行数、慢SQL Top清单。
1 个赞

内容很好

宝贵的经验分享,谢谢!

收藏了

写得很详细

又学到一招

1 个赞

干货满满,受益匪浅

实践出真知,感谢分享实战经验

感谢分享!

内容很好

内容很好

内容很好

赞一个!

宝贵的经验分享,谢谢!

干货满满,受益匪浅

写得很详细

干货满满,受益匪浅

实践出真知,感谢分享实战经验