oracle,mysql,pg杀会话区别和注意点
##### pg和mysql杀会话要用数据库层命令,oracle数据库层有多个命令,还有disconnect... immediate相当于os的kill命令
##### pg和mysql不能在os层用kill杀会话,会导致重启所有会话,pg除了postmater和logger进程,其他后台进程也重启,mysql直接是实例重启,mysqld也会重启
##### 只有oracle可以用os的kill杀会话,一般只杀指定会话,出现严重问题时批量杀LOCAL=NO的远程连接:
ps -ef|grep ora|grep -v grep|grep -v ora_|grep LOCAL=NO|awk '{print $2}'|xargs kill -9
##### 另外杀会话一般只杀连接,而不是杀sql,杀sql,连接和事务还在,还要配合程序端的重试机制,否则会话还挂在那。
##### 三大数据库都提供杀会话连接、杀会话正在执行sql的命令,一般杀连接不是杀会话
pg中不要kill -9 pid 杀会话,很危险,它不会只杀指定会话,而是把所有客户端连接会话都杀掉,正常会话杀掉还不会重启。
然后相关后台进程都会重启(除了postmaster和logger不会重启),在pg里杀会话还是用常规select pg_terminate_backend(pid)
一般数据库杀会话,提供cancel/kill sql和disconnect session两种方法,{BANNED}中国第一种取消{BANNED}最佳近的sql,但是事务和连接还在,一般不会用这个,
这个要程序端有重试机制,不然会话还挂在那,可能持有锁还不会释放,而要用第二张,disconnect/kill session。
mysql如果通过os kill 会话的thread_id也会导致主进程mysqld重启和kill所有会话,所以也不能os层kill,而要用数据库的kill命令。
三大数据库,只有oracle可以在os层kill -9 pid,对于pg和mysql要使用数据库提供的命令来kill会话:
pg:pg_cancel_backend(pid)和 pg_terminate_backend(pid),一般用后面的终止会话,前面的是终止sql没有断开会话,事务并未结束还要配合重试机制需要编程解决。
mysql:KILL [CONNECTION | QUERY] processlist_id,默认是kill connection断开会话,而不是终止sql
###
pg和mysql如果终止会话后,再次执行语句,{BANNED}中国第一次会提示会话断开,第二次会重新建立连接执行SQL,而oracle断开了不会重启会话。
Oracle也有数据库的kill session命令:
kill session是需要交给数据库自己清理会话,需要回滚等释放资源,遇到大事务,可能很慢,这时候可能需要os层kill,os层kill会破坏一致性。
ALTER SYSTEM KILL SESSION 'sid,serial#';
ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id';
### 数据库层一般用这个
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- disconnect增加POST_TRANSACTION是等待事务正常完成后再断开,基本没有啥用,必须事务发送了commit或rollback才会断开会话
-- disconnect immediate是相当于os的kill -9 spid,立即断开会话进程
ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION;
##这个和os的kill -9类似,如果alter system kill session杀不掉用这个。
ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;
--18c开始的终止sql,终止sql,则会话还在那,事务也不会回滚,一般不用,要配合重试机制。
ALTER SYSTEM CANCEL SQL 'SID, SERIAL[, @INST_ID][, SQL_ID]';
--os层
kill -9 spid
-- Oracle可以用这个生成alter system kill session或os的kill命令
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'
and ...;