查看和終止 Oracle 連接會話以及正在執(zhí)行的 SQL 語句
作者: 不剪發(fā)的Tony老師
畢業(yè)于北京航空航天大學(xué),十多年數(shù)據(jù)庫管理與開發(fā)經(jīng)驗,目前在一家全球性的金融公司從事數(shù)據(jù)庫架構(gòu)設(shè)計。CSDN學(xué)院簽約講師以及GitChat專欄作者。csdn上的博客收藏于以下地址:https://tonydong.blog.csdn.net
文章目錄
查看當(dāng)前連接的會話
終止正在執(zhí)行的 SQL 語句
終止指定的連接會話
通過 SQL 命令終止連接會話
通過操作系統(tǒng)命令終止連接會話
總結(jié)
大家好,我是只談技術(shù)不剪發(fā)的 Tony 老師。作為 DBA,有時候為了執(zhí)行管理操作需要終止當(dāng)前的用戶會話;當(dāng)某個 SQL
語句長時間運行并占用大量系統(tǒng)資源時,我們也可能需要手動終止正在執(zhí)行的語句。因此,今天我們來討論一下如何查看和終止 Oracle
的連接會話,以及正在執(zhí)行的 SQL 語句。
查看當(dāng)前連接的會話
Oracle 系統(tǒng)視圖 V$SESSION 和對應(yīng)的 GV$SESSION(全局視圖主要用于 RAC 環(huán)境)提供了當(dāng)前所有會話的相關(guān)信息。例如:
select inst_id, sid, serial#, username,
status, server, program, sql_id
from gv$session
where type != 'BACKGROUND'
and username is not null
and nvl(osuser,'x') <> 'SYSTEM';
INST_ID|SID|SERIAL#|USERNAME|STATUS |SERVER |PROGRAM |SQL_ID |
-------|---|-------|--------|--------|---------|----------------------------------------|-------------|
1|143| 9323|TONY |ACTIVE |DEDICATED|DBeaver 7.1.3 - SQLEditor <Script-2.sql>|9b1bawv3upw70|
1|265| 24368|TONY |INACTIVE|DEDICATED|DBeaver 7.1.3 - Main |3fnstj6ydy4xk|
1|399| 16226|TONY |INACTIVE|DEDICATED|sqlplus@sqlhost (TNS V1-V3) | |
以上查詢只返回了用戶的連接會話,不包括后臺進程的連接會話。其中,
inst_id 是會話所在的實例 id;
sid 是會話標識符,serial# 是會話序列號,兩者唯一確定實例中的會話;
username 是連接數(shù)據(jù)庫的用戶;
status 是會話的狀態(tài),例如 ACTIVE、INACTIVE、KILLED 等;
server 是服務(wù)器的類型,例如 DEDICATED、SHARED 等;
program 是會話客戶端的應(yīng)用程序名;
sql_id 是正在執(zhí)行的 SQL 語句 id。
??關(guān)于 V$SESSION 視圖的更多字段可以參考官方文檔。
終止正在執(zhí)行的 SQL 語句
從 Oracle 18c 開始增加了ALTER SYSTEM CANCEL SQL命令,可以用于終止指定會話中正在執(zhí)行的 SQL 語句,但不會終止連接會話。該語句的語法如下:
ALTER SYSTEM CANCEL SQL 'sid, serial# [, @inst_id][, sql_id]';
其中,
sid 是會話標識符;
serial# 是會話序列號;
inst_id 是實例 id,如果省略表示當(dāng)前實例;
sql_id 是 SQL 標識符,如果省略表示終止該會話中正在運行的語句。
以上輸入信息都可以通過查詢上文中的 V$SESSION 或者 GV$SESSION 視圖獲得。使用該語句可以終止高負載的 SQL 語句;如果終止的是 DML 語句,該語句將會被回滾。
我們首先在一個會話(sid = 399、serial# = 16226)中執(zhí)行以下語句:
SQL> EXEC DBMS_LOCK.sleep(300);
該會話將會睡眠 300 秒,然后在另一個會話中終止該語句(可以再次查詢 GV$SESSION 視圖獲得相關(guān)信息):
-- 另一個會話
ALTER SYSTEM CANCEL SQL '399, 16226';
此時,上面的第一個會話返回以下錯誤:
SQL> EXEC DBMS_LOCK.sleep(300);
BEGIN DBMS_LOCK.sleep(300); END;
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation
ORA-06512: at "SYS.DBMS_LOCK", line 205
ORA-06512: at line 1
??如果想要查看會話中正在執(zhí)行的 SQL 語句內(nèi)容,可以通過 sql_id 字段關(guān)聯(lián)查詢系統(tǒng)視圖 V$SQL 或者 GV$SQL。
終止指定的連接會話
通過 SQL 命令終止連接會話
??如果終止了錯誤的會話,可能會造成嚴重的影響,因此在確定要終止的會話時要格外小心。如果終止了后臺進程對應(yīng)的會話,將會導(dǎo)致實例崩潰。
當(dāng)會話終止被時,該會話的所有活動事務(wù)都會被回滾,并且該會話持有的資源(例如鎖和內(nèi)存)將立即釋放。終止用戶會話的基于命令如下:
ALTER SYSTEM KILL SESSION 'sid, serial# [, @inst_id]';
其中,
sid 是會話標識符;
serial# 是會話序列號;
inst_id 是實例 id,如果省略表示當(dāng)前實例。
以上輸入信息都可以通過查詢上文中的 V$SESSION 或者 GV$SESSION 視圖獲得。
我們使用以下語句終止指定會話(sid = 399、serial# = 16226):
alter system kill session '399, 16226';
此時再次查詢 gv$session 可以看到該會話的狀態(tài)為 KILLED:
select inst_id, sid, serial#, username,
status, server, program, sql_id
from gv$session s
where type != 'BACKGROUND'
and username is not null
and nvl(osuser,'x') <> 'SYSTEM';
INST_ID|SID|SERIAL#|USERNAME|STATUS |SERVER |PROGRAM |SQL_ID |
-------|---|-------|--------|--------|---------|----------------------------------------|-------------|
1|143| 9323|TONY |ACTIVE |DEDICATED|DBeaver 7.1.3 - SQLEditor <Script-2.sql>|b3upx6u952qfb|
1|265| 24368|TONY |INACTIVE|DEDICATED|DBeaver 7.1.3 - Main |3fnstj6ydy4xk|
1|399| 16226|TONY |KILLED |DEDICATED|sqlplus@sqlhost (TNS V1-V3) | |
如果我們在被終止的會話中執(zhí)行操作,將會返回以下錯誤:
SQL> select 1 from dual;
select 1 from dual
*
ERROR at line 1:
ORA-00028: your session has been killed
SQL> select 1 from dual;
select 1 from dual
*
ERROR at line 1:
ORA-01012: not logged on
Process ID: 27994
Session ID: 399 Serial number: 16226
ALTER SYSTEM KILL SESSION 語句實際上并不會立即終止會話,它只是請求會話自己終止。在某些情況下,例如等待遠程數(shù)據(jù)庫的響應(yīng)或者事務(wù)的回滾時,會話不會立即終止,而是等待當(dāng)前操作完成。此時會話的狀態(tài)為 KILLED,表示“標記為終止”。
ALTER SYSTEM KILL SESSION 命令支持使用 IMMEDIATE 選項:
ALTER SYSTEM KILL SESSION 'sid, serial# [, @inst_id]' IMMEDIATE;
IMMEDIATE 選項不會改變該命令執(zhí)行的操作,但是會立即返回,而不會等待會話被終止。
除了以上命令之外,ALTER SYSTEM DISCONNECT SESSION 語句也可以用于終止會話:
DISCONNECT SESSION 'sid, serial#' POST_TRANSACTION;
DISCONNECT SESSION 'sid, serial#' IMMEDIATE;
該命令與 ALTER SYSTEM KILL SESSION 語句不同之處在于它會終止專用服務(wù)器進程(或者共享服務(wù)器進程中的虛擬鏈路,相當(dāng)于通過操作系命令終止服務(wù)器進程。其中 POST_TRANSACTION 選項表示等待正在執(zhí)行中的事務(wù)結(jié)束后終止連接,IMMEDIATE 選項表示立即斷開連接并且回滾事務(wù)。
對于上面終止會話的示例(如果沒有執(zhí)行的話),也可以使用以下語句實現(xiàn)相同的目的:
alter system disconnect session '399, 16226' post_transaction;
這種方式可以避免通過操作系統(tǒng)命令終止會話,減少了錯誤操作的風(fēng)險。
通過操作系統(tǒng)命令終止連接會話
如果想要通過操作系統(tǒng)命令終止會話,首先需要找出會話對應(yīng)的操作系統(tǒng)進程 id,可以通過 V$PROCESS 或者 GV$PROCESS 進行查看:
select s.inst_id,
s.sid,
s.serial#,
s.sql_id,
p.spid,
s.username,
s.status,
s.server,
s.program
from gv$session s
join gv$process p on p.addr = s.paddr and p.inst_id = s.inst_id
where s.type != 'BACKGROUND'
and s.username is not null
and nvl(s.osuser,'x') <> 'SYSTEM';
INST_ID|SID|SERIAL#|SQL_ID |SPID |USERNAME|STATUS |SERVER |PROGRAM |
-------|---|-------|-------------|-----|--------|--------|---------|----------------------------------------|
1|399| 22691| |12195|TONY |INACTIVE|DEDICATED|sqlplus@sqlhost (TNS V1-V3) |
1|265| 24368|3fnstj6ydy4xk|9152 |TONY |INACTIVE|DEDICATED|DBeaver 7.1.3 - Main |
1|143| 9323|7yyukqn3pkt89|9193 |TONY |ACTIVE |DEDICATED|DBeaver 7.1.3 - SQLEditor <Script-2.sql>|
其中,spid 就是會話對應(yīng)的操作系統(tǒng)進程 id。
有了進程 id ,就可以通過操作系統(tǒng)命令終止相應(yīng)的進程。對于 Unix/Linux 操作系統(tǒng),可以使用 kill 命令終止進程:
kill spid
kill -9 spid
其中,-9 表示強制終止。在終止進程之前也可以使用 ps 命令進行二次確認:
ps -ef | grep ora
我們使用以下命令終止會話(sid = 399、serial# = 22691)對應(yīng)的操作系統(tǒng)進程(12195):
[root@sqlhost ~]# kill 12195
此時,如果在該會話中執(zhí)行任何語句都會返回錯誤:
SQL> select 1 from dual;
select 1 from dual
*
ERROR at line 1:
ORA-03135: connection lost contact
Process ID: 12195
Session ID: 399 Serial number: 22691
??Oracle 12c 開始支持 Unix/Linux 環(huán)境下的多線程模型;如果使用了這種模型,不要使用操作系統(tǒng)命令終止會話,否則會一次終止多個會話。
對于 Windows 操作系統(tǒng),可以使用 orakill 命令行工具終止進程:
orakill sid spid
其中,sid 是會話標識符,spid 是會話對應(yīng)的進程 id。
總結(jié)
Oracle 提供了幾種終止連接會話/進程和運行中的 SQL 語句的方法。首先可以通過 GV$SESSION 和 GV$PROCESS 等視圖查看會話和對應(yīng)的系統(tǒng)進程信息,然后使用 ALTER SYSTEM KILL SESSION 或者 ALTER SYSTEM DISCONNECT SESSION 命令終止連接會話,或者利用操作系統(tǒng)命令(kill、orakill)終止相應(yīng)的進程;另外,也可以使用 ALTER SYSTEM CANCEL SQL 命令終止正在運行的 SQL 語句。
如果覺得文章對你有用,歡迎關(guān)注??、評論??、點贊??!