Risposte:
Devi ucciderli uno per uno, MySQL non ha alcun comando di uccisione massiccia. Puoi scriverlo in qualsiasi lingua, ad esempio in PHP puoi usare qualcosa come:
$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
L' operazione di uccisione di massa fa risparmiare tempo. Fallo in MySql stesso:
Esegui questi comandi
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------------
se non si desidera archiviare in file, archiviare in un file variable
Esegui semplicemente nel tuo prompt dei comandi
> 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")
Ho anche cercato come analizzare tramite MySQL il comando SHOW PROCESSLIST e terminato con una riga in una Shell:
mysqladmin processlist -u <USERNAME> -p<PASSWORD> | \
awk '$2 ~ /^[0-9]/ {print "KILL "$2";"}' | \
mysql -u <USERNAME> -p<PASSWORD>
È possibile eseguire grep prima del comando awk per filtrare un particolare nome di database.
Oppure ... in guscio ...
service mysql restart
Sì, lo so, sono pigro, ma può anche essere utile.
Non diventa più semplice di questo, basta eseguirlo nel prompt di mysql.
kill USER username;
Ucciderà tutto il processo con il nome utente fornito. poiché la maggior parte delle persone usa lo stesso utente per tutti gli scopi, funziona!
Ho provato questo su MariaDB non sono sicuro di mysql.
KILL [CONNECTION | QUERY] processlist_id. Ho provato la tua query in MySQL 5.6.34 ed è considerata un errore di sintassi.
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 Probabilmente la tua risposta è una caratteristica specifica solo di MariaDB.
Quanto segue creerà una semplice procedura memorizzata che utilizza un cursore per terminare tutti i processi uno per uno tranne quello attualmente in uso:
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 ;
Può essere eseguito con SELECTs per mostrare i processi prima e dopo come segue:
SELECT * FROM information_schema.processlist;
CALL kill_other_processes();
SELECT * FROM information_schema.processlist;
Di recente avevo bisogno di farlo e mi è venuto in mente questo
-- 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;
In questo modo, non è necessario archiviare su file ed eseguire tutte le query con un singolo comando.
KILL TUTTE LE DOMANDE SELEZIONATE
select concat('KILL ',id,';')
from information_schema.processlist
where user='root'
and INFO like 'SELECT%' into outfile '/tmp/a.txt';
source /tmp/a.txt;
accedi a Mysql come amministratore:
mysql -uroot -ppassword;
E poi eseguire il comando:
mysql> show processlist;
Otterrai qualcosa come di seguito:
+----+-------------+--------------------+----------+---------+------+-------+------------------+
| 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 |
+----+-------------+--------------------+----------+---------+------+-------+------------------+
Vedrai i dettagli completi delle diverse connessioni. Ora puoi interrompere la connessione inattiva come di seguito:
mysql> kill 52;
Query OK, 0 rows affected (0.00 sec)
Questo frammento ha funzionato per me (server MySQL 5.5) per uccidere tutti i processi MySQL:
mysql -e "show full processlist;" -ss | awk '{print "KILL "$1";"}'| mysql
Ecco una soluzione che puoi eseguire senza fare affidamento sul sistema operativo:
PASSAGGIO 1: creare una procedura memorizzata.
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 ;
PASSAGGIO 2: chiamare la procedura memorizzata dandogli il nome di un utente del database di cui si desidera terminare i processi. Potresti riscrivere la stored procedure per filtrare in base ad altri criteri, se lo desideri.
CHIAMATA kill_user_processes('devdba');
mysqladmin pr -u 'USERNAME' -p'PASSWORD' | awk '$2~/^[0-9]+/{print $2}' | xargs -i mysqladmin -u 'USERNAME' -p'PASSWORD' kill {}
Possiamo farlo da MySQL Workbench. Basta eseguire questo:
kill id;
Esempio:
kill 13412
Questo lo rimuoverà.
Un modo semplice sarebbe riavviare il server mysql .. Apri "services.msc" in Windows Esegui, seleziona Mysql dall'elenco. Fare clic con il tasto destro e interrompere il servizio. Quindi ricomincia e tutti i processi sarebbero stati uccisi tranne quello (la connessione riservata predefinita)
#! /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;
A volte ho alcuni processi mysql di zombi che non possono essere uccisi (usando MAMP Pro).
Per prima cosa ottieni un elenco di tutti i processi mysql:
ps -ax | grep mysql
Quindi uccidi ognuno di loro con (sostituisci processId con la prima colonna nel risultato del comando precedente):
kill -9 processId
Quanto segue ha funzionato alla grande per me:
echo "show processlist" | mysql | grep -v ^Id | awk '{print $1}' | xargs -i echo "KILL {}; | mysql"
per il linguaggio Python, puoi fare così
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()
Se stai usando laravel, questo è per te:
$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));
}
}
Ovviamente dovresti usarlo use Illuminate\Support\Facades\DB;dopo il tuo spazio dei nomi.
Query 1 select concat ('KILL', id, ';') da information_schema.processlist dove user = 'username' in outfile '/tmp/a.txt';
Fonte della query 2 a.txt
Ciò ti consentirà di terminare tutte le query in show processlist da parte di un utente specifico.
sudo service mysqld restart