回答:
perconaツールキットからpt-killコマンドを確認してください。
そして...あなたのシステムの監視を開始します- のmunin、サボテンとMySQLのためのより良いサボテンのテンプレート、何でもあなたが上で何が起こっているのか、いくつかのアイデアを得るようにします。mysqlの遅いクエリを記録することも良い考えです。
プロセスリストがINFORMATION_SCHEMAにあるMySQL 5.1がある場合、これを実行して、20分(1200秒)より長いクエリを実行するためにmysqlクライアント内からKILL QUERYコマンドを一括で生成できます。
SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery
FROM information_schema.processlist WHERE user<>'system user'
AND time >= 1200\G
INFOフィールドに対してWHERE句を実行して、特定のクエリ、長時間実行されるクエリに対してTIMEフィールド、または特定のデータベースに対してDBフィールドを検索できます。
root @ localhostの場合、次のようにこれを実行するための完全な権限が必要です。
SECONDS_TOO_LONG=1200
KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword
次のようにこれをcrontabできます:
SECONDS_TOO_LONG=1200
QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"`
if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ]
then
KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword
fi
別のバリエーションがあります:
SECONDS_TOO_LONG=1200
QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"`
if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ]
then
KILLPROC_SQLSTMT="SELECT CONCAT('KILL QUERY ',id,';') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" > /tmp/kill_log_queries.sql
mysql -uroot -ppassword < /tmp/kill_log_queries.sql
fi
ところで、完全修飾テーブル名としてinformation_schema.processlistから明示的に読み取ったため、myDBを指定していません。
ここにあなたが見るべきもののデモがあります。この例では、時間が20000秒を超えるすべてのプロセスのKILLコマンドをエコーします。
[root@***** ~]# mysql `lwdba_connect` -ANe"SELECT GROUP_CONCAT('KILL ',id,'; ' SEPARATOR ' ') FROM information_schema.processlist WHERE time > 25000 AND user<>'system user';"
+----------------------------------------------------+
| KILL 180186; KILL 180141; KILL 176419; KILL 3; |
+----------------------------------------------------+
[root@***** ~]#
私はこの5年間、この手法を行ってきました。実際、私は昨年、この回答をDBA StackExchangeに提出し、受け入れられました。
更新 2013-01-14:これは潜在的に危険であり、複製プロセスも殺す可能性があるという匿名のヒントがありました。自己責任で使用してください:
mysql -e 'show processlist\G' |\
egrep -b5 'Time: [0-9]{2,}' |\
grep 'Id:' |\
cut -d':' -f2 |\
sed 's/^ //' |\
while read id
do
mysql -e "kill $id;"
done
稼働時間が好きなら、bashソリューションを試してみません!
コードにアクセスできる場合は、ここで概説した方法を使用して、実際にSELECTステートメントの最大実行時間を設定できます。
SELECT
MAX_EXECUTION_TIME = 1000 --in milliseconds
*
FROM table;
それ以外の場合、サーバー上で:
/programming/415905/how-to-set-a-maximum-execution-time-for-a-mysql-query
pt-killをインストールします。
$ wget percona.com/get/pt-kill
プロセスリストのスナップショットを取得します。
$ mysql -u root -B -pmyreallyimportantpassword -e "show processlist;" > processlist.txt
スナップショットでpt-killをテストします。
$ ./pt-kill --test-matching processlist.txt --busy-time 45 --kill-busy-commands 'Execute' --victims all --print
# 2019-02-25T17:34:37 KILL 45710302 (Execute 374 sec) SELECT\n\tCOUNT(DISTINCT(LP.sessionId))\nFROM lp_traffic LP\nINNER JOIN orders O ON O.orderId = LP.order
# 2019-02-25T17:34:37 KILL 45713515 (Execute 67 sec) SELECT \n\tCOUNT(DISTINCT(CASE WHEN T.response = 'SUCCESS' AND T.isVoid = 0 AND (T.txnType IN
一致ルールがケースに合っていることを確認してください。上記のコマンドは、45秒にわたってすべてのExecuteステートメントを強制終了します。確認したら、次のコマンドを変更して実行し、10秒間隔でステートメントを実行します。
$ ./pt-kill -u root -p myreallyimportantpassword --busy-time 45 --kill-busy-commands 'Execute' --victims all --interval 10 --kill