Oracle 数据库中经常会出现session阻塞等导致CPU使用率异常的情况,而一个快速解决这个故障的方法就是kill session,可以直接kill 所有session,也可以使用hanganalyze 工具找到具体的session 在kill。
关于hanganalyze的使用可以参考博客:
Oracle HANGANALYZE 功能诊断 DB hanging
https://www.cndba.cn/Dave/article/1562
Oracle 数据库有四种Kill Session的方法:
1: ALTER SYSTEM KILL SESSION
杀死会话的基本语法如下所示。
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#';
在RAC环境中,可以选择指定INST_ID,在查询GV$SESSION视图时显示。这允许终止不同RAC节点上的会话。
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id';
KILL SESSION命令实际上不会终止会话。它只是要求会话自杀。在某些情况下,例如等待远程数据库的回复或回滚事务,会话不会立即自行终止并等待当前操作完成。在这些情况下,会话将具有“标记为杀死”的状态。然后它会尽快被杀死。
除了上面描述的语法之外,还可以添加IMMEDIATE子句。
SQL> ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
这不会影响命令执行的工作,但会立即将控制权返回给当前会话,而不是等待确认kill。
如果标记的会话持续一段时间,您可以考虑在操作系统级别终止该进程。在执行此操作之前,有必要检查它是否正在执行回滚。你可以通过运行此脚本(session_undo.sql)来完成此操作。如果有问题的会话的USED_UREC值正在减少,则应该让它完成回滚而不是在操作系统级别终止会话。
2: ALTER SYSTEM DISCONNECT SESSION
ALTER SYSTEM DISCONNECT SESSION语法是用于终止Oracle会话的替代方法。与要求会话自行终止的KILL SESSION命令不同,DISCONNECT SESSION命令会终止专用服务器进程(或使用共享服务器时的虚拟电路),这相当于从操作系统中终止服务器进程。基本语法类似于KILL SESSION命令,并添加了POST_TRANSACTION子句。相关会话的SID和SERIAL#值可以替换为以下语句之一。
SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION;
SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;
POST_TRANSACTION子句在断开会话之前等待正在进行的事务完成,而IMMEDIATE子句断开会话并且正在进行的事务立即回滚。
POST_TRANSACTION和IMMEDIATE子句可以一起使用,但文档声明在这种情况下会忽略IMMEDIATE子句。此外,语法图表明两个子句都是可选的,但实际上,必须指定一个或两个,否则会收到错误。
SQL> alter system disconnect session '207,7';
alter system disconnect session '207,7'
*
ERROR at line 1:
ORA-02000: missing POST_TRANSACTION or IMMEDIATE keyword
此命令意味着你永远不需要切换到操作系统来终止会话,这样可以减少杀死错误进程的可能性。
3:ALTER SYSTEM CANCEL SQL (18c+)
Oracle数据库18c中引入了ALTER SYSTEM CANCEL SQL命令以取消会话中的SQL语句,从而提供了杀死恶意会话的替代方法。
ALTER SYSTEM CANCEL SQL 'SID, SERIAL[, @INST_ID][, SQL_ID]';
如果省略INST_ID,则假定表示当前实例。如果省略SQL_ID,则假定指的是当前在指定会话中运行的SQL。一些变化如下所示:
— 此实例上的当前SQL会话。
ALTER SYSTEM CANCEL SQL '61, 16384';
INST_ID = 1的实例中的当前SQL会话。
ALTER SYSTEM CANCEL SQL '61, 16384, @1';
— 在此实例的会话中指定的SQL。
ALTER SYSTEM CANCEL SQL '61, 16384, 2rr5x2xz7sbd3';
— 在INST_ID = 1的实例上的会话中指定的SQL。
ALTER SYSTEM CANCEL SQL '61, 16384, @1, 2rr5x2xz7sbd3';
4:操作系统级别杀掉进程
Windows方法
要在Windows操作系统上终止会话,请首先标识会话,然后将相关的SID和SPID值替换为从命令行发出的以下命令。
C:/Users/Leo> orakill ORACLE_SID spid
应立即终止会话线程并释放所有资源。
UNIX方法
警告:如果在Oracle 12c中使用多线程模型,则不应尝试终止操作系统进程。要知道原因,请阅读此内容。
要在UNIX或Linux操作系统上终止会话,请先识别会话,然后将相关的SPID替换为以下命令。
[root@cndba ~]# kill spid
如果几分钟后进程尚未停止,请使用以下命令终止会话。
[root@cndba ~]# kill -9 spid
如果有疑问,请检查SPID是否与使用的UNIX PROCESSID匹配。
[root@cndba ~]#ps -ef | grep ora
应立即终止会话线程并释放所有资源。
确定要杀死的会话
如果杀死错误的会话,被杀掉的会话可能会非常具有破坏性,因此在识别要杀死的会话时要非常小心。如果终止属于后台进程的会话,则会导致实例崩溃。
使用[G]V$SESSION和[G]V$PROCESS视图查询会话,如下所示。
SET LINESIZE 150
COLUMN spid FORMAT A10
COLUMN username FORMAT A10
COLUMN program FORMAT A45
COLUMN sql_id FORMAT A45
SELECT s.inst_id,
s.sid,
s.serial#,
s.sql_id,
p.spid,
s.username,
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';
然后,可以将相关会话的SID和SERIAL#值替换为前面部分中的命令。