问题现象
场景一:
在系统 sys 租户的【性能监控】页面发现系统 sys 租户 CPU 长时间使用率均达到 100%:

场景二:
系统 sys 租户遇到告警:租户状态:不可用,错误信息: (conn=3187411) No memory or reach tenant memory limit:

问题原因
场景一:
在第一个场景中分析系统 sys 租户的【SQL 诊断】,发现主要是下列两条 SQL 导致 sys 租户的 CPU 被打满:

TopSQL1:
SELECT arbitration_member FROM __all_virtual_log_stat WHERE tenant_id = ? AND ls_id = ? AND role = ?TopSQL2:
SELECT row_id, column_name, column_value FROM __all_core_table WHERE table_name = ? ORDER BY row_id, column_name通过分析 SQL Audit 执行记录,发现上面两条 TopSQL 是由于查询
CDB_OB_TABLE_LOCATIONS表的监控语句引起的,每查询一次CDB_OB_TABLE_LOCATIONS就会产生出几十万条查询__all_core_table的查询语句:SELECT tenant_id, SVR_IP, SVR_PORT, count(*) as cnt FROM CDB_OB_TABLE_LOCATIONS WHERE TABLE_ID > 500000 GROUP BY TENANT_ID, SVR_IP, SVR_PORT SELECT tenant_id, svr_ip, svr_port, count(*) as cnt FROM CDB_OB_TABLE_LOCATIONS WHERE ROLE = 'leader' AND TABLE_ID > 500000 GROUP BY TENANT_ID, SVR_IP, SVR_PORT场景二:
在第二个场景中分析系统 sys 租户的【SQL 诊断】,发现下面的一条 TopSQL 语句占用了超过 65% 的 sys 租户 CPU:

对应的 SQL 语句如下:
SELECT h.SAMPLE_ID AS obSampleId, DATE_FORMAT(h.SAMPLE_TIME, '%Y%m%d%H%i%s') AS sampleId, h.SESSION_ID AS sessionId, h.SESSION_TYPE AS sessionType, p.USER_CLIENT_IP AS client, p.USER_CLIENT_PORT AS clientPort, p.DB AS currentSchema, p.TENANT AS dbName, p.USER AS userName, h.SQL_ID AS orgnSqlId, h.SQL_ID AS digestSqlId, h.STMT_TYPE AS sqlType, h.PLAN_ID AS orgnSqlPlanId, h.SQL_PLAN_LINE_ID AS sqlPlanLineId, h.PLAN_ID AS digestSqlPlanId, h.WAIT_CLASS AS enmoWaitClass, h.WAIT_CLASS AS waitClass, h.SESSION_STATE AS sessionState, h.EVENT AS waitEvent, BLOCKING_SESSION_ID AS blockSessionId FROM GV$OB_ACTIVE_SESSION_HISTORY h LEFT JOIN GV$OB_PROCESSLIST p ON h.SESSION_ID = p.ID WHERE h.CON_ID = ? AND h.SQL_ID IS NOT NULL AND h.SQL_ID != ? AND SAMPLE_ID > ? AND SESSION_TYPE = ? AND PLAN_ID > ?同时发现系统 sys 租户的【会话管理】中积压了的大量的慢 SQL,如下所示:

对应的 SQL 语句如下:
SELECT TENANT_ID, SVR_IP, SVR_PORT, COUNT(*) AS cnt FROM CDB_OB_TABLE_LOCATIONS WHERE ROLE = 'LEADER' AND ( TENANT_ID = 1 AND TABLE_ID > 500000 OR LS_ID > 1 ) GROUP BY TENANT_ID, SVR_IP, SVR_PORT select t1.tenant_id, t1.database_name, t3.object_id as database_id, sum(t2.data_size) as data_size, sum(t2.required_size) as required_size from ( select tenant_id, database_name, table_id, tablet_id from cdb_ob_table_locations group by tenant_id, database_name, tablet_id ) t1 left join ( select tenant_id, tablet_id, svr_ip, svr_port, data_size, required_size from cdb_ob_tablet_replicas ) t2 on t1.tenant_id = t2.tenant_id and t1.tablet_id = t2.tablet_id left join ( select con_id, object_name, object_id from CDB_OBJECTS where object_type = 'DATABASE' ) t3 on t1.tenant_id = t3.con_id and t1.database_name = t3.object_name group by t1.tenant_id, t1.database_name基于上面的 SQL 分析,基本判断直接原因是 ocp_monitor 用户在收集集群的监控信息(比如统计各个租户的副本数量、各个数据库磁盘占用大小等)时,因为集群的表数量、分区数量过多或者业务租户数量太多(比如这边第二个场景中业务租户数量超过了 100 个)导致系统 sys 租户出现了大量的慢 SQL,这些慢 SQL 长期积压后将 sys 租户的 CPU 和内存打爆了。
问题的风险及影响
系统 sys 租户状态变成不可用,影响了该集群的正常工作和运维。
适用版本
OceanBase 数据库 V4.x 及更高版本。
OCP V3.2.x 及更高版本。
解决方法
删掉多余的不再使用的业务租户,减少需要监控的业务租户的数据量。
调大 sys 租户的 CPU/Memory 资源规格,增加 sys 租户的可用资源。
暂时屏蔽相关的 ocp_monitor 监控。
vi /home/admin/ocp_agent/conf/module_config/monitor_ob.yaml将下面两条 SQL 相关的内容都注释掉:

最后修改完需要重启 OCP Agent 才能生效:
# /home/admin/ocpagent/bin/ocp_agentctl restart 或者: # systemctl restart ocp_agent
规避方式
无。