
好的,我们来对 Oracle 19C 数据库中的 V$BUFFERED_PUBLISHERS 动态性能视图进行一次全面、深入的解析。
这个视图是 Oracle Advanced Queuing (AQ) 功能,特别是缓冲消息 (Buffered Messaging) 部分的核心监控接口之一。理解它对于管理和诊断基于AQ的异步应用至关重要。
1. 作用与简介
核心作用:
V$BUFFERED_PUBLISHERS 动态性能视图用于实时监控所有正在向缓冲队列(Buffered Queue)发布消息的生产者(Publishers)的状态和性能指标。
背景知识:
Oracle AQ 提供了两种消息传递模式:
- 持久消息 (Persistent Messaging):消息持久化到磁盘表(AQ表),保证消息的可靠性和可恢复性。这是最常用的模式。
- 缓冲消息 (Buffered Messaging):消息主要存储在内存的缓冲区域中,旨在提供极高性能和低延迟的消息传递。牺牲了部分的持久性保证(在实例崩溃时,内存中的消息会丢失),适用于对性能要求极高且可以容忍少量消息丢失的场景(如实时事件处理、审计日志流等)。
V$BUFFERED_PUBLISHERS 正是为监控第二种模式中的消息生产者而设计的。
2. 使用场景
-
性能诊断与调优:
- 识别发布消息慢的生产者。通过观察
TOTAL_MSGS和TOTAL_TIME,可以计算平均发布延迟。 - 监控消息发布速率 (
TOTAL_MSGS,CURRENT_MSGS的变化),判断生产者是否成为系统瓶颈。 - 通过
SPILL_MSGS了解内存压力。如果溢出消息很多,说明SGA中的缓冲队列内存不足,需要调整_AQ_BUFFERED_QUEUE_SIZE参数或优化生产者提交频率。
- 识别发布消息慢的生产者。通过观察
-
容量规划与监控:
- 监控
CURRENT_MSGS可以了解当前有多少消息正在从该生产者流向消费者,帮助评估系统负载。 - 结合
V$BUFFERED_QUEUES和V$BUFFERED_SUBSCRIBERS,可以全面了解整个缓冲消息链路的健康状况。
- 监控
-
问题排查:
- 当一个缓冲消息流出现问题时,可以通过此视图快速定位到是哪个生产者(
PUBLISHER_NAME)或哪个队列(QUEUE_ID)出现了异常,例如消息堆积、发布停滞等。
- 当一个缓冲消息流出现问题时,可以通过此视图快速定位到是哪个生产者(
-
实时监控:
- 可以编写周期性查询脚本,实时捕捉生产者的活动情况,用于仪表盘或告警系统。
3. 字段含义详解
以下是 V$BUFFERED_PUBLISHERS 视图中的主要字段及其含义:
| 字段名 | 数据类型 | 含义 |
| :— | :— | :— |
| QUEUE_ID | NUMBER | 队列的唯一标识符。可以与 DBA_QUEUES 或 V$BUFFERED_QUEUES 中的 QID 字段关联。 |
| PUBLISHER_ID | NUMBER | 生产者的唯一标识符。在视图实例范围内唯一。 |
| PUBLISHER_NAME | VARCHAR2(128) | 生产者的名称。这是在使用 DBMS_AQADM.ADD_PUBLISHER 过程时指定的名字。 |
| TRANSACTION_ID | RAW(8) | 生产者当前所在事务的事务ID。如果生产者未在事务中,则为 NULL。 |
| PID | NUMBER | 操作系统进程标识符 (OS PID)。标识了是哪个服务器进程正在代表此生产者发布消息。 |
| SID | NUMBER | Session ID。标识了是哪个数据库会话正在扮演生产者的角色。可与 V$SESSION 关联。 |
| SERIAL# | NUMBER | Session Serial Number。与 SID 一起用于唯一标识一个会话(因为 SID 可能会重用)。 |
| TOTAL_MSGS | NUMBER | 此生产者已成功发布的消息总数。这是一个累积值。 |
| CURRENT_MSGS | NUMBER | 当前正在事务中但尚未提交的消息数。提交后,这些消息会计入 TOTAL_MSGS 并交付给消费者。 |
| SPILL_MSGS | NUMBER | 由于内存不足而从内存缓冲区溢出到磁盘临时表空间的消息数量。这个值高是性能问题的明显信号。 |
| TOTAL_TIME | NUMBER | 此生产者发布所有消息所花费的总时间(微秒)。用于计算平均发布延迟。 |
| MEM_USAGE | NUMBER | 此生产者当前使用的共享内存量(字节)。 |
| STATE | VARCHAR2(9) | 生产者的当前状态。可能的值: |
| | | • INACTIVE:生产者存在但当前未发布消息。 |
| | | • PUBLISHING:生产者正在 actively 发布消息。 |
| | | • SCHEDULING:生产者正在安排消息发布(内部状态)。 |
4. 相关视图与基表
-
相关动态性能视图:
V$BUFFERED_QUEUES: 显示所有缓冲队列的整体信息,如队列ID、名称、当前消息数、溢出消息数、内存使用情况等。QUEUE_ID是关联键。V$BUFFERED_SUBSCRIBERS: 显示所有缓冲消息消费者的信息,如消费者名称、已处理消息数、等待时间等。V$SESSION: 通过SID和SERIAL#关联,可以获取生产者会话的详细信息(如用户名、机器名、程序名、SQL语句等)。V$TRANSACTION: 通过TRANSACTION_ID关联,可以获取生产者事务的详细信息。
-
基表 (Underlying Table):
- 像绝大多数
V$视图一样,V$BUFFERED_PUBLISHERS没有直接对应的基表。 - 它是一个动态性能视图,其数据来源于实例运行时在SGA中维护的内存结构。当实例关闭时,这些数据会丢失。它的数据是通过底层 X$ 表(如
X$KJBDP)拼接和转换而来的,这些 X$ 表是Oracle内部的、未公开的、结构不稳定的内存结构接口,严禁直接查询。
- 像绝大多数
5. 底层详细原理
-
内存结构:
- 当配置了缓冲队列时,Oracle会在 Shared Pool 的 Streams Pool(如果配置了)或 Buffer Cache 中分配一块内存区域来存储缓冲消息。
- 对于每个活跃的生产者,Oracle会在SGA中维护一个发布者上下文结构 (Publisher Context Structure)。这个结构体记录了字段部分描述的所有信息(如消息计数、状态、时间等)。
-
发布者注册:
- 当一个会话首次开始向缓冲队列发布消息时,它会被注册为一个生产者。一个唯一的
PUBLISHER_ID会被分配,并且在SGA中创建对应的上下文结构。
- 当一个会话首次开始向缓冲队列发布消息时,它会被注册为一个生产者。一个唯一的
-
消息生成与记录:
- 生产者调用
ENQUEUE操作发布消息。 - 消息首先被写入到SGA的缓冲队列内存区域。
- 同时,该生产者的上下文结构中的
CURRENT_MSGS和MEM_USAGE会增加。 - 如果缓冲队列内存已满, oldest messages 会被溢出 (Spill) 到磁盘的临时表空间中(这是一个内部操作)。此时,
SPILL_MSGS计数会增加。
- 生产者调用
-
提交与清理:
- 当生产者提交事务时,该事务中发布的所有消息变得对消费者可见。
CURRENT_MSGS的值会被加到TOTAL_MSGS上,然后CURRENT_MSGS被重置。- 如果生产者会话结束,其对应的条目可能会从
V$BUFFERED_PUBLISHERS中消失。
-
视图数据来源:
V$BUFFERED_PUBLISHERS视图的本质是一个实时窗口,它直接查询并格式化展示上述SGA中的生产者上下文结构数组。这就是为什么它能提供近乎实时的监控数据。
6. 常用查询SQL示例
1. 查看所有活跃的生产者及其关键指标
SELECT p.publisher_name,
q.name AS queue_name,
p.sid,
p.serial#,
p.state,
p.total_msgs,
p.current_msgs,
p.spill_msgs,
ROUND(p.total_time / DECODE(p.total_msgs, 0, 1, p.total_msgs) / 1000, 2) AS avg_publish_time_ms,
p.mem_usage
FROM v$buffered_publishers p
JOIN v$buffered_queues q ON p.queue_id = q.qid
ORDER BY p.total_msgs DESC;
2. 查找产生大量溢出(Spill)的生产者(潜在性能问题)
SELECT p.publisher_name,
q.name AS queue_name,
p.spill_msgs,
p.total_msgs,
ROUND((p.spill_msgs / DECODE(p.total_msgs, 0, 1, p.total_msgs)) * 100, 2) AS spill_percentage
FROM v$buffered_publishers p
JOIN v$buffered_queues q ON p.queue_id = q.qid
WHERE p.spill_msgs > 0
ORDER BY spill_percentage DESC;
3. 关联V$SESSION,获取生产者的会话详情(如用户、程序)
SELECT p.publisher_name,
s.username,
s.osuser,
s.machine,
s.program,
s.module,
p.state,
p.total_msgs
FROM v$buffered_publishers p
JOIN v$session s ON p.sid = s.sid AND p.serial# = s.serial#;
4. 实时监控发布速率(需要周期性运行,例如间隔5秒)
-- 第一次运行
SELECT publisher_name, total_msgs INTO :v_old_name, :v_old_msgs
FROM v$buffered_publishers WHERE publisher_id = <your_publisher_id>;
-- 等待5秒...
-- 第二次运行
SELECT p.publisher_name,
(p.total_msgs - :v_old_msgs) / 5 AS msgs_per_sec
FROM v$buffered_publishers p
WHERE p.publisher_id = <your_publisher_id>;
总结
V$BUFFERED_PUBLISHERS 是 Oracle Advanced Queuing 缓冲消息模式下的一个关键性能监控工具。它提供了生产者粒度的实时指标,帮助你:
- 洞察性能:识别慢速生产者,计算延迟。
- 发现瓶颈:监控内存溢出(Spill),指示内存配置是否合理。
- 关联诊断:通过与会话(
V$SESSION)和事务(V$TRANSACTION)视图关联,快速定位问题根源。
准确使用这个视图,对于构建和维护高性能、高可靠的基于Oracle AQ的异步应用系统具有重要意义。
欢迎关注我的公众号《IT小Chen》
583

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



