做过数据库运维的人大概都有过这样的经历:线上突然变慢,打开监控一看,什么都正常;去数据库里翻日志,密密麻麻不知从何看起;找DBA来排查,第一句话往往是——"你们有没有开统计?"
这个问题背后其实是一个很根本的话题:一套数据库,怎么才能让你真正看见它在做什么?
KingbaseES(以下简称KES)在这方面做了一套相对完整的设计。本文就来拆解它的性能观测体系——从动态性能视图到日志分析工具,把这套"记账系统"讲清楚。
一、先搞清楚:数据是怎么被收集的?
KES 在运行过程中持续产生大量统计信息,涵盖等待事件、IO操作、SQL执行情况等维度。但这些信息并不存储在普通关系表里,而是以哈希表或动态数组的形式存在于共享内存或本地内存中,通过动态性能视图的方式暴露出来供查询。
这种设计的好处是读写代价低、不污染存储,代价是数据不能像普通表那样随意修改——想清空只能调专门的重置函数,比如 sys_stat_reset() 或 sys_stat_statements_reset(),直接用 DELETE 会直接报错:
kingbase=# DELETE sys_stat_statements_all;
ERROR: cannot delete from view "sys_stat_statements_all" ...
这个设计本身就是一种约束:统计数据的管理权在系统,不在你。
二、动态性能视图:两个维度,四类数据
KES 的动态性能视图按统计范围分为实例级和当前库两类,按时效性分为实时状态和累积状态两类,组合起来覆盖了绝大多数观测场景。
2.1 实时状态视图:此刻正在发生什么?
最核心的是 sys_stat_activity,每个服务器进程一行,记录当前状态、等待事件、正在执行的 SQL 等信息。排查慢查询、锁等待、长事务,基本都从这里开始:
SELECT pid, wait_event, state, substr(query,0,20) as query, backend_type
FROM sys_stat_activity;
输出结果里能直接看到哪个进程在等什么、在跑什么。比如 wait_event 显示 SysSleep,说明这个进程在主动等待;显示 Lock 相关字样,那就要看锁情况了。
除此之外还有一类偏门但很有用的:实时 TPS/QPS 视图。
sys_stat_metric_history 记录了过去一小时内每15秒粒度的平均 TPS 和 QPS,不需要等待 1 秒的函数调用,直接查即可。对于判断业务流量是否异常、高峰时段定位,这个视图比凭感觉靠谱得多。但需要注意,这个功能默认是关的,要先打开 track_real_stats 参数。
2.2 累积状态视图:过去发生了什么?
累积视图更适合趋势分析和历史问题复盘。比如 sys_stat_database 记录了每个库的事务提交次数、回滚次数、插入/更新/删除行数等,服务器正常关闭时会持久化到文件,下次启动时再加载回来。
SELECT datid, datname, xact_commit, xact_rollback, tup_inserted, tup_updated, tup_deleted
FROM sys_stat_database WHERE datname = 'kingbase';
这些数字在日常状态下可能意义不大,但对比昨天和今天的值,或者对比事故前后的值,往往能直接说明问题。
2.3 数据库对象级统计:哪张表最"累"?
sys_stat_user_tables 是开发者排查性能问题时最常用的视图之一,记录了每张用户表的顺序扫描次数(seq_scan)、索引扫描次数(idx_scan)、各类 DML 操作的行数等。
SELECT relid, seq_scan, idx_scan, n_tup_ins, n_tup_upd, n_tup_del
FROM sys_stat_user_tables WHERE relname = 'ksh_statements';
如果一张表的 seq_scan 远大于 idx_scan,说明索引没被用上,或者压根没建索引,是性能优化的一个明显信号。
类似地,sys_statio_* 系列视图专门记录 IO 情况,sys_stat_user_functions 记录函数执行情况,粒度细到每一个对象。
三、GUC 参数:统计系统的开关面板
KES 的统计能力不是"开箱全给你",而是通过一组 GUC 参数控制采集范围,按需开启,避免不必要的性能开销。
几个关键开关:
track_counts(默认开启):最基础的统计开关,控制关系表和索引的访问统计。关掉它,AUTOVACUUM 会失效,KWR 报告也会缺数据,一般不建议动。
track_io_timing(默认关闭):控制 IO 调用时间统计。开启后才能看到块读写耗时,执行计划里也会出现 I/O Read Time 等信息。代价是每次 IO 调用都要额外计时,有一定开销,建议在需要排查 IO 问题时才打开。
track_functions(默认 none):控制用户自定义函数的统计。如果怀疑某个存储过程有性能问题,可以临时设置为 pl,只跟踪过程语言函数,开销可控。
track_activities(默认开启):支撑 sys_stat_activity 视图的基础开关,同时也支撑各类进度视图(sys_stat_progress_*)。用来看长耗时操作(比如创建大索引)的进度,非常实用。
理解这些开关的逻辑之后,你会发现 KES 的统计体系其实是按成本分层的:越细粒度的统计,开销越大,默认越保守。这是一种合理的工程取舍。
四、kbbadger:当问题藏在日志里
动态性能视图解决的是"现在"和"历史累计"的问题,但有一类场景它覆盖不到——已经发生过、但没有留存统计快照的历史事故。
这时候能救命的是日志。
KES 提供了 kbbadger 这个命令行工具,专门用于分析运行日志,并生成可交互的 HTML 报告。
使用前需要在 kingbase.conf 中做基本配置,核心是打开几个 log 参数:
log_min_duration_statement = 0 # 记录所有SQL执行时间
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
log_temp_files = 0
log_autovacuum_min_duration = 0
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,remote=%h '
配置完成后跑一段负载,然后直接对日志目录执行分析:
$ kbbadger ./sys_log/kingbase* -f stderr -J 12 -j 32
生成的报告涵盖的内容相当全面:耗时最多的查询、最常见的错误、查询时间分布直方图、检查点统计、自动 VACUUM 情况、锁等待、取消最多的查询……而且所有图表都可以单独下载为 PNG。
一个真实场景的参考数据:100 仓库、100 并发的 TPCC 压测跑约 23 分钟,产生约 6.3 GB 日志,kbbadger 能完整解析并生成报告。
什么时候用 kbbadger?
两种典型场景:一是 KES 版本较低、KWR(性能快照)功能不支持的情况下,kbbadger 是直接可用的替代方案;二是事故已经发生、需要回溯定位的情况,只要日志还在,就能分析。
不过有一点需要提醒:开启全量日志记录对磁盘和服务器性能都有明显影响,6.3 GB 只是 23 分钟的量,长时间开启会是个不小的负担。分析完成之后,记得及时关掉相关的 log 参数。
五、一点思考
把 KES 的这套观测体系整体看下来,有一个感受:它在结构上是分层的,在使用上是渐进的。
动态视图用于常态监控,GUC 参数控制精细化采集的成本,kbbadger 应对历史问题复盘——三个层次各司其职,组合起来基本能覆盖从日常运维到深度排障的各种场景。
当然,工具再完善,也需要人去看、去问正确的问题。
性能问题最难的不是没有数据,而是面对一大堆数据不知道该看哪里。希望这篇文章能帮你在下次排查时,多一点方向感。