Ben max_connection bitmesini önlemek için, bunu yapmak için iyi test edilmiş bir bash script (veya alternatif çözüm) arıyorum. Semptomlarla savaştığını biliyorum, ancak kısa süreli bir çözüm olarak gerçekten senaryoya ihtiyaç duyuyorum.
Ben max_connection bitmesini önlemek için, bunu yapmak için iyi test edilmiş bir bash script (veya alternatif çözüm) arıyorum. Semptomlarla savaştığını biliyorum, ancak kısa süreli bir çözüm olarak gerçekten senaryoya ihtiyaç duyuyorum.
Yanıtlar:
percona araç setinden pt-kill komutunu kontrol edin .
- ve .. sisteminizi izleme başlarım Munin , kaktüs ile daha iyi kaktüsler mysql için şablonlar size ne oluyor bazı fikir edinmek böylece, herhangi bir şey. mysql yavaş sorguları günlüğe kaydetmek de iyi bir fikir olacaktır.
İşlem listesinin BİLGİ_SCHEMA'da bulunduğu MySQL 5.1'iniz varsa, bunu 20 dakikadan (1200 saniye) daha uzun süren sorgu için mysql istemcisinden toplu olarak KILL QUERY komutlarını oluşturmak için yapabilirsiniz:
SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery
FROM information_schema.processlist WHERE user<>'system user'
AND time >= 1200\G
Belirli bir sorguyu, uzun süren sorgulara karşı ZAMAN alanını veya belirli bir veritabanına karşı DB alanını aramak için BİLGİ alanına karşı WHERE yan tümceleri yapabilirsiniz.
Root @ localhost iseniz, bunu aşağıdaki gibi çalıştırmak için tam ayrıcalıklara sahip olmalısınız
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
Bunu aşağıdaki gibi crontab edebilirsiniz:
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
İşte başka bir varyasyon:
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 Information_schema.processlist'ten tam olarak nitelenmiş bir tabename olarak açıkça okuduğum için bir myDB belirtmeniz gerekmez.
İşte ne görmeniz gerektiğini gösteren bir örnek. Bu örnek için, zamanı> 20000 saniye olan tüm işlemlerin KILL komutunu yankılayacağım:
[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@***** ~]#
Bu tekniği son 5 yıldır yapıyorum. Aslında, bu cevabı geçen yıl DBA StackExchange'e gönderdim ve kabul edildi .
Ben burada aşağıdaki kod snipped bulundu :
2013-01-14 Güncellemesi : Bunun potansiyel olarak tehlikeli olduğu ve çoğaltma işlemlerini de öldürebileceği konusunda anonim bir ipucu vardı. Bu yüzden kendi sorumluluğunuzdadır kullanın:
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 ve sonrasında tüm "SELECT" okuma sorguları için bunu otomatik olarak yapmak için max_execution_time değişkenini kullanabilirsiniz.
Çalışma süresini seviyorsanız bash çözümlerini denemem!
Koda erişiminiz varsa, burada özetlenen yöntemi kullanarak SELECT ifadelerinde maksimum yürütme süresini ayarlayabilirsiniz :
SELECT
MAX_EXECUTION_TIME = 1000 --in milliseconds
*
FROM table;
Aksi takdirde, sunucuda:
/programming/415905/how-to-set-a-maximum-execution-time-for-a-mysql-query
Pt-kill'i yükleyin:
$ wget percona.com/get/pt-kill
İşlem listenizin bir anlık görüntüsünü alın:
$ mysql -u root -B -pmyreallyimportantpassword -e "show processlist;" > processlist.txt
Anlık görüntüde pt-kill'i test edin:
$ ./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
Eşleşme kurallarının davanıza uygun olduğundan emin olun. Yukarıda belirtilenler 45 saniye boyunca tüm Execute deyimlerini öldürecektir. Emin olduktan sonra, ifadeyi 10 saniyelik aralıklarla çalıştırmak için bu komutu değiştirin ve çalıştırın:
$ ./pt-kill -u root -p myreallyimportantpassword --busy-time 45 --kill-busy-commands 'Execute' --victims all --interval 10 --kill