V$SESSION 找不到SQL_ID
--本方法基于ORACLE11G
实验:
SQL> create table test_1205 as select * from dba_objects;
Table created
SQL> select sid from v$mystat where rownum=1;
SID
----------
1155
SQL> update test_1205 set owner='WMZ' where object_id<100;
98 rows updated
在1155这个SESSION里面执行一个UPDATE,不要提交。
SQL> select sid from v$mystat where rownum=1;
SID
----------
1529
SQL> update test_1205 set owner='WMZ' where object_id<10;
--在1529里面跑另外一个UPDATE,因为1155没提交,1529处于行锁等待。
这个时候通过如下脚本去查询数据库:
select inst_id,
sid,
sql_id,
event,
blocking_session,
blocking_instance
from gv$session a
where blocking_session is not null;
--查询SQL_ID 对应的内容
select sql_text from v$sql where sql_id='72cbkgkmx1477';
--查询1155对应的SQL_ID
--确实,SQL_ID是空的,那我去查询PREV_SQL_ID,这个SQL_ID是事物的SQL_ID,并不是UPDATE的SQL_ID
select prev_sql_id from gv$session where inst_id=1 and sid=1155;
select sql_text from gv$sql where sql_id='9m7787camwh4m';
--另外一种方法
select PREV_EXEC_START,USERNAME,MODULE,ACTION FROM GV$SESSION WHERE INST_ID=1 AND SID=1155;
SELECT SQL_ID,SQL_TEXT,LAST_ACTIVE_TIME,MODULE,ACTION FROM GV$SQL WHERE INST_ID=1 AND LAST_ACTIVE_TIME=TO_DATE('2018-12-05 17:38:15','YYYY-MM-DD HH24:MI:SS');
---至此找到没有提交的SQL_ID 以及SQL 内容!
请注意:
1.在高并发的情况下,可能会出现多个可疑SQL
2.UPDATE执行过后,又继续执行新的SQL,就悲催了,这个时候要自己把所有SQL抓出来,按照时间线排序,CHECK
----check
select a.inst_id, a.sid, a.sql_id, b.sql_id, b.sql_text
from gv$session a, gv$sql b
where a.inst_id = b.inst_id
and a.PREV_EXEC_START = b.LAST_ACTIVE_TIME
and a.USERNAME = b.PARSING_SCHEMA_NAME
and a.MODULE = b.MODULE
--and a.ACTION_HASH = b.ACTION_HASH
select a.inst_id,
a.sid,
a.event,
a.sql_id,
b.sql_text running_sql,
c.sql_in_session,
c.sql_id_in_v$sql,
c.sql_text blocking_sql,
a.blocking_session,
a.blocking_instance
from gv$session a,
(select sql_id, sql_text
from (select sql_id,
sql_text,
row_number() over(partition by sql_id order by sql_id) as rn
from gv$sql)
where rn = 1) b,
(select a.inst_id,
a.sid,
a.sql_id sql_in_session,
b.sql_id sql_id_in_v$sql,
b.sql_text
from gv$session a, gv$sql b
where a.inst_id = b.inst_id
and a.PREV_EXEC_START =b.LAST_ACTIVE_TIME
and a.USERNAME = b.PARSING_SCHEMA_NAME
and a.MODULE = b.MODULE
) c
where a.sql_id = b.sql_id
and a.blocking_session is not null
and a.BLOCKING_SESSION = c.sid
and a.BLOCKING_INSTANCE = c.inst_id;