首頁 >資料庫 >Oracle >oracle查看鎖及session執行中的sql(總結分享)

oracle查看鎖及session執行中的sql(總結分享)

WBOY
WBOY轉載
2022-07-01 12:23:153683瀏覽

這篇文章為大家帶來了關於Oracle的相關知識,其中主要介紹了查看鎖及session執行中的sql的相關問題,下面一起來看一下,希望對大家有幫助。

oracle查看鎖及session執行中的sql(總結分享)

推薦教學:《Oracle影片教學

本文測試資料的資料庫環境:Oracle 11g

           為什麼說是session執行中的sql呢,某個session的sql執行記錄好像取得不到,也看了很多的博文,網上很多有說透過視圖v$active_session_history和v$sqlarea關聯sql_id就能查詢到某個session的sql執行記錄,經過實踐發現是不行的(透過表dba_hist_active_sess_history試過了也是不行),某些sql的sql_id在v$active_session_history根本就沒有記錄,我嘗試修改參數:control_management_pack_access,發現我沒有權限,而且我對了一下,參數值是正常的,該參數數據庫是開啟的,參考博文:Oracle V$ACTIVE_SESSION_HISTORY查詢沒有數據- wazz_s - 博客園

        透過v$sqlarea檢視能查詢到sql的執行記錄,但卻無法查到執行該sql的sessionid,如果有這個sessionid該多好,我就能查到那個人執行了該sql 。

        如果我想要查詢導致鎖定表的那一條sql,網上大部分的博文都是這樣教的,透過查詢視圖v$session得到對應的prev_sql_addr字段值,記為值A,然後透過值A作為視圖v$sqlarea欄位address的查詢條件值,然後就可以查詢到對應的sql記錄了。這個作為練習測試你是可以找到找到鎖表的sql,但是在正常生產環境下大部分情況下你是獲取不到的,為什麼呢,請看下文的介紹。

本文以探索的方式學習,為了確保資料的準確性,我開了三個資料庫會話,分別記為session1、session2、session3,具體步驟如下:

1  在會話session1中新測試表及測試資料

--新建测试表
create table zxy_table(zxy_id int,zxy_name varchar2(20));
--插入数据
insert into zxy_table(zxy_id,zxy_name) values(1,'zxy1');
insert into zxy_table(zxy_id,zxy_name) values(2,'zxy2');
insert into zxy_table(zxy_id,zxy_name) values(3,'zxy3');
insert into zxy_table(zxy_id,zxy_name) values(4,'zxy4');
commit;

2  查看session1的會話Id

 select userenv('sid') from dual;

可以看到會話Id為2546

3  在session1中,透過select  for update的對錶zxy_table的某一行進行鎖定,如下:

 select * from zxy_table where zxy_name='zxy1' for update;

4  在session2中,查詢到該會話id為2189:

然後在session2中對錶zxy_table值為zxy_name='zxy1'的行進行update,如下:

update zxy_table set zxy_name='zxy1_modify' where zxy_name='zxy1';

然後看到該sql已經被堵塞了,如下圖:

#5  然後我們來到會話session3查看鎖定表的情況了

首先查看表v$locked_object 

select * from v$locked_object;

 可以看到造成鎖定表的會話id為2546,就是前面的session1,同時object_id為110154,當然咯,在生成環境中,你看到的肯定不只一筆記錄,你要多執行幾遍,執行n遍後,還能看到的記錄,證明這條記錄就是鎖表的記錄

透過object_id :110154查詢dba4_objects表格查詢詳細鎖定表的資訊

select object_name as 被锁的表名称,obj.* from dba_objects obj where object_id='110154';

 透過sessionid:2546查詢檢視v$session

select 
       s.prev_sql_addr,
       module as 客户端工具名称,
       s.user# as 数据库账号名,
       s.osuser as 连接数据库客户端对应的window账号名称,
       s.machine as 连接数据库客户端对应的计算机名称,
       s.* 
from v$session s where sid='2546';

############################################################################################################################### ######## 得到prev_sql_addr的值為:000000012E045E28,然後透過得到的值查詢檢視v$sqlarea###
select * from v$sqlarea where address='000000012E045E28';
############ 從上圖可以看到造成鎖表的語句了,但是很多博文到了這一步就完事了,這樣查詢真的可靠嗎?答案是不可靠的,你可以回到session1中隨便執行一條sql ,如下:###
 select * from zxy_table;
###然後你再到session3執行###
select 
       s.prev_sql_addr,
       module as 客户端工具名称,
       s.user# as 数据库账号名,
       s.osuser as 连接数据库客户端对应的window账号名称,
       s.machine as 连接数据库客户端对应的计算机名称,
       s.* 
from v$session s where sid='2546';
#########

 再看看prev_sql_addr是不是变了,从000000012E045E28变为了00000001FB03CEC0,再通过00000001FB03CEC0查询视图v$sqlarea

select * from v$sqlarea where address='00000001FB03CEC0';

得到的sql_text是select * from zxy_table,你敢说这条sql导致了锁表吗?所有只能说是session1当前执行的sql,而且你很难保证session1执行完锁表的sql: select * from zxy_table where zxy_name='zxy1' for update且在提交前不再执行别的sql,这就是前文提出的问题的答案。

推荐教程:《Oracle视频教程

以上是oracle查看鎖及session執行中的sql(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除