【OceanBase系列】—— 运维实战:从集群状态到SQL性能的常用诊断SQL
1. OceanBase运维实战集群与租户健康检查作为一款企业级分布式数据库OceanBase的稳定运行离不开日常的健康检查。我见过太多因为忽视基础检查而导致的故障案例这里分享几个最实用的诊断SQL帮你快速掌握集群脉搏。先看集群基本信息这是运维的起点。执行show variables like version_comment能立即获取当前OceanBase版本这个命令简单但关键不同版本的特性差异很大。记得有次升级后性能异常就是靠这个命令发现测试环境版本与生产环境不一致。集群拓扑检查更重要。SELECT * FROM dba_ob_zones会列出所有Zone信息包括状态、合并版本等。重点关注STATUS字段正常应该是ACTIVE如果出现INACTIVE就要警惕了。配合select * from DBA_OB_SERVERS查看各节点状态我习惯用这个命令做每日巡检5秒就能掌握全局。租户健康检查是另一重点。这条SQL我用了三年依然实用SELECT tenant_id,tenant_name,primary_zone,compatibility_mode FROM oceanbase.__all_tenant;它能显示所有租户的分布情况和兼容模式。特别是primary_zone字段能快速定位主副本分布是否均衡。上周就靠它发现某个租户的主副本全集中在同一个机柜及时避免了单点风险。内存检查也不能忽视。运行select TENANT_ID,SVR_IP,SVR_PORT,HOLD/1024/1024/1024,FREE/1024/1024/1024 from oceanbase.GV$OB_TENANT_MEMORY where tenant_id 1002;这个命令按GB显示租户内存使用情况HOLD是已用内存FREE是剩余内存。当FREE低于总内存的20%时就需要关注了我设置了个定时任务每小时检查这个指标。2. 资源与容量精细监控实战资源监控是保证OceanBase稳定运行的关键。先说CPU资源监控这个复杂查询我优化过多次select t1.name resource_pool_name, t2.name unit_config_name, t2.max_cpu, t2.min_cpu, round(t2.memory_size/1024/1024/1024,2) mem_size_gb, round(t2.log_disk_size/1024/1024/1024,2) log_disk_size_gb from __all_resource_pool t1 join __all_unit_config t2 on (t1.unit_config_idt2.unit_config_id) order by t1.resource_pool_id;它能清晰展示每个资源池的CPU和内存配置max_cpu和min_cpu的差值过大可能引发资源争抢这个经验来自去年的一次性能调优。磁盘空间监控更实用。这个统计租户大小的SQL我几乎每天用select t.tenant_name, round(sum(t2.data_size)/1024/1024/1024,2) as data_size_gb, round(sum(t2.required_size)/1024/1024/1024,2) as required_size_gb from dba_ob_tenants t,cdb_ob_table_locations t1,cdb_ob_tablet_replicas t2 where t.tenant_idt1.tenant_id and t1.svr_ipt2.svr_ip and t1.tenant_idt2.tenant_id and t1.ls_idt2.ls_id and t1.tablet_idt2.tablet_id group by t.tenant_name;data_size_gb是实际数据大小required_size_gb是包含副本的预估空间。当required_size接近磁盘总空间的80%时就该考虑扩容了。对于表级空间监控这个命令帮我们发现了多个大表select t1.table_name, round(sum(t2.data_size)/1024/1024/1024,2) as data_size_gb from dba_ob_tenants t,cdb_ob_table_locations t1,cdb_ob_tablet_replicas t2 where t.tenant_name生产租户 and t1.database_name核心库 group by t1.table_name order by data_size_gb desc;去年用这个命令找出了几个可以归档的历史表直接节省了30%的存储空间。3. SQL性能分析与优化技巧SQL性能是DBA最常遇到的问题。先说如何找问题SQL这个查询是我的首选select SQL_ID, avg(ELAPSED_TIME), avg(QUEUE_TIME), count(*) cnt, avg(execute_time) avg_exec_time from v$OB_SQL_AUDIT where tenant_id1001 and request_time (time_to_usec(now()) - 3600000000) group by 1 order by avg_exec_time * cnt desc limit 10;它找出最近1小时内执行耗时最长的TOP10 SQL按总耗时排序。avg_exec_time是平均执行时间cnt是执行次数两者乘积能真实反映SQL对系统的整体影响。拿到SQL_ID后用这个命令看详细执行计划select * from GV$OB_PLAN_CACHE_PLAN_STAT where sql_id刚才查到的SQL_ID;重点关注EXECUTIONS执行次数、DISK_READS物理读、ELAPSED_TIME总耗时这几个字段。物理读过多的SQL通常需要优化索引。对于执行计划的分析这个Hint技巧很实用SELECT /* INDEX(表名 索引名) */ * FROM 表名 WHERE 条件;强制使用指定索引可以用来验证索引效果。但要注意这只是临时方案长期还是应该优化统计信息。慢SQL实时监控也很重要。我部署了这个查询作为定时任务select SQL_ID, substr(query_sql, 1, 200) as query_sql, sum(elapsed_time - queue_time) sum_t, count(*) cnt from oceanbase.gv$ob_sql_audit where tenant_id 1001 and request_time (time_to_usec(now()) - 60000000) and elapsed_time 1000000 group by sql_id order by sum_t desc;它监控过去1分钟内执行时间超过1秒的SQL按CPU总耗时排序。queue_time是等待时间elapsed_time - queue_time才是实际消耗的CPU时间。4. 高级诊断与运维技巧日志流监控是分布式数据库特有的。这个查询我用来检查LS健康状态select svr_ip,svr_port,tenant_id,ls_id,ls_state,tablet_count from __all_virtual_ls_info where ls_state ! NORMAL;任何非NORMAL状态的日志流都需要立即检查。tablet_count字段还能看出数据分布是否均衡。对于DDL操作监控这个命令帮我们定位过多次卡住的问题select * from oceanbase.gv$session_longops where opname like %CREATE INDEX% order by elapsed_seconds desc;elapsed_seconds显示已执行时间message字段包含详细进度。上周一个建索引任务卡住就是用这个命令发现是在排序阶段停滞。最后分享一个自增列监控技巧select a.table_name,b.AUTO_INCREMENT_VALUE from oceanbase.__all_table a, oceanbase.DBA_OB_AUTO_INCREMENT b where a.table_idb.AUTO_INCREMENT_KEY and a.autoinc_column_idb.COLUMN_ID and a.TABLE_NAME重要表名;AUTO_INCREMENT_VALUE显示下一个自增值接近最大值时需要及时处理。我们曾因此避免了多次主键溢出事故。