核心内容摘要
差差差不多,生活就该如此鲜活!
在高并发、海量数据的业务场景下数据库性能直接决定了应用系统的响应速度和稳定性而瓶颈排查则是性能调优的核心前提——只有精准定位问题根源才能避免盲目调参、优化无效的内耗。
KingbaseES作为国产数据库中的优秀代表在政务、金融、企业级应用中广泛部署其瓶颈排查有一套标准化、可落地的方法论核心可分为「实例级别」和「语句级别」两个层次覆盖从整体到局部的全场景排查需求。
本文将基于KingbaseES的性能排查特性结合实操命令、工具使用和典型场景案例详细拆解每一种排查手段的
使用方法、参数配置和结果分析帮助技术从业者快速掌握从整体健康度诊断到单条SQL优化的全流程技巧真正实现“排查有方向、优化有依据”。
实例级别排查搞定数据库整体性能瓶颈实例级别排查的核心目标是分析数据库实例的整体健康状况判断是否存在系统负载过高、IO瓶颈、内存不足、连接异常等全局性问题适用于压测场景优化、上线前全量调优、业务整体响应缓慢等场景——比如当用户反馈“整个系统卡顿所有接口响应都超过3秒”时优先从实例级别入手排除全局性问题后再深入局部语句。
KingbaseES提供了KWR、KSH、KDDM、KWR DIFF四大核心工具搭配系统视图补充分析形成了完整的实例级排查体系每一种工具都有其专属场景和优势无需重复使用可根据问题场景精准选择。
1 KWR报告实例健康度的“全景体检报告”KWRKingbase Workload Repository报告是实例级别排查的首选工具相当于给数据库做了一次“全景体检”能够全面采集系统负载、等待时间、IO使用、内存消耗、Top SQL等核心指标通过对比不同时间点的快照数据清晰呈现数据库的性能变化趋势是判断整体健康状况的最直观手段。
不同于简单的指标查询KWR报告能够将分散的性能数据进行汇总分析自动识别高消耗资源的操作帮助我们快速锁定“哪些操作占用了最多CPU”“IO瓶颈出在哪里”“哪些SQL是性能拖油瓶”为后续优化提供明确方向。
需要注意的是KWR依赖sys_kwr扩展且需要提前配置相关参数确保数据采集的完整性。
KWR的使用分为「参数配置→生成快照→生成报告」三步所有操作均无需重启数据库修改参数后reload即可生效降低了线上环境的使用风险。
第一步启用sys_kwr扩展并配置参数-- 查看已安装扩展确认sys_kwr是否已启用\dx-- 安装sys_kwr扩展若未安装Createextension sys_kwr;-- 配置核心参数修改kingbase.conf后执行reloadtrack_sqlon-- 开启SQL跟踪必配track_instanceon-- KWR
3版本新增跟踪实例整体状态track_wait_timingon-- 跟踪等待事件时间默认开启track_countson-- 跟踪统计信息默认开启track_io_timingon-- 跟踪IO操作时间必配track_functionsall-- 跟踪所有函数执行可选sys_stat_statements.tracktop-- 跟踪Top SQL与KWR联动-- 执行参数重载无需重启数据库selectsys_reload_conf();第二步生成快照快照是KWR报告的核心数据来源需在关键时间点生成-- 生成第一个快照比如业务低峰期作为基准SELECT*FROMperf.create_snapshot();-- 获得快照1快照ID自动递增-- 执行一些业务操作或等待业务运行一段时间比如10分钟CREATETABLEIFNOTEXISTSt1(idint);-- 示例创建测试表SELECTcount(*)FROMt1;-- 示例执行简单查询-- 生成第二个快照比如业务高峰期或出现性能问题时SELECT*FROMperf.create_snapshot();-- 获得快照2第三步生成KWR报告支持TEXT和HTML两种格式HTML格式更直观推荐线上使用-- 生成TEXT版本报告适合命令行快速查看SELECT*FROMperf.kwr_report(1,
;-- 1为起始快照ID2为结束快照ID-- 生成HTML版本报告适合详细分析带图表和格式化展示SELECT*FROMperf.kwr_report(1,2,html);-- 补充报告自动保存路径——DATA目录下的sys_log子目录可直接下载查看很多人生成KWR报告后无从下手其实重点关注3个部分即可系统负载概况查看数据库整体CPU、内存、IO使用率判断是否存在资源耗尽的情况等待事件分析重点关注“等待时间占比最高”的事件比如IO等待过高说明存在磁盘读写瓶颈锁等待过高说明存在事务阻塞Top SQL列表定位执行时间最长、消耗资源最多的SQL语句这些语句往往是实例性能的“拖油瓶”后续可重点优化。
2 KSH业务卡顿瞬间的“高清抓拍器”如果说KWR是“定期体检”那么KSHKingbase Session History就是“应急抓拍”——当业务出现突发卡顿、响应缓慢但KWR报告无法捕捉到瞬间的性能波动时KSH就能发挥作用。
它以每秒1次的频率采样会话和数据将采集到的信息存入内存的Ringbuf队列采集频率远高于KWR能够精准捕捉到突发性能问题的细节。
需要注意的是KSH采集频率高、产生的数据量大对系统资源有一定消耗因此不建议长期开启仅在业务出现卡顿的时间段临时开启采集完成后立即关闭避免影响数据库正常运行。
此外旧版本KingbaseES中KSH是独立扩展新版本如V8R6B24及以上已集成到sys_kwr扩展中无需单独安装简化了使用流程。
--
确保sys_kwr扩展已启用若未启用执行Create extension sys_kwr;--
开启KSH采集无需重启reload即可生效setsys_kwr.collect_kshon;selectsys_reload_conf();--
查看采集的数据内存中实时数据和数据库历史数据分开查看-- 查看内存中Ringbuf的实时数据最新采集的会话信息SELECT*FROMperf.session_history;-- 查看数据库中保存的历史数据已落盘的采样数据SELECT*FROMperf.ksh_history;--
生成KSH报告分析卡顿原因SELECTperf.ksh_report(start_ts,duration,slot_width,write_to_file);-- 参数说明start_ts采集开始时间、duration采集时长、slot_width采样间隔、write_to_file是否写入文件--
业务恢复后立即关闭KSH采集降低资源消耗setsys_kwr.collect_kshoff;selectsys_reload_conf();
3 KDDM性能问题的“智能诊断医生”对于经验不足的技术从业者来说最头疼的不是采集性能数据而是分析数据、找到优化方向——KWR和KSH能给出数据但需要人工判断优化方案而KDDMKingbase Diagnostic and Debugging Manager则完美解决了这个问题它相当于一个“智能诊断医生”。
KDDM基于KWR快照采集的性能指标和数据库时间模型DB Time自动分析等待事件、IO、网络、内存和SQL执行时间等问题直接给出针对性的优化建议无需人工深入分析数据极大提升了排查效率。
其核心优势在于“诊断建议”一体化尤其适合新手使用同时也能为资深工程师提供优化参考。
--
启用sys_kwr扩展KDDM依赖KWR快照数据Createextension sys_kwr;--
生成两个快照与KWR快照生成方式一致覆盖问题时间段SELECT*FROMperf.create_snapshot();-- 快照1基准INSERTINTOt1SELECTgenerate_series(1,
;-- 模拟业务操作大批量插入SELECT*FROMperf.create_snapshot();-- 快照2问题时段--
生成KDDM诊断报告TEXT格式SELECT*FROMperf.kddm_report(1,
;-- 1为起始快照ID2为结束快照ID--
生成报告到指定文件方便保存和分享推荐使用SELECT*FROMperf.kddm_report_to_file(1,2,/home/test/kddm_1_
txt);--
生成指定SQL的诊断报告针对性分析某条异常SQLSELECT*FROMperf.kddm_sql_report(1,2,
;-- 最后一个参数为SQL ID示例优化建议KDDM报告中可能会出现“建议调整work_mem参数至128MB以减少磁盘排序”“建议为t1表的id字段创建索引避免全表扫描”等明确提示直接按照建议调整即可无需再反复测试参数。
4 KWR DIFF性能变化的“差异对比镜”在数据库运维过程中我们经常会遇到这样的场景参数调整后性能是否有提升业务高峰期和低谷期的性能差异根源是什么此时KWR DIFF报告就能发挥作用它相当于一个“差异对比镜”通过分析两个KWR报告之间的差异精准定位性能变化的原因验证优化效果。
KWR DIFF的核心是“对比两个时间段的KWR数据”需要生成4个快照两个KWR报告各需2个快照通过对比两个报告的指标变化比如CPU使用率下降了多少、Top SQL执行时间缩短了多久、等待事件占比变化等判断优化操作是否有效或找到性能退化的根源。
--
启用sys_kwr扩展Createextension sys_kwr;--
生成4个快照两个KWR报告每个报告2个快照-- 第一个KWR报告比如优化前快照
SELECT*FROMperf.create_snapshot();-- 快照1优化前基准CREATETABLEt1(aint);INSERTINTOt1SELECTgenerate_series(1,
;SELECT*FROMperf.create_snapshot();-- 快照2优化前问题时段-- 第二个KWR报告比如优化后快照
INSERTINTOt1SELECTgenerate_series(1,
;-- 模拟优化后的业务操作SELECT*FROMperf.create_snapshot();-- 快照3优化后基准INSERTINTOt1SELECTgenerate_series(1,
;SELECT*FROMperf.create_snapshot();-- 快照4优化后业务时段--
生成KWR DIFF报告保存为HTML格式方便对比查看SELECT*FROMperf.kwr_diff_report_to_file(1,2,3,4,/home/test/kwr_diff_rpt_
html);参数解读snap_1第一个KWR报告的起始快照ID优化前基准snap_2第一个KWR报告的结束快照ID优化前问题时段snap_3第二个KWR报告的起始快照ID优化后基准snap_4第二个KWR报告的结束快照ID优化后业务时段。
5 Kbbadger日志分析的“高效工具”当数据库出现异常但上述工具无法定位问题时日志分析就成为了最后的突破口——KingbaseES的日志文件中记录了所有SQL执行、连接、错误等信息而Kbbadger则是一款专门用于分析KingbaseES日志的工具能够高效解析大型日志文件自动识别日志格式生成可缩放的图表突出显示异常SQL极大提升日志分析效率。
Kbbadger支持解析syslog、stderr、csvlog、jsonlog等多种日志格式能够过滤指定时间段、指定类型的日志排除无效信息精准定位异常操作尤其适合排查“偶发性能问题”“日志量过大无法手动分析”的场景。
使用Kbbadger前需先配置日志参数确保日志信息完整且可解析--
配置日志参数修改kingbase.conf后reloadlog_min_duration_statement0-- 记录所有SQL语句的执行时间必配需reloadlog_statementoff-- 禁止开启默认关闭开启后日志量过大影响解析lc_messagesen_US.UTF-8-- 日志语言必须设为英文否则Kbbadger无法解析--
重载参数selectsys_reload_conf();常用Kbbadger命令覆盖大部分日志分析场景#
解析单个日志文件kbbadger /var/log/kingbase.log#
解析多个日志文件包括压缩文件kbbadger /var/log/kingbase.log.
gz /var/log/kingbase.log.
gz /var/log/kingbase.log#
解析指定时间段的日志-b开始时间-e结束时间kbbadger -b
10:56:11-e
10:59:11/var/log/kingbase.log#
排除指定类型的SQL比如排除COPY、COMMIT语句聚焦查询语句kbbadger --exclude-query^(COPY|COMMIT)/var/log/kingbase.log#
从标准输入解析日志适合管道操作cat/var/log/kingbase.log|kbbadger -#
多CPU并行解析加快大型日志文件解析速度-j后接CPU核心数kbbadger -j8/sys_log/kingbase-
1
1-main.log#
解析指定前缀格式的日志适配不同的日志配置kbbadger --prefix%t [%p]: user%u,db%d,client%h/sys_log/kingbase-
*
6 核心系统视图补充排查的“关键抓手”除了上述四大工具KingbaseES还提供了多个系统视图用于补充排查实例级问题尤其是在定位具体资源消耗、连接异常、锁阻塞等场景时视图查询更加便捷、精准常用视图如下附核心查询场景
sys_stat_statements 视图SQL执行情况的“明细台账”该视图是排查SQL层面资源消耗的核心视图能够详细记录所有SQL语句的执行情况当KWR报告定位到Top SQL后可通过该视图查看具体明细为SQL优化提供依据。
可查询核心内容语句内容具体的SQL语句文本执行统计执行次数、解析次数、解析时间内存使用shared_buffer使用情况磁盘读/缓存命中其他内存temp_buffer、work_mem、maintenance_mem的命中情况通过local字段排查。
示例查询查看执行次数最多、消耗时间最长的前10条SQLSELECTqueryid,query,calls,total_time,mean_timeFROMsys_stat_statementsORDERBYtotal_timeDESCLIMIT10;
sys_stat_activity 视图数据库连接的“实时监控台”当业务出现“连接超时”“无法连接数据库”“会话阻塞”等问题时可通过该视图查看当前数据库的所有连接信息定位异常连接。
可查询核心内容连接状态是否有等待事件、锁信息连接明细连接方式、客户端地址时间信息连接开始时间、事务开始时间、查询开始时间执行信息当前正在执行的查询语句。
示例查询查看所有处于等待状态的连接SELECTpid,usename,client_addr,wait_event,queryFROMsys_stat_activityWHEREwait_eventISNOTNULL;
IO分析视图sys_stdio_user_tables sys_stdio_user_indexes这两个视图用于排查IO瓶颈能够详细记录表和索引的读写情况判断IO压力是否来自表数据读取或索引读取。
可查询核心内容表数据读盘次数、内存命中次数索引数据读盘次数、内存命中次数Toast表读盘次数、内存命中次数Toast表用于存储大字段数据易被忽略。
sys_locks 视图锁信息的“明细清单”当数据库出现“事务阻塞”“死锁”等问题时可通过该视图查看所有锁的持有和等待情况定位阻塞源快速解锁。
示例查询查看所有锁等待情况定位阻塞进程SELECTlocktype,database,relation,pid,mode,grantedFROMsys_locksWHEREgrantedfalse;
语句级别排查精准优化单条SQL的“瓶颈点”当实例级别排查排除了全局性问题或定位到具体的高消耗SQL后就需要进入语句级别排查——聚焦单条SQL语句或批量跑批语句分析其执行过程定位具体的性能瓶颈比如全表扫描、磁盘排序、索引失效等这是性能优化的“最后一公里”。
语句级别排查的核心工具是「执行计划」KingbaseES中通过explain命令查看执行计划这是最常用、最直接的SQL优化手段——执行计划能够清晰呈现SQL语句的执行路径比如“如何扫描表”“如何连接表”“是否排序”“是否使用索引”等通过分析执行计划就能快速找到SQL的性能瓶颈。
1 explain命令详解看懂执行计划的“说明书”explain命令的核心作用是“模拟SQL执行输出执行路径和成本估算”无需实际执行SQL除非加上analyze选项不会对数据库产生业务影响可放心在生产环境使用。
命令格式与可选参数explain[option]statement;其中option为可选项支持5种参数的组合使用核心参数说明如下重点掌握前4个analyze执行SQL并显示实际执行时间默认false能够对比“估算成本”和“实际成本”精准定位偏差verbose显示附加信息如计划树每个节点的输出字段名默认false适合深入分析执行细节costs显示执行计划的成本CPU成本IO成本默认true成本越高执行效率越低buffers显示缓冲区使用信息共享块、本地块、临时读写块默认false前置条件是开启analyzeformat指定输出格式TEXT/XML/JSON/YAML默认TEXTJSON格式适合程序解析TEXT格式适合人工查看。
常用命令组合生产环境高频使用--
基础查看执行计划仅估算成本不执行SQLexplainSELECTcount(*)FROMt1WHEREid1000;--
查看实际执行情况执行SQL显示实际时间和缓冲区使用推荐使用explainanalyzebuffersSELECTcount(*)FROMt1WHEREid1000;--
查看详细执行细节附加字段信息适合复杂SQL分析explainverboseanalyzeSELECTcount(*)FROMt1WHEREid1000;
2 执行计划分析思路3步找到瓶颈点很多人看不懂执行计划核心是没有掌握分析思路——执行计划的分析无需逐行阅读重点遵循“找成本→找步骤→找问题”的3步思路快速定位瓶颈。
第一步找总体成本判断SQL执行效率执行计划开头通常会显示“总估算成本”Total runtime。
这个数值越大说明SQL运行得越慢。
对于简单的查询最好让成本保持在1000以下而对于复杂的查询则应尽量控制在10000以内。
如果成本超过了这些范围就需要仔细分析一下了。
第二步找高成本步骤定位性能瓶颈点在执行计划里每个步骤都会标出它自己的“成本”和到这一步为止的“总成本”。
你需要特别注意那些“总成本”占大头的步骤因为这些通常是拖慢你SQL查询速度的地方。
常见的可能拖慢速度的操作有全表扫描、磁盘上的排序操作、以及在处理大量数据时使用的嵌套循环连接等。
第三步分析步骤细节找到优化方向针对高成本步骤围绕3个核心点分析找到优化方向scan方式扫描方式是否使用索引扫描Index Scan若使用全表扫描Seq Scan需判断是否合理比如表数据量极小全表扫描比索引扫描更快则合理否则需优化索引连接方式多表关联场景多表关联时是否使用了合适的连接方式Hash Join适合大数据量Nested Loop适合小数据量Merge Join适合有序数据其他操作是否存在磁盘排序、临时表创建等耗时操作这些操作往往是性能瓶颈的核心原因。
实战案例统计信息不准确导致索引失效现象t1表的id字段已创建索引但查询语句仍使用全表扫描执行效率低下执行计划如下explainanalyzeSELECT*FROMt1WHEREid10000;-- 执行计划关键信息-- Seq Scan on t1 (cost
0.
.
1
00 rows1 width
(actual time
500.
.
8
00 ms)-- Filter: (id
-- Total runtime:
8
50 ms分析虽然id字段已经建了索引但查询时还是用了全表扫描。
主要原因就是统计信息不准。
KingbaseES的优化器会根据这些统计信息来决定要不要用索引。
如果数据大量增删后没有更新统计信息优化器就会误判数据分布情况从而导致索引没被用上。
验证查看执行计划中“估算行数”与“实际行数”的差异若差异较大说明统计信息不准确上述执行计划中估算行数rows1与实际行数假设实际返回1行差异不大但仍未使用索引进一步查看统计信息-- 查看t1表的统计信息更新时间SELECTrelname,last_analyzeFROMpg_stat_user_tablesWHERErelnamet1;若last_analyze时间较早说明统计信息过时需手动更新。
优化方案更新表的统计信息让优化器准确判断数据分布-- 更新t1表的统计信息ANALYZEt1;-- 重新查看执行计划已使用索引扫描Index Scan using t1_id_idx on t1explainanalyzeSELECT*FROMt1WHEREid10000;-- 优化后执行时间5ms以内
四、
总结排查数据库瓶颈这事儿对搞技术的人来说特别重要特别是现在国产数据库用得这么广泛。
要是你能搞定排查方法那就能迅速解决性能问题让系统更稳、用户体验更好。