
好的,我们来深入解析 Oracle 19c 数据库中一个非常实用但常被忽略的性能视图:V$SESSMETRIC。
V$SESSMETRIC 提供了近期(默认约60秒)会话级别的关键性能指标快照。它不像 V$SESSTAT 那样提供自会话启动以来的累计值,而是展示了一个时间窗口内的速率和变化,这对于实时性能监控和诊断短期性能问题至关重要。
一、字段含义详解
V$SESSMETRIC 包含大量字段,以下表格分类列出了最核心和常用的指标:
| 字段名 | 数据类型 | 描述 | 重要说明与解读 |
|---|---|---|---|
| 会话标识 | |||
| SID | NUMBER | 会话标识符。 | 与 V$SESSION.SID 对应。 |
| SESSION_SERIAL# | NUMBER | 会话序列号。用于唯一标识一个会话,防止 SID 重用产生歧义。 | 与 V$SESSION.SERIAL# 对应。 |
| 性能效率指标 | |||
| CPU_PER_CALL | NUMBER | 每次数据库调用消耗的 CPU 时间(单位:厘秒,即 1/100 秒)。 | 值过高表示 SQL 执行效率低下或 CPU 竞争激烈。 |
| DB_TIME_PER_CALL | NUMBER | 每次数据库调用消耗的总数据库时间(CPU + 等待时间)(单位:厘秒)。 | 综合衡量一次调用的性能。 |
| 响应时间指标 | |||
| AVG_HARD_PARSE_TIME | NUMBER | 平均每次硬解析所花费的时间(单位:厘秒)。 | 用于评估共享池和 SQL 解析性能。 |
| APPLICATION_WAIT_TIME | NUMBER | 在应用程序等待类别(如行锁)中花费的时间。 | |
| CONCURRENCY_WAIT_TIME | NUMBER | 在并发等待类别(如缓冲区忙等待)中花费的时间。 | |
| USER_IO_WAIT_TIME | NUMBER | 在用户 I/O 等待类别中花费的时间。 | |
| PLSQL_EXEC_TIME | NUMBER | 在 PL/SQL 执行中花费的 CPU 时间。 | 评估 PL/SQL 代码的CPU消耗。 |
| JAVA_EXEC_TIME | NUMBER | 在 Java 执行中花费的 CPU 时间。 | |
| 吞吐量与操作速率 | |||
| LOGONS_PER_SEC | NUMBER | 每秒的登录次数。 | 突发增高可能表示应用层连接池重启或攻击。 |
| EXECUTES_PER_SEC | NUMBER | 每秒执行的 SQL 语句次数(包括递归SQL)。 | 衡量数据库负载的重要指标。 |
| USER_TRANSACTIONS_PER_SEC | NUMBER | 每秒的用户事务数。 | 衡量业务压力。 |
| PHYSICAL_READS_PER_SEC | NUMBER | 每秒产生的物理读(磁盘I/O)次数。 | 监控 I/O 压力的核心指标。 |
| PHYSICAL_READS_DIRECT_PER_SEC | NUMBER | 每秒产生的直接路径读次数(常与并行查询、全表扫描相关)。 | |
| PHYSICAL_WRITES_PER_SEC | NUMBER | 每秒产生的物理写次数。 | |
| PHYSICAL_WRITES_DIRECT_PER_SEC | NUMBER | 每秒产生的直接路径写次数(常与直接路径加载、ADG 相关)。 | |
| REDO_PER_SEC | NUMBER | 每秒产生的重做数据量(单位:字节)。 | 监控日志生成速率和磁盘负载。 |
| 逻辑读指标 | |||
| LOGICAL_READS_PER_SEC | NUMBER | 每秒产生的逻辑读(缓存获取)次数。 | 监控内存压力和SQL效率的核心指标。过高表示可能缺少索引或SQL效率低。 |
| CELL_LOGIC | NUMBER | 在 Exadata 存储节点上完成的逻辑读次数。 | Exadata 特有指标。 |
| 等待事件指标 | |||
| ROW_LOCK_WAITS_PER_SEC | NUMBER | 每秒发生的行锁等待次数。 | 监控阻塞和锁争用的关键指标。 |
| BUFFER_BUSY_WAITS_PER_SEC | NUMBER | 每秒发生的缓冲区忙等待次数。 | 监控热点块争用的关键指标。 |
| ENQUEUE_DEADLOCKS_PER_SEC | NUMBER | 每秒发生的死锁次数。 | 非零即表示应用逻辑可能有问题。 |
| GLOBAL_CACHE_CR_BLOCKS_RECEIVED_PER_SEC | NUMBER | (RAC)每秒接收的全局缓存一致性读块数量。 | 监控 RAC 跨实例缓存融合流量的核心指标。 |
| GLOBAL_CACHE_CU_BLOCKS_RECEIVED_PER_SEC | NUMBER | (RAC)每秒接收的全局缓存当前块数量。 |
二、核心原理与底层机制
1. 数据来源与收集机制
V$SESSMETRIC 的数据并非直接来自会话的实时活动,而是由 Oracle 的 MMON (Manageability Monitor) 后台进程周期性采集的快照。
- 采集频率:默认情况下,MMON 每 60 秒(1分钟)会唤醒一次,从 SGA 中的相关内存结构中收集所有活动会话的累积计数器值。
- 计算差值:MMON 并非简单地记录当前值,它会减去上一次快照时的值,从而计算出在过去一个时间间隔内(约60秒)各个指标的变化量(Δ值)。
- 计算速率:然后将这个 Δ 值除以时间间隔,就得到了视图中所展示的 “_PER_SEC”(每秒)的速率指标。
- 存储:这些计算好的指标值被存储在 SGA 的一个固定大小的循环缓冲区 中。
2. 底层基表 (X$ Tables)
V$SESSMETRIC 是基于底层 X$ 表构建的,其源极有可能是 X$KSLSMS 或类似的动态性能基表。这些 X$ 表直接映射了 MMON 进程填充的 SGA 缓冲区。
3. 与 V$SESSTAT 的核心区别
这是理解 V$SESSMETRIC 的关键:
| 特性 | V$SESSMETRIC | V$SESSTAT |
|---|---|---|
| 数据性质 | 速率/差值(Rate/Differential) | 累计值(Cumulative) |
| 时间范围 | 最近约60秒的活跃窗口 | 自会话启动以来的全部历史 |
| 用途 | 实时监控、趋势分析、告警。回答“当前会话表现如何?” | 历史性能分析、容量规划。回答“会话总共做了多少工作?” |
| 开销 | 极低(预计算好的快照) | 较低(直接查询内存计数器) |
举例:V$SESSTAT 中的 session logical reads 统计项会告诉你会话从启动到现在总共发生了 100 万次逻辑读。而 V$SESSMETRIC 的 LOGICAL_READS_PER_SEC 会告诉你,在刚刚过去的这一分钟里,该会话平均每秒产生了 5000 次逻辑读。后者对于判断当前是否正在发生性能问题更有意义。
三、常用查询 SQL 示例
-
查看当前所有会话的实时资源消耗排名(过去~60秒)
SELECT s.sid, s.username, s.program, s.sql_id, sm.logical_reads_per_sec, sm.physical_reads_per_sec, sm.cpu_per_call, sm.user_io_wait_time FROM v$sessmetric sm JOIN v$session s ON sm.sid = s.sid WHERE s.type = 'USER' AND s.status = 'ACTIVE' ORDER BY sm.logical_reads_per_sec DESC NULLS LAST; -
找出当前 I/O 压力最大的会话
SELECT sm.sid, s.username, s.osuser, s.module, sm.physical_reads_per_sec, sm.physical_writes_per_sec, sm.user_io_wait_time, s.sql_id FROM v$sessmetric sm JOIN v$session s ON sm.sid = s.sid ORDER BY (sm.physical_reads_per_sec + sm.physical_writes_per_sec) DESC; -
监控数据库中的锁争用情况
SELECT sm.sid, s.username, s.program, sm.row_lock_waits_per_sec, sm.buffer_busy_waits_per_sec, s.blocking_session, s.sql_id FROM v$sessmetric sm JOIN v$session s ON sm.sid = s.sid WHERE sm.row_lock_waits_per_sec > 0 OR sm.buffer_busy_waits_per_sec > 0 ORDER BY sm.row_lock_waits_per_sec DESC; -
识别高 CPU 或低效 SQL
SELECT sm.sid, s.username, s.sql_id, sm.cpu_per_call, sm.db_time_per_call, sm.logical_reads_per_sec, sq.sql_text FROM v$sessmetric sm JOIN v$session s ON sm.sid = s.sid LEFT JOIN v$sql sq ON s.sql_id = sq.sql_id WHERE sm.cpu_per_call > 100 -- 每次调用CPU时间超过1秒 ORDER BY sm.cpu_per_call DESC;
四、主要应用场景
-
实时性能监控:
这是V$SESSMETRIC最主要的用途。DBA 或监控工具可以周期性地(如每60秒)查询此视图,快速识别出在最近一个时间窗口内,哪些会话正在消耗最多的 CPU、产生最多的 I/O、遭遇最多的锁等待,从而实时捕捉性能异常。 -
建立性能基线:
持续收集V$SESSMETRIC的数据,可以建立系统在正常负载下的性能基线(如平均逻辑读/秒、CPU/调用等)。当系统出现性能问题时,可以与基线进行对比,快速发现异常指标。 -
关联分析:
将高资源消耗的指标(如高LOGICAL_READS_PER_SEC)与V$SESSION中的SQL_ID、MODULE、PROGRAM等信息关联,可以迅速将资源消耗归因到具体的 SQL 语句或应用程序模块。 -
容量规划和负载评估:
通过观察不同时间点的V$SESSMETRIC聚合数据,可以了解系统的负载高峰和低谷,为容量规划提供数据支持。
五、相关视图
V$SESSION:提供会话的上下文信息(用户、程序、状态、当前SQL等),是与V$SESSMETRIC关联查询的最重要视图。V$SESSTAT:提供会话级别的累计统计信息,用于长期历史分析。V$SYSMETRIC/V$SYSMETRIC_HISTORY:提供系统级别的指标快照和历史,与V$SESSMETRIC类似,但粒度是整个实例。V$SQL:用于通过SQL_ID获取正在消耗资源的具体 SQL 文本和执行计划信息。DBA_HIST_ACTIVE_SESS_HISTORY:如果当前数据已被老化,可以查询 AWR 中的历史活动会话数据,但其粒度是每秒采样,而非60秒汇总。
总结:V$SESSMETRIC 是 Oracle 数据库实时性能监控(Near-Real-Time Monitoring)的基石。它通过提供会话级、速率化的关键指标,将DBA从繁琐的累计值计算中解放出来,使得快速定位和诊断正在发生的性能瓶颈变得异常高效。理解并熟练运用此视图,是成为一名高级 Oracle DBA 的关键一步。
欢迎关注我的公众号《IT小Chen》

被折叠的 条评论
为什么被折叠?



