生产集群上创建了三个租户(tenant_mysql、tenant_oracle、tenant_olap),分别承载 TP 业务、Oracle 兼容业务和离线分析。某天凌晨,tenant_olap突然执行了一个超大并行查询,瞬间打满所在 OBServer 节点的所有 CPU,导致同节点上其他租户的 TP 事务出现大量超时,影响在线业务。
在 不重启集群、不重启租户、不 kill 所有会话 的前提下,使用 OceanBase 的资源隔离机制(如 io_capacity、cpu_quota配置,或临时调整 Unit 规格)快速压制 tenant_olap的资源占用,保证 TP 租户恢复正常, 待系统稳定后,查出引发故障的 SQL 具体内容、执行计划、并行度及其启动时间。
梳理出一套 SQL 拦截规则,使用 OceanBase 的 SQL 审计和自动限流功能,让该类型查询以后再也不能执行成功
在不重启集群、不重启租户、不 Kill 所有会话的前提下,分两步操作。
1:先定位那个正在疯狂消耗 CPU 的并行查询,只结束这一个 SQL,而不是整个会话。
SELECT
ID AS SESSION_ID,
SQL_ID,
SQL_TEXT,
TRACE_ID,
TIME,
PARALLEL_DEGREE,
TENANT_NAME
FROM oceanbase.GV$OB_PROCESSLIST
WHERE TENANT_NAME = ‘tenant_olap’
AND STATE = ‘ACTIVE’
AND INFO LIKE ‘%SELECT%’
ORDER BY TIME DESC;
获取目标 SQL_ID和对应的 TRACE_ID(或直接用 SESSION_ID),然后取消该查询:
KILL QUERY <SESSION_ID>;
2. 立即限制 OLAP 租户的资源上限,防止该租户再次发起大查询。通过动态调整 Unit 规格中的 MAX_CPU ,将 OLAP 租户的可用 CPU 压缩到安全水位(如 2 核),而 TP 租户保持原规格,
– 1. 查出 OLAP 租户使用的 Unit 配置名
SELECT TENANT_NAME, RESOURCE_POOL_LIST
FROM oceanbase.DBA_OB_TENANTS
WHERE TENANT_NAME = ‘tenant_olap’;
– 假设返回的资源池为 pool_olap,再查其 Unit 名
SELECT UNIT_CONFIG_ID, NAME, MAX_CPU, MIN_CPU
FROM oceanbase.DBA_OB_UNIT_CONFIGS
WHERE NAME = (SELECT UNIT_NAME FROM oceanbase.DBA_OB_RESOURCE_POOLS WHERE NAME = ‘pool_olap’);
系统稳定后,从 SQL 审计视图里反向追踪。
– 基于时间段和租户,找出执行时间最长的 SQL
SELECT
SQL_ID,
SQL_TEXT,
QUERY_SQL_TEXT,
SVR_IP,
START_TIME,
ELAPSED_TIME,
EXECUTE_TIME,
AFFECTED_ROWS,
RETRY_CNT,
PARALLEL_DEGREE,
PLAN_ID,
TENANT_NAME
FROM oceanbase.GV$OB_SQL_AUDIT
WHERE TENANT_NAME = ‘tenant_olap’
AND START_TIME BETWEEN ‘2025-06-03 01:00:00’ AND ‘2025-06-03 02:00:00’
AND SQL_TYPE = ‘SELECT’
ORDER BY ELAPSED_TIME DESC
LIMIT 1;
– 2. 紧急修改 MAX_CPU(在线生效,不需要重启)
ALTER RESOURCE UNIT unit_olap SET MAX_CPU = 2;
– 3. 如果 MIN_CPU 也较大,一并调低
ALTER RESOURCE UNIT unit_olap SET MIN_CPU = 1;
获取该 SQL 的执行计划:
SELECT OPERATOR, NAME, ROWS, COST, PARALLEL
FROM oceanbase.GV$OB_PLAN_CACHE_PLAN_STAT
WHERE PLAN_ID = <上面查到的PLAN_ID>;
开启自动 SQL 限流,防止同类变异 SQL 漏网
– 开启 SQL 自动限流特性(租户级)
ALTER SYSTEM SET sql_throttle_enable = true;
– 设置触发限流的阈值(如执行时间超过 5 秒的 SELECT 即触发)
ALTER SYSTEM SET sql_throttle_rt = 5;
ALTER SYSTEM SET sql_throttle_select_rt = 5;
– 限制被限流 SQL 的最大并发度,此处设为 0 表示直接排队,或设为极小值
ALTER SYSTEM SET sql_throttle_concurrent = 0;
woc 感谢老师!!!!