阻塞与锁
1. 查询阻塞
SELECT '节点 ' || a_s.INST_ID || ' session ' || a_s.sid || ',' || a_s.SERIAL# ||
' 阻塞了 节点 ' || b_s.INST_ID || ' session ' || b_s.SID || ',' ||
b_s.SERIAL# blockinfo,
a_s.INST_ID,
a_s.SID,
a_s.SCHEMANAME,
a_s.MODULE,
a_s.MACHINE,
a_s.PROGRAM,
a_s.STATUS,
'后为被阻塞信息',
b_s.INST_ID blocked_inst_id,
b_s.SID blocked_sid,
b_s.SCHEMANAME blocked_SCHEMANAME,
b_s.EVENT blocked_event,
b_s.MODULE blocked_module,
b_s.STATUS blocked_status,
b_s.SQL_ID blocked_sql_id,
obj.owner blocked_owner,
obj.object_name blocked_object_name,
obj.OBJECT_TYPE blocked_OBJECT_TYPE,
case
when b_s.ROW_WAIT_OBJ# <> -1 then
dbms_rowid.rowid_create(1,
obj.DATA_OBJECT_ID,
b_s.ROW_WAIT_FILE#,
b_s.ROW_WAIT_BLOCK#,
b_s.ROW_WAIT_ROW#)
else
'-1'
end blocked_rowid, --被阻塞数据的rowid
decode(obj.object_type,
'TABLE',
'select * from ' || obj.owner || '.' || obj.object_name ||
' where rowid=''' ||
dbms_rowid.rowid_create(1,
obj.DATA_OBJECT_ID,
b_s.ROW_WAIT_FILE#,
b_s.ROW_WAIT_BLOCK#,
b_s.ROW_WAIT_ROW#) || '''',
NULL) blocked_data_querysql
from gv$session a_s, gv$session b_s, dba_objects obj
where b_s.BLOCKING_INSTANCE is not null
and b_s.BLOCKING_SESSION is not null
and a_s.INST_ID = b_s.BLOCKING_INSTANCE
and a_s.SID = b_s.BLOCKING_SESSION
and b_s.ROW_WAIT_OBJ# = obj.object_id(+)
order by a_s.inst_id, a_s.sid;
2. 查询阻塞后sql语句
SELECT *
FROM v$sql
WHERE sql_id = '39c75p5w6h3tg';
找到了这个会话:
3. 查询未提交的事务
SELECT s.sid,
s.serial#,
s.username,
s.osuser,
s.program,
s.event,
to_char(s.logon_time, 'yyyy-MM-dd hh24:mi:ss'),
to_char(t.start_date, 'yyyy-MM-dd hh24:mi:ss'),
s.last_call_et,
s.blocking_session,
s.status,
(SELECT q.sql_text
FROM v$sql q
WHERE q.last_active_time = t.start_date
AND ROWNUM <= 1) AS sql_text
FROM v$session s,
v$transaction t
WHERE s.saddr = t.ses_addr;
未提交事务的进程SID号正好是 126
。
4. 查询锁
SELECT A.OWNER 方案名,
A.OBJECT_NAME 表名,
B.XIDUSN 回滚段号,
B.XIDSLOT 槽号,
B.XIDSQN 序列号,
B.SESSION_ID 锁表SESSION_ID,
B.ORACLE_USERNAME 锁表用户名,
D.TYPE,
decode(D.type,
'XR',
'NULL',
'RS',
'SS(Row-S)',
'CF',
'SS(Row-S)',
'TM',
'TABLE LOCK',
'PW',
'TABLE LOCK',
'TO',
'TABLE LOCK',
'TS',
'TABLE LOCK',
'RT',
'ROW LOCK',
'TX',
'ROW LOCK',
'MR',
'S(Share)',
NULL) 锁定方式,
C.MACHINE 用户组,
C.TERMINAL 机器名,
B.OS_USER_NAME 系统用户名,
B.PROCESS 系统进程id,
DECODE(C.STATUS, 'INACTIVE', '不活动', 'ACTIVE', '活动') 活动情况,
C.SERVER,
C.SID,
C.SERIAL#,
C.PROGRAM 连接方式,
C.LOGON_TIME
FROM ALL_OBJECTS A, V$LOCKED_OBJECT B, SYS.GV_$SESSION C, v$lock d
WHERE (A.OBJECT_ID = B.OBJECT_ID)
AND (B.PROCESS = C.PROCESS)
and C.sid = d.sid
and B.LOCKED_MODE = D.LMODE
ORDER BY 1, 2;
5. 数据库追踪日志
在数据库全局做追踪
-- 开启数据库级追踪:
alter system set events '10046 trace name context forever, level 12';
-- 查询日志位置
SELECT s.sid,s.serial#, p.tracefile, s.sql_id
FROM v$session s
LEFT JOIN v$process p ON s.paddr = p.addr
WHERE s.username = 'EASYTONG';
-- 关闭数据库级跟踪:
alter system set events '10046 trace name context off';
被阻塞的会话日志。阻塞的会话是inactive,没有产生日志
总结
A会话对am_account表产生了一个锁,交易的时候,B会话先锁了最大值表,然后等待A会话锁的释放。