Oracle锁表监控应查v$lock、v$session、v$locked_object和v$transaction四个视图,其中v$locked_object和v$transaction用于精准定位阻塞型锁表,需重点检查blocking_session是否非空、row_wait_obj#是否有效及lock_type是否为TX或TM。
Oracle锁表监控该查哪些视图?
直接查 v$lock 和 v$session 是基础,但仅靠它们容易漏判或误报。真正要定位“阻塞型锁表”,必须关联 v$locked_object 和 v$transaction,尤其关注 blocking_session 字段是否非空、row_wait_obj# 是否有效、以及 lock_type 是否为 tx(事务锁)或 (dml表锁)。生产环境里,只查 <code>v$lock 会把大量共享锁(如 null 模式)当成严重问题。
- 优先用如下关联查询:
SELECT s.sid, s.serial#, s.username, s.osuser, s.machine, s.program, l.type, l.lmode, l.request, s.blocking_session FROM v$session s, v$lock l WHERE s.sid = l.sid AND l.blocking_others = 'VALID' - 避免查
dba_locks—— 它是基于v$lock的封装,延迟高且不含阻塞链信息 - 注意
v$视图需SELECT_CATALOG_ROLE权限,不能只给SELECT ANY DICTIONARY
Java定时轮询怎么避免被Oracle反制?
Oracle对高频查询 v$ 视图有隐式限制:连续多次无 sleep 的轮询可能触发内部节流,表现为 ORA-00600 内部错误或查询返回空结果。这不是权限问题,而是 Oracle 内核对诊断视图访问的保护机制。
- 最小间隔设为 10 秒,低于 5 秒风险陡增;若需更高频感知,改用 Oracle 的
DBMS_ALERT或UTL_HTTP主动回调(但需 DBA 配合) - 每次查询后显式调用
Connection.close(),不要依赖连接池自动回收 ——v$查询占用 PGA 资源,连接复用会累积内存压力 - 加
/*+ RULE */提示无效,v$视图不走 CBO,但可加/*+ NO_INDEX(v$lock) */防止某些版本因索引统计异常导致执行计划卡死
告警阈值怎么设才不误报?
锁等待时间不是唯一指标。一个运行 300 秒的锁可能是批处理正常操作,而一个等待 5 秒却阻塞了 20 个业务会话的锁才是真问题。重点看阻塞链深度和被阻塞会话数。
- 触发告警条件建议组合:
blocking_session IS NOT NULL且(blocking_session_status = 'ACTIVE' OR blocking_session_serial# IS NOT NULL)且blocking_session_count >= 3 - 避免用
last_call_et > 300判定 —— 这字段在锁等待中不更新,反映的是会话空闲时长,非锁持有时长 - 对
lmode = 6(排他锁)且对象类型为TABLE的锁,即使只有 1 个被阻塞也应立即告警
Java代码里如何安全提取阻塞关系?
从查询结果构建阻塞树时,别直接递归解析 blocking_session 字段。Oracle 12c+ 的 v$session 中该字段是 SID,但 11g 可能为 0 或无效值,且跨实例 RAC 环境下它不包含实例 ID。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 正确做法:用
SELECT sid, serial#, blocking_session, blocking_session_serial#, blocking_session_status FROM v$session WHERE status = 'ACTIVE'先筛活跃会话,再用sid和serial#做唯一键匹配阻塞关系 - 用
PreparedStatement绑定参数,禁止字符串拼接 SID ——v$视图字段不支持绑定变量,但外围过滤条件必须用预编译防止注入 - 记录原始 SQL 执行耗时,若单次查询超 800ms,说明实例负载已高,此时告警本身可能加剧问题,应降级为日志记录而非推送
实际部署时,最常被忽略的是 Oracle 数据库端的 _kgl_hot_block_debug 隐含参数影响 —— 某些补丁版本下,该参数开启会导致 v$session 中 blocking_session 返回 -1,Java 层若没做负值校验就会抛 NumberFormatException。
立即学习“Java免费学习笔记(深入)”;

















