Oracle:
(1)数据库内操作
1 2 3 4 5 6 7 |
--单实例: select 'alter system kill session '''||s.sid||','||s.SERIAL#||''' immediate;' from v$session s where s.status='INACTIVE' --状态为非活跃 and s.USERNAME= 'ZZZ' --用户为ZZZZ s.type<>'BACKGROUND' --不为oracle后台进程 and program not like '%(J0%' --不为oracle的JOB进程 order by s.LOGON_TIME asc,sql_exec_start asc; |
(2)操作系统中操作(要求登录到数据库主机)
1 2 |
## kill掉所有local=no的非本地连接进程 ps -ef|grep -v grep|grep LOCAL=NO|awk '{print $2}'|xargs kill -9 |
SQL Server:
1 2 3 |
--kill 被阻塞会话 select 'kill '+cast(spid as varchar) FROM sys.sysprocesses sp where sp.blocked !=0 and sp.spid != sp.blocked and loginame='XXX'; |
PG:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
(1)数据库内操作: 方案一,较保守、风险低,但是针对高并发的系统效果不好。因为kill的速度慢,跟不上再次上来的会话。 SELECT 'select pg_terminate_backend('||pid||');' FROM pg_stat_activity WHERE pid <> pg_backend_pid() -- 不kill掉自己的进程 and datname='ZZZ' --涉及到的数据库名 and usename='ZZZ' --涉及到的用户名 and query like '%ZZZ%' – 涉及到的语句 order by (now()-query_start) desc – 根据执行时间长短排序,先kill执行时间长的 ; 方案二,可以针对高并发系统,会话上来很快,且kong端虽然限流但是还是没有限制住(可能是开发没找对接口,报给运维限制了kong,但是还是有大量的会话进来) 1. 先确认pid对应的sql是需要kill的sql,没有别的类似相似的sql干扰: SELECT pid,query FROM pg_stat_activity WHERE pid <> pg_backend_pid() and datname='XXX' and usename='YYY' and state='active' and query like '%ZZZZZZZZ%' order by (now()-query_start) desc; 如: SELECT pid,query FROM pg_stat_activity WHERE pid <> pg_backend_pid() and datname='flysafe_websdite' and usename='app_rw' and state='active' and query like '%SELECT * FROM "quiz_info" WHERE "quiz_info"."deleted_at" IS NULL AND (("questionnaire_id" IN ($1)) AND (enc_sn = $2))%' order by (now()-query_start) desc; 2.然后批量循环kill session select pg_terminate_backend(pid) from (SELECT pid FROM pg_stat_activity WHERE pid <> pg_backend_pid() and datname='XXX' and usename='YYY' and state='active' and query like '%ZZZ%' ) a \watch 5; 如: select pg_terminate_backend(pid) from (SELECT pid FROM pg_stat_activity WHERE pid <> pg_backend_pid() and datname='flysafe_websdite' and usename='app_rw' and state='active' and query like '%SELECT * FROM "quiz_info" WHERE "quiz_info"."deleted_at" IS NULL AND (("questionnaire_id" IN ($1)) AND (enc_sn = $2))%' ) a \watch 5; |
(2)操作系统中操作(要求登录到数据库主机)
1 |
有kill -9的语句可以用,但是不建议,会导致正在update的语句被kill之后,数据库进入recovery状态。 |
MySQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
(1) aws : select concat('call mysql.rds_kill(',id,');') from information_schema.processlist where user='ZZZ' and info like '%ZZZ%' -- 当前消耗高的SQL语句 and command = '' -- 按照SQL语句的状态 order by time desc; --- 在SQL命令行得到的kill命令不能直接粘贴复制,可通过shell命令快速得到kill id的脚本 mysql -uroot -p -h xxxx < kill_query.sh > kill_id.txt (2) 阿里云 : select concat('KILL ',id,';') from information_schema.processlist where user='ZZZ' -- 操作的数据库用户 and info like '%ZZZ%' -- 当前消耗高的SQL语句 and command = '' -- 按照SQL语句的状态 order by time desc; -- 根据操作时间排序,先kill执行时间长的; --- 在SQL命令行得到的kill命令不能直接粘贴复制,可通过shell命令快速得到kill id的脚本 mysql -uroot -p -h xxxx < kill_query.sh > kill_id.txt (3)内网 (3.1)数据库内操作: select time,concat('KILL ',id,';') from information_schema.processlist where user='ZZZ' --操作的数据库用户 and info like '%ZZZ%' –当前消耗高的SQL语句 order by time desc; --根据操作时间排序,先kill执行时间长的; (3.2)操作系统中操作:(要求登录到数据库主机) ## 假定kill掉所有ZZZ用户的线程 mysqladmin -uroot -p processlist|awk -F "|" '{if($3 == "ZZZ")print $2}'|xargs -n 1 mysqladmin -uroot -p kill |