Я шукаю добре перевірений сценарій bash (або альтернативне рішення), щоб зробити це, щоб уникнути вичерпання max_connection. Я знаю, що це боротьба з симптомами, але дуже потрібен такий сценарій, як короткочасне рішення.
Я шукаю добре перевірений сценарій bash (або альтернативне рішення), щоб зробити це, щоб уникнути вичерпання max_connection. Я знаю, що це боротьба з симптомами, але дуже потрібен такий сценарій, як короткочасне рішення.
Відповіді:
перевірити команду pt-kill з інструментарію percona .
і .. почніть моніторинг вашої системи - munin , кактуси з кращими шаблонами кактусів для mysql , будь-що, щоб ви зрозуміли, що відбувається. увійти мирові запити mysql також буде хорошою ідеєю.
Якщо у вас є MySQL 5.1, де список процесів знаходиться в INFORMATION_SCHEMA, ви можете зробити це, щоб генерувати масово команди KILL QUERY з клієнта mysql для запиту, який триває більше 20 хвилин (1200 секунд):
SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery
FROM information_schema.processlist WHERE user<>'system user'
AND time >= 1200\G
Ви можете виконати пункти WHERE проти поля INFO, щоб шукати конкретний запит, поле 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
Ви можете це зробити так:
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
BTW У вас не вказано myDB, оскільки я чітко читаю з information_schema.processlist як повноцінне ім'я таблиці.
Ось демонстрація того, що ви повинні бачити. У цьому прикладі я повторюю команду KILL усіх процесів, час> 20000 секунд:
[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
MySQL 5.7 далі ви можете використовувати змінну max_execution_time, щоб зробити це автоматично для всіх запитів читання "SELECT".
Я б не намагався баш-рішень, якщо вам подобається тривалість роботи!
Якщо у вас є доступ до коду, ви можете фактично встановити максимальний час виконання для операторів 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
Переконайтесь, що правила відповідності відповідають вашому випадку. Зазначені вище вбивають усі оператори Execute протягом 45 секунд. Коли ви впевнені, то змініть та запустіть цю команду для виконання оператора через інтервал 10 секунд:
$ ./pt-kill -u root -p myreallyimportantpassword --busy-time 45 --kill-busy-commands 'Execute' --victims all --interval 10 --kill