[20211014]如何取消使用者的查詢在另外的會話.txt

lfree發表於2021-10-14

[20211014]如何取消使用者的查詢在另外的會話.txt

--//昨天看了連結
--//裡面提到幾種方法取消使用者的查詢在另外的會話.

--//當然最簡單的方法,對於當前會話就是按ctrl+c,僅僅對linux有效,windows直接退出,如果是12c以上的版本:
ALTER SYSTEM CANCEL SQL 'SID, SERIAL;
ALTER SYSTEM CANCEL SQL 'SID, SERIAL, SQL_ID';
ALTER SYSTEM CANCEL SQL 'SID, SERIAL, @INST_ID, SQL_ID';

--//作者還提到了設定consumer group對會話取消正在進行的查詢:
DBMS_RESOURCE_MANAGER.SWITCH_CONSUMER_GROUP_FOR_SESS
  sessionid IN NUMBER,
  sessionserial IN NUMBER,
  consumergroup IN VARCHAR2
)

--//要測試它需要建立consumer group,很少這方面的實踐.
--//作者還提到一種方法就是傳送SIGURG給對應程式,不過也是僅僅對linux系統有效,測試看看.

1.環境:
SCOTT@book> @ ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

2.測試:
SCOTT@book> @ spid
       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
        30        965 64784                    DEDICATED 64785       26         86 alter system kill session '30,965' immediate;

SCOTT@book> select count(*) from all_objects,all_objects;

$ kill -l
 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL
 5) SIGTRAP      6) SIGABRT      7) SIGBUS       8) SIGFPE
 9) SIGKILL     10) SIGUSR1     11) SIGSEGV     12) SIGUSR2
13) SIGPIPE     14) SIGALRM     15) SIGTERM     16) SIGSTKFLT
17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25) SIGXFSZ     26) SIGVTALRM   27) SIGPROF     28) SIGWINCH
29) SIGIO       30) SIGPWR      31) SIGSYS      34) SIGRTMIN
35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3  38) SIGRTMIN+4
39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7  58) SIGRTMAX-6
59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

--//UGR=23,URG應該是urgent縮寫.

$ kill -23 64785

SCOTT@book> select count(*) from all_objects,all_objects;
select count(*) from all_objects,all_objects
                     *
ERROR at line 1:
ORA-01013: user requested cancel of current operation

--//僅僅取消,但是程式並沒有退出.
SCOTT@book> @ spid
       SID    SERIAL# PROCESS                  SERVER    SPID       PID  P_SERIAL# C50
---------- ---------- ------------------------ --------- ------ ------- ---------- --------------------------------------------------
        30        965 64784                    DEDICATED 64785       26         86 alter system kill session '30,965' immediate;

3.客戶是windows呢?

--//按照作者的介紹是不行的,windows直接忽略URG訊號.實際上windows下ctrl+c也不行,直接退出.大家可以自行測試.

4.轉抄一些主要內容:

Before we go on, here's how query cancellation (pressing CTRL+C in sqlplus for example) works in Oracle:

在我們繼續之前,下面是查詢取消(例如在Ctll+c中按Cqlplus鍵)在Oracle中的工作原理:

The user presses CTRL+C or clicks some button in App which runs OCICancel()

使用者按CTRL+C或點選執行OCICancel()的應用程式中的一些按鈕

The client process sends an urgent TCP packet (which is a regular TCP packet with URG bit set) to the socket in the
database server it is connected to

客戶端程式將一個緊急TCP包(這是一個設定了URG位的常規TCP包)傳送到它所連線到的資料庫伺服器中的套接字

The server OS TCP stack receives the urgent TCP packet and sends URGENT signal to the process which owns the socket (the
Oracle server process)

伺服器OSTCP堆疊接收緊急TCP資料包,並向擁有套接字的程式(Oracle伺服器程式)傳送緊急訊號

Unix interrupts whatever the current process was doing and calls the URGENT signal handler function (which Oracle has
registered during process startup)

Unix中斷當前程式正在做的任何事情,並呼叫緊急訊號處理程式函式(Oracle在程式啟動過程中註冊)

The urgent signal handler blindly assumes that the urgent signal has been received because user wants to cancel the
query, stops the execution and returns back with an error: ORA-01013: user requested cancel of current operation

緊急訊號處理程式盲目地假設已經收到了緊急訊號,因為使用者想要取消查詢,停止執行並返回一個錯誤:ORA-01013:使用者請求取消當前
操作

This works only on Unix platforms. Also this does not work when your client application is Windows sqlplus! This is
because Windows sqlplus does not set up the out-of-band break checking properly when connecting. Maybe this is because
old Windows versions TCP stacks didn't know anything about urgent TCP packets! :)

這隻在Unix平臺上工作。此外,當您的客戶端應用程式是Windows sqlplus!這是因為Windows sqlplus在連線時沒有正確設定帶外中斷檢
查。也許這是因為舊的Windows版本的TCP堆疊對緊急TCP資料包一無所知!:)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2798515/,如需轉載,請註明出處,否則將追究法律責任。

相關文章