☰
数据库监测指标清单:从Oracle到DB2的监控要点与避坑指南
2026/10/13 16:37:28 网站建设 项目流程

简介:数据库监测是保障数据库高效、稳定运行的核心环节,这份文档面向DBA、运维及性能调优人员,系统梳理了Oracle、SQL Server、Sybase、Informix、DB2等主流数据库的关键监测指标。内容涵盖连接会话与事务处理、锁和死锁检测、缓冲池与Cache命中率、进程与内存利用率、表空间与日志空间管理、I/O读写速率、检查点与多线程调度等多个维度,并对每类指标给出了具体监测参数,例如游标数、Session数、每秒事务数、Largest Chunk、Transaction Log Size、Page Read/Write Rate、Dead-lock Rate等,覆盖从操作系统交互到数据库内部结构的各层状态,帮助读者从性能、资源、并发、存储等层面建立完整监控视图。资源包共1个文件,为286KB的doc文档,内容按数据库类型分模块呈现,便于查阅和对照实践。已有83人学习/下载,适合正在构建数据库监控方案、梳理性能调优知识体系或开展数据库巡检的运维人员参考使用。

1. 数据库监测指标别靠背:这份清单解决的是“该看什么”和“怎么看”

做运维的前三年,我桌上总摆着一本打印出来的指标手册,Oracle、SQL Server、Sybase、Informix、DB2、MySQL的监控项密密麻麻排在一起。数据库监测指标这件事,难的不是采集工具,而是你不知道哪些指标真正反映问题。数据库监测指标清单这份文档,就是把六类数据库的几百个监测项按库、按模块归好了类:游标、Session、锁、缓冲池、表空间、网络读写、死锁信息全都有。它适合刚接手数据库监控的DBA,也适合做监控平台的人拿来当字段字典。看完你就知道,每个指标不是孤立数字,而是背后对应一种故障模式。接下来我就按库拆开讲,哪些指标值得每天看,哪些是忽悠人的。

2. 先啃 Oracle:游标、Session、锁与缓冲池命中率的真实读法

2.1 会话与游标:判断连接是否健康的两个起点

Oracle 指标里游标数和 Session 数排在前面,这俩是一对。游标数是当前打开的游标总量,Session 数是数据库当前的会话连接数。很多人一看 Session 数接近上限就慌,其实要先分清是活跃会话还是空闲会话。常见做法是查v$session的status字段,把 ACTIVE 和 INACTIVE 分开统计。

SELECT status, COUNT(*) FROM v$session GROUP BY status; SELECT COUNT(*) AS total_cursors FROM v$open_cursor;

第一句看会话状态分布,第二句看全局打开的游标总数。如果 INACTIVE 的会话特别多,问题多半出在应用层连接池没释放,而不是数据库自身。游标数高的时候,我更倾向于查v$sqlarea里open_versions很大的 SQL,而不是直接清缓存。

参数上要注意两点:OPEN_CURSORS是单个会话能打开的游标上限,默认值一般够用,但应用用了大量 PreparedStatement 不关闭时会撞上。另一个是SESSIONS参数,它受PROCESSES影响,改的时候两个要一起调,只改一个会在启动时报错。

2.2 锁和死锁:从数量倒推阻塞场景

数据库锁数量和死锁数量是监测并发控制的核心指标。Oracle 里查锁最直接的是v$lock,但v$lock是行级锁和对象锁的混合体,直接数会混入很多 TM 锁。我一般用下面这个查询把锁按类型和模式分好:

SELECT l.type, l.mode, COUNT(*) lock_count, s.username, s.machine FROM v$lock l LEFT JOIN v$session s ON l.sid = s.sid GROUP BY l.type, l.mode, s.username, s.machine ORDER BY lock_count DESC;

锁数量多不一定就是问题,要看阻塞链。实际排障时,先用v$session找BLOCKING_SESSION,再用v$session_wait看等待事件。有一种很常见的翻车现场:死锁数量一直在涨,但查v$lock没有锁,因为死锁已经被 Oracle 自动回滚释了。所以死锁监测要用alert_log抓ORA-00060,或者开启deadlock_detection跟踪,不能只看实时锁数量。

2.3 缓冲池命中率:别再盯着 98% 不放了

缓冲池命中率是最容易被误读的指标。文档里 Oracle 的 Cache 命中率和 Buffer 命中率都列了,但同样的 99% 命中率,在 OLTP 和 OLAP 场景下完全是两个意思。OLTP 大量短查询,命中率低反而说明数据访问模式合理;OLAP 全表扫描多,命中率虚高只是因为扫描过的块还在内存里。我统计过一份生产库,命中率 99.8%,但 AWR 里physical read total I/O requests照样高,因为吞吐大,1% 的未命中就能产生大量物理读。

想判断缓冲池是否够用,我一般看v$db_cache_advice,它会模拟不同db_cache_size下的物理读数量,那个趋势线比命中率更直观。另外Largest Chunk指标反映的是共享池里最大的空闲内存块,如果这个值越来越小,并伴随ORA-04031,说明共享池碎片化严重,该考虑shared_pool_reserved_size或者改用大页。

3. SQL Server 与 Sybase:性能计数器里的“速率”陷阱

3.1 SQL Server 的缓存与内存计数器怎么对应现实问题

SQL Server 部分文档列了 Page Read Rate、Page Write Rate、Free Data Cache Buffers,还有 SQL Memory Manager 下的一串内存计数器。这些指标有个共同点:它们都是速率或者瞬时值,单独看没有意义。比如 Page Read Rate 是每秒物理读页面数,要对比的是磁盘能力,而不是这条 SQL 本身。我看 SQL Server 的习惯是先看sys.dm_os_performance_counters里的关键计数器,再对照sys.dm_os_wait_stats里的PAGEIOLATCH_SH等待。

SELECT counter_name, cntr_value, CASE WHEN counter_name LIKE '%(KB/sec)%' OR counter_name LIKE '%(number/sec)%' THEN 'Rate' ELSE 'Snapshot' END AS counter_type FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Buffer Manager' AND counter_name IN ('Buffer cache hit ratio', 'Page reads/sec', 'Page writes/sec');

执行这段之前提醒一下:Buffer cache hit ratio 的 cntr_value 是累计值,不是百分比,要看Buffer cache hit ratio base做除法。这是一个特别容易踩的坑,很多监控平台的 SQL Server 命中率算出来超过 100%,就是因为直接拿cntr_value当百分比用了。正确算法是ratio / base * 100。

SQL Server 的Free Data Cache Buffers保持低位其实是正常状态,缓存就是用来用的,闲置太多反而说明内存分配过大了。真正要盯的是sys.dm_exec_query_stats里total_worker_time和total_elapsed_time的比值,那能看出 CPU 消耗集中在哪里。

3.2 Sybase 的 I/O 与网络包指标:容易误读的一组

Sybase 指标里有一串“每分钟”的计数器:每分钟读取次数、写入次数、读取输入数据包数、写入输出数据包数、读写错误数,还有服务器 CPU 时间和空闲时间。注意这里的时间单位是“每分钟”,不是秒。所以拿到这些指标后,第一件事就是确认采集间隔是不是 1 分钟,否则算出来的速率是错的。

Sybase 最常见的监测方式是sp_monitor,它会输出一段文本,里面有每秒 CPU 忙、IO 读写、包读写等数据,但它是累计值,两次执行之间的差值才是这段时间的变化。我习惯用一个脚本定时抓取两次,再做差。

-- 第一次执行,记录当前累计值 exec sp_monitor go -- 等60秒后执行第二次 exec sp_monitor go

看第二次输出时,重点看packets read和packets written的增量。如果网络读包增加但写包不涨,可能是客户端请求多但事务没有提交,要配合sysprocesses查阻塞。Sybase 的死锁指标在文档里单独列出,包括死锁数、最长死锁时间、死锁进程 ID,这些信息靠sp_configure开启死锁报告才能拿到,不然只有错误日志里有零散记录。

3.3 一份可以直接抄的采集 SQL 模板

无论是 SQL Server 还是 Sybase,我都不建议手工一条条执行。下面这个 SQL Server 模板,把缓冲池、连接和用户管理三类指标合并成一次查询,可以直接丢到监控脚本里,隔 60 秒跑一次。

SELECT GETDATE() AS collect_time, (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Buffer Manager' AND counter_name = 'Buffer cache hit ratio') * 1.0 / (SELECT NULLIF(cntr_value, 0) FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Buffer Manager' AND counter_name = 'Buffer cache hit ratio base') AS hit_ratio, (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:General Statistics' AND counter_name = 'User Connections') AS user_conn, (SELECT cntr_value FROM sys.dm_os_performance_counters WHERE object_name = 'SQLServer:Memory Manager' AND counter_name = 'Total Server Memory (KB)') AS total_mem_kb;

这里NULLIF是用来防止 base 为 0 时除零的,这个细节在很多生产环境里救过命。Total Server Memory是当前 SQL Server 持有的内存,配合Maximum Server Memory看,可以判断是不是内存压力过大,持续接近上限说明要评估 max server memory 的设置了。

4. Informix 与 DB2:冷门库的指标反而最需要整理

4.1 Informix 的空间与 checkpoint 指标

Informix 在很多公司里是“老遗产”一般的存在,文档里给的指标却最细:逻辑日志文件总数、表总数、表所用页面总数、块空间总数、剩余空间,还有 Server Mode、Check-point in progress、Page Size、Thread Spawn Rate、Virtual Processors 等。这些指标用一条onstat命令就能拿到一大半。

onstat -g chunk onstat -g dsk onstat -c | grep checkpoint

onstat -g chunk查看每个 chunk 的空间分配与剩余量,对应文档里的 Chunks、Space Allocated、Space Used、Space Utilization。onstat -g dsk看磁盘读写、排序溢出等速率指标。onstat -c输出的 checkpoint 配置里,Check-point in progress如果长时间为 1,说明检查点卡住了,通常是刷脏页太慢,要检查ONLILOGS目录所在的磁盘 I/O。

Informix 的Logical Log Records Write Rate和Logical Log Pages Write Rate是累计速率,两次采样差值才有意义。另外看Dead-lock Rate和Lock Wait Rate时,要分清楚是每分钟还是每个事务,文档里没写单位,实际用onstat -p看到的是自启动以来的累计次数,要除以运行秒数换算成速率。

4.2 DB2 的连接、代理与缓存池状态

DB2 指标分了三块:连接状态、代理状态、缓存池状态。连接状态里的Current Connections是当前连接数,Connection Rate是新连接建立速率,如果两者都高且伴随Agents Waiting上涨,说明并发连接超过了可用代理数量。DB2 的命令行工具db2pd比 SQL 查询更直接:

db2pd -db <数据库名> -agents db2pd -db <数据库名> -bufferpools db2pd -db <数据库名> -tcbstats

-agents输出的Agents Waiting和ActiveAgents就能对上文档里的 Active Agents、Idle Agents、Agents Waiting。-bufferpools里有 Buffer Pool Hit Ratio、Index Page Hit Ratio、Data Page Hit Ratio,注意 db2pd 的命中率已经是百分数,不用再乘 100。-tcbstats看的是表缓存,对应 Package Cache Hit Ratio 和 Catalog Cache Hit Ratio。

DB2 有篇文章里常提“Direct Reads”和“Direct Writes”,这是指绕过缓冲池直接读写的页数,通常发生在LONG VARCHAR大字段或临时表空间。如果 Direct Reads 占物理读的比例超过 30%,就要检查是不是有大字段操作没走缓冲池,不能只看缓冲池命中率。

4.3 用命令行工具拉取指标的工作习惯

Informix 和 DB2 不像 Oracle、SQL Server 那样有统一视图,所以我的习惯是把命令封装成脚本,定时跑并把结果落到表里。比如 DB2 的采集脚本,每次执行db2pd后把关键字段用awk抽出来,再插入监控表。这样能把文档里的指标和历史对比。

db2pd -db PROD -bufferpools | awk '/Buffer Pool Hit Ratio/{print $NF}' >> /var/lib/db2mon/bp_hit_ratio.log

这条命令把命中率数值追加到日志文件,配合 crontab 每 5 分钟一次,就能画出趋势。要提醒的是,db2pd的部分指标输出会因为授权级别不同而缺字段,至少要SYSADM或SYSMON权限。Informix 的onstat同理,需要informix用户执行,onstat -g系列有些选项还要特定诊断模式。

5. 数据库监测指标常见避坑:为什么采集到的数据经常“对不上号”

5.1 现象:命中率 99% 但查询还是慢

有一次给 Oracle 库做体检,缓冲池命中率长期 99.8%,但一个报表查询要跑 40 秒。一开始怀疑索引,后来查v$segment_statistics才发现,那个查询访问的表物理读在buffer busy waits里特别高。原因是命中率只覆盖了已访问的块,而大量的小表扫描产生的逻辑读都被缓存了,真正的物理读集中在几个热点块上。解决:不要单看整体命中率,要按对象拆,查dba_segments里各段的物理读取次数,找到真正拖后腿的表。

5.2 现象:死锁计数每天涨,却不知道锁在哪

某套 SQL Server 的Number of Deadlocks计数器一天涨到三位数,但抓死锁图困难,因为默认没开deadlock_trace。后来开启 1222 跟踪标记才看到,是应用层先更新主表再更新明细表,另一个进程顺序相反,造成循环等待。解决:所有数据库的死锁监测都要提前开启日志跟踪,别等出事再开。Oracle 里设置events '10046 trace name context forever, level 8'或简单点开deadlock_detection,SQL Server 用DBCC TRACEON(1222, -1),Sybase 靠sp_configure 'deadlock report'打开。代价是少量性能损耗,比裸奔强。

5.3 现象:表空间用了 80% 但文件没变大

Oracle 的表空间使用率一直卡在 80%,DBA 急着加文件,我查了一眼发现是TEMPORARY表空间,排序溢出导致临时段占用,但临时段会在会话结束后自动释放。那个 80% 其实是峰值快照,不是持续水位。解决:看表空间使用率时先分清楚永久还是临时,临时表空间要看v$sort_usage里的当前排序段,而不是dba_tablespaces的分配总量。同理,Sybase 和 Informix 的表空间“已用空间”如果包含逻辑日志,也要单独拆出来。

5.4 现象:SQL Server 内存计数器一直在涨

SQL Server:Memory Manager的Total Server Memory持续走高,新手以为内存泄漏。实际是 SQL Server 默认用尽它认为合理的内存,并缓存在 buffer pool 里。如果不想让它吃掉整个机器内存,要在sp_configure里设置max server memory,并预留内存给操作系统。完整设置方式:用sp_configure 'show advanced options', 1后改max server memory,重启服务生效。从那以后我遇到类似问题,先看sys.dm_os_sys_memory判断是否物理内存不足,而不是单看 SQL Server 自己的计数器。

5.5 现象:用快照差值算速率时出现负数

数据库监测指标里的速率,大部分是靠两次快照做差值再除以时间间隔得到的。有一次 Sybase 的sp_monitor二次采样后包写入速率算出来是 -2,原因是对应的计数器发生了重置,因为数据库重启过。解决:采集脚本里要同时记录快照时间、服务器启动时间,如果启动时间变了就要丢弃重启前后那一段数据。另外有的计数器是 64 位整型,在高并发下翻转,差值时会变成负数。我现在的习惯是差值计算前先做溢出判断:如果这次值比上次小,就按补码处理或者直接标记为无效点。

6. 把监测指标从“看看”变成“能报警”:基线阈值与趋势判断

前面讲的都是怎么看单点指标,但在生产环境里,指标真正的价值是形成基线和趋势。比如 Oracle 的每秒事务数,白天高峰 300,凌晨 30,如果你把报警阈值设成 200,那凌晨必然误报。正确做法是先给每个指标算一周的分时段基线,再按基线偏离度报警。我一般用一张表,字段是指标名、实例、小时、平均、标准差,每天跑一次汇总。

INSERT INTO metric_baseline (metric_name, instance_name, hour_num, avg_value, stddev_value) SELECT 'transactions_per_sec', instance_name, TO_CHAR(sample_time, 'HH24'), AVG(value), STDDEV(value) FROM metric_samples WHERE sample_day BETWEEN TRUNC(SYSDATE) - 7 AND TRUNC(SYSDATE) - 1 GROUP BY instance_name, TO_CHAR(sample_time, 'HH24');

这个 SQL 是通用的,换表名和字段就能用到任何数据库。有了基线后,报警规则就是当前值与均值差超过 3 倍标准差时触发,而不是固定阈值。这套方式比“死锁=1 就报警”可靠得多,死锁报警通常会从猎到漏报,因为死锁频率和业务并发强相关。

再一个技巧是把指标分成三层:第一层黑匣子,只看整体状态,比如数据库状态、Listener 状态、连接数、表空间使用率,适合做大屏;第二层是问题定位,比如死锁数、锁等待率、缓冲池命中率、Page Read Rate;第三层是深度调优,比如 Row Source Ratio、Sort Overflow Ratio、Chunk Wait Rate 这些小众指标,只在做性能分析时看。日常监测只盯第一第二层,第三层记在文档里,出了问题再翻。

我从做监控第一年就吃过这个亏:把文档里所有指标都接进告警系统,结果每天几百条通知,没过两周就没人看了。后来我强制自己给每个指标写“这个数字异常意味着什么,我该干什么”,写不出来的就不接。这份指标清单的价值就在这里——它不是让你全接,而是让你知道每种数据库有哪些牌可以打。我后来养成的习惯是每接手一个新数据库,先对照这份文档的目录,划掉用不上的专项指标,再给剩下的每个指标配基线和阈值,整个监控体系才真正转起来。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询