เนื่องจากฉันเห็นกระบวนการมากมายที่นั่นและคอลัมน์ "เวลา" จะแสดงค่ามหาศาลสำหรับกระบวนการทั้งหมด
เนื่องจากฉันเห็นกระบวนการมากมายที่นั่นและคอลัมน์ "เวลา" จะแสดงค่ามหาศาลสำหรับกระบวนการทั้งหมด
คำตอบ:
คุณต้องฆ่าพวกมันทีละคน MySQL ไม่มีคำสั่ง kill จำนวนมาก คุณสามารถเขียนสคริปต์เป็นภาษาใดก็ได้ตัวอย่างเช่นใน PHP คุณสามารถใช้สิ่งต่างๆเช่น:
$result = mysql_query("SHOW FULL PROCESSLIST");
while ($row=mysql_fetch_array($result)) {
$process_id=$row["Id"];
if ($row["Time"] > 200 ) {
$sql="KILL $process_id";
mysql_query($sql);
}
}
for i in {994..1145}; do mysql -uroot -p123456 -e "kill $i" ; done
ปฏิบัติการฆ่าจำนวนมากช่วยประหยัดเวลา ทำใน MySql เอง:
เรียกใช้คำสั่งเหล่านี้
mysql> select concat('KILL ',id,';') from information_schema.processlist
where user='root' and time > 200 into outfile '/tmp/a.txt';
mysql> source /tmp/a.txt;
---------edit------------
หากคุณไม่ต้องการจัดเก็บในไฟล์ให้จัดเก็บในไฟล์ variable
เพียงแค่เรียกใช้ในพรอมต์คำสั่งของคุณ
> out1=$(mysql -B test -uroot -proot --disable-column-names -e "select concat('KILL ',id,';') from information_schema.processlist where user='root' and time > 200;")
> out2= $(mysql -B test -uroot -proot --disable-column-names -e "$out1")
ฉันได้ค้นหาวิธีการแยกวิเคราะห์ผ่าน MySQL ด้วยคำสั่ง SHOW PROCESSLIST และจบลงด้วย one-liner ใน Shell:
mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
คุณสามารถรันgrepก่อนคำสั่งawkเพื่อกรองชื่อฐานข้อมูลเฉพาะ
หรือ ... ในเปลือก ...
service mysql restart
ใช่ฉันรู้ว่าฉันขี้เกียจ แต่มันก็มีประโยชน์เช่นกัน
สำหรับ mariaDB เท่านั้น
มันไม่ได้ง่ายไปกว่านี้แล้วเพียงแค่รันสิ่งนี้ใน mysql prompt
kill USER username;
มันจะฆ่ากระบวนการทั้งหมดภายใต้ชื่อผู้ใช้ที่ระบุ เนื่องจากคนส่วนใหญ่ใช้ผู้ใช้เดียวกันเพื่อวัตถุประสงค์ทั้งหมดมันได้ผล!
ฉันได้ทดสอบสิ่งนี้บน MariaDB แล้วไม่แน่ใจเกี่ยวกับ mysql
KILL [CONNECTION | QUERY] processlist_id
มีหลักฐานว่ามันเป็นไปได้ที่จะฆ่าโดยไม่มีผู้ใช้: ฉันลองใช้แบบสอบถามของคุณใน MySQL 5.6.34 และถือว่าเป็นข้อผิดพลาดทางไวยากรณ์
mysql> kill user root; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'root' at line 1
คำตอบของคุณอาจเป็นคุณลักษณะเฉพาะสำหรับ MariaDB เท่านั้น
ต่อไปนี้จะสร้างขั้นตอนการจัดเก็บอย่างง่ายที่ใช้เคอร์เซอร์เพื่อฆ่ากระบวนการทั้งหมดทีละรายการยกเว้นกระบวนการที่ใช้อยู่ในปัจจุบัน:
DROP PROCEDURE IF EXISTS kill_other_processes;
DELIMITER $$
CREATE PROCEDURE kill_other_processes()
BEGIN
DECLARE finished INT DEFAULT 0;
DECLARE proc_id INT;
DECLARE proc_id_cursor CURSOR FOR SELECT id FROM information_schema.processlist;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN proc_id_cursor;
proc_id_cursor_loop: LOOP
FETCH proc_id_cursor INTO proc_id;
IF finished = 1 THEN
LEAVE proc_id_cursor_loop;
END IF;
IF proc_id <> CONNECTION_ID() THEN
KILL proc_id;
END IF;
END LOOP proc_id_cursor_loop;
CLOSE proc_id_cursor;
END$$
DELIMITER ;
สามารถรันด้วยSELECT
s เพื่อแสดงกระบวนการก่อนและหลังดังนี้:
SELECT * FROM information_schema.processlist;
CALL kill_other_processes();
SELECT * FROM information_schema.processlist;
เมื่อเร็ว ๆ นี้ฉันต้องทำสิ่งนี้และฉันก็คิดสิ่งนี้ขึ้นมา
-- GROUP_CONCAT turns all the rows into 1
-- @q:= stores all the kill commands to a variable
select @q:=GROUP_CONCAT(CONCAT('KILL ',ID) SEPARATOR ';')
FROM information_schema.processlist
-- If you don't need it, you can remove the WHERE command altogether
WHERE user = 'user';
-- Creates statement and execute it
PREPARE stmt FROM @q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
ด้วยวิธีนี้คุณไม่จำเป็นต้องจัดเก็บลงไฟล์และเรียกใช้แบบสอบถามทั้งหมดด้วยคำสั่งเดียว
ฆ่าคำถามที่เลือกทั้งหมด
select concat('KILL ',id,';')
from information_schema.processlist
where user='root'
and INFO like 'SELECT%' into outfile '/tmp/a.txt';
source /tmp/a.txt;
หากคุณไม่มี information_schema:
mysql -e "show full processlist" | cut -f1 | sed -e 's/^/kill /' | sed -e 's/$/;/' ; > /tmp/kill.txt
mysql> . /tmp/kill.txt
เข้าสู่ระบบ Mysql ในฐานะผู้ดูแลระบบ:
mysql -uroot -ppassword;
และกว่ารันคำสั่ง:
mysql> show processlist;
คุณจะได้รับสิ่งต่อไปนี้:
+----+-------------+--------------------+----------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+--------------------+----------+---------+------+-------+------------------+
| 49 | application | 192.168.44.1:51718 | XXXXXXXX | Sleep | 183 | | NULL ||
| 55 | application | 192.168.44.1:51769 | XXXXXXXX | Sleep | 148 | | NULL |
| 56 | application | 192.168.44.1:51770 | XXXXXXXX | Sleep | 148 | | NULL |
| 57 | application | 192.168.44.1:51771 | XXXXXXXX | Sleep | 148 | | NULL |
| 58 | application | 192.168.44.1:51968 | XXXXXXXX | Sleep | 11 | | NULL |
| 59 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+-------------+--------------------+----------+---------+------+-------+------------------+
คุณจะเห็นรายละเอียดทั้งหมดของการเชื่อมต่อที่แตกต่างกัน ตอนนี้คุณสามารถฆ่าการเชื่อมต่อแบบสลีปได้ดังนี้:
mysql> kill 52;
Query OK, 0 rows affected (0.00 sec)
สิ่งนี้ใช้งานได้สำหรับฉัน (เซิร์ฟเวอร์ MySQL 5.5) เพื่อฆ่ากระบวนการ MySQL ทั้งหมด:
mysql -e "show full processlist;" -ss | awk '{print "KILL "$1";"}'| mysql
ฉันจะรวม bash และ mysql:
for i in $(mysql -Ne "select id from information_schema.processlist where user like 'foo%user' and time > 300;"); do
mysql -e "kill ${i}"
done
นี่คือโซลูชันที่คุณสามารถดำเนินการได้โดยไม่ต้องอาศัยระบบปฏิบัติการ:
ขั้นตอนที่ 1: สร้างขั้นตอนการจัดเก็บ
DROP PROCEDURE IF EXISTS kill_user_processes$$
CREATE PROCEDURE `kill_user_processes`(
IN user_to_kill VARCHAR(255)
)
READS SQL DATA
BEGIN
DECLARE name_val VARCHAR(255);
DECLARE no_more_rows BOOLEAN;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE num_rows INT DEFAULT 0;
DECLARE friends_cur CURSOR FOR
SELECT CONCAT('KILL ',id,';') FROM information_schema.processlist WHERE USER=user_to_kill;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = TRUE;
OPEN friends_cur;
SELECT FOUND_ROWS() INTO num_rows;
the_loop: LOOP
FETCH friends_cur
INTO name_val;
IF no_more_rows THEN
CLOSE friends_cur;
LEAVE the_loop;
END IF;
SET @s = name_val;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SELECT name_val;
SET loop_cntr = loop_cntr + 1;
END LOOP the_loop;
SELECT num_rows, loop_cntr;
END $$
DELIMITER ;
ขั้นตอนที่ 2: เรียกขั้นตอนการจัดเก็บโดยให้ชื่อของผู้ใช้ฐานข้อมูลที่มีกระบวนการที่คุณต้องการฆ่า คุณสามารถเขียนกระบวนงานที่จัดเก็บใหม่เพื่อกรองเกณฑ์อื่น ๆ ได้หากต้องการ
โทร kill_user_processes('devdba');
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
เราสามารถทำได้โดย MySQL Workbench เพียงดำเนินการนี้:
kill id;
ตัวอย่าง:
kill 13412
ที่จะลบมันออก
วิธีง่ายๆคือรีสตาร์ทเซิร์ฟเวอร์ mysql .. เปิด "services.msc" ใน windows Run เลือก Mysql จากรายการ คลิกขวาและหยุดบริการ จากนั้นเริ่มต้นอีกครั้งและกระบวนการทั้งหมดจะถูกฆ่ายกเว้นกระบวนการ (การเชื่อมต่อที่สงวนไว้เริ่มต้น)
#! /bin/bash
if [ $# != "1" ];then
echo "Not enough arguments.";
echo "Usage: killQueryByDB.sh <db_name>";
exit;
fi;
DB=${1};
for i in `mysql -u <user> -h localhost ${DB} -p<password> -e "show processlist" | sed 's/\(^[0-9]*\).*/\1/'`; do
echo "Killing query ${i}";
mysql -u <user> -h localhost ${DB} -p<password> -e "kill query ${i}";
done;
บางครั้งฉันมีกระบวนการ mysql ของซอมบี้ที่ไม่สามารถฆ่าได้ (โดยใช้ MAMP Pro)
ขั้นแรกรับรายการกระบวนการ mysql ทั้งหมด:
ps -ax | grep mysql
จากนั้นฆ่าทุกคนด้วย (แทนที่ processId ด้วยคอลัมน์แรกในผลลัพธ์คำสั่งก่อนหน้า):
kill -9 processId
สิ่งต่อไปนี้ใช้ได้ผลดีสำหรับฉัน:
echo "show processlist" | mysql | grep -v ^Id | awk '{print $1}' | xargs -i echo "KILL {}; | mysql"
ฉันใช้คำสั่งflush tables
เพื่อฆ่าการเชื่อมต่อที่ไม่ใช้งานทั้งหมดซึ่งเป็นปัญหาที่เกิดขึ้นจริง
สำหรับภาษา python คุณสามารถทำได้เช่นนี้
import pymysql
connection = pymysql.connect(host='localhost',
user='root',
db='mysql',
cursorclass=pymysql.cursors.DictCursor)
with connection.cursor() as cursor:
cursor.execute('SHOW PROCESSLIST')
for item in cursor.fetchall():
if item.get('Time') > 200:
_id = item.get('Id')
print('kill %s' % item)
cursor.execute('kill %s', _id)
connection.close()
หากคุณใช้ laravel สิ่งนี้เหมาะสำหรับคุณ:
$query = "SHOW FULL PROCESSLIST";
$results = DB::select(DB::raw($query));
foreach($results as $result){
if($result->Command == "Sleep"){
$sql="KILL ". $result->Id;
DB::select(DB::raw($sql));
}
}
แน่นอนคุณควรใช้สิ่งนี้use Illuminate\Support\Facades\DB;
หลังเนมสเปซ
แบบสอบถาม 1 เลือก concat ('KILL', id, ';') จาก information_schema.processlist โดยที่ user = 'username' เป็น outfile '/tmp/a.txt';
Query 2 ที่มา a.txt
สิ่งนี้จะช่วยให้คุณสามารถฆ่าการค้นหาทั้งหมดในรายการกระบวนการแสดงโดยผู้ใช้ที่ระบุ
sudo service mysqld restart