MySQL wait_timeout değerini düşürerek açık bağlantı sayısını düşürür


39

Oldukça yoğun bir site işletiyorum ve peek saatlerinde bir netstat komutu çalıştırdığınızda web sunucumda veritabanı sunucuma 10.000'in üzerinde açık bağlantı görüyorum. Bağlantıların% 99'u TIME_WAITeyalette.

Bu mysql değişkenini öğrendim: wait_timeout http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout . Mine hala varsayılan 28.800 saniyede ayarlanmış.

Bu değeri düşürmek güvenli midir?

Sorgularımdan hiçbiri genellikle bir saniyeden fazla sürmez. Bu yüzden bağlantının 480 dakika boyunca açık kalması aptalca görünüyor.

Ayrıca kullanmak mysql_pconnectyerine duyduğumu da duydum mysql_connect, ama korku hikayeleri dışında hiçbir şey okumadım, bu yüzden ondan uzak kalacağımı düşünüyorum.


3
Sorgular ve bağlantılar arasında bir fark var. En azından wait_timeout, yazılımın açık kalmasını beklediğinde bağlantının kapanmasına neden olursa, web sitesi yazılımınızın bozulmayacağından emin olmanız gerekir .
John Gardeniers

Yanıtlar:


74

Değeri düşürmek, mysql restart olmadan oldukça önemsizdir.

Zaman aşımını 30 saniyeye düşürmek istediğinizi varsayalım.

İlk önce bunu my.cnf dosyasına ekleyin.

[mysqld]
interactive_timeout=30
wait_timeout=30

O zaman böyle bir şey yapabilirsin

mysql -uroot -ppassword -e"SET GLOBAL wait_timeout=30; SET GLOBAL interactive_timeout=30"

Bundan sonraki tüm DB Bağlantıları 30 saniye içinde zaman aşımına uğrayacak

UYARI

Açıkça kullandığınızdan emin olun mysql_close. Çoğu geliştiricinin yaptığı gibi Apache'ye güvenmiyorum. Olmazsa, bazen, Apache'nin bir DB Bağlantısını kapattığı, ancak mysqld ve mysqld'in bu bağlantıyı zaman aşımına kadar açık tuttuğunu bildirmeyen bir yarış durumu vardır. Daha da kötüsü, TIME_WAIT'leri daha sık görebilirsiniz. Zaman aşımı değerlerinizi akıllıca seçin.

GÜNCELLEME 2012-11-12 10:10 EDT

UYARI

Gönderilen önerilerimi uyguladıktan sonra /root/show_mysql_netstat.sh, aşağıdaki satırlarla adlandırılan bir komut dosyası oluşturun :

netstat | grep mysql > /root/mysql_netstat.txt
cat /root/mysql_netstat.txt | awk '{print $5}' | sed 's/:/ /g' | awk '{print $2}' | sort -u > /root/mysql_netstat_iplist.txt
for IP in `cat /root/mysql_netstat_iplist.txt`
do
        ESCOUNT=`cat /root/mysql_netstat.txt | grep ESTABLISHED | awk '{print $5}' | grep -c "${IP}"`
        TWCOUNT=`cat /root/mysql_netstat.txt | grep TIME_WAIT   | awk '{print $5}' | grep -c "${IP}"`
        IPPAD=`echo "${IP}..................................." | cut -b -35`
        (( ESCOUNT += 1000000 ))
        (( TWCOUNT += 1000000 ))
        ES=`echo ${ESCOUNT} | cut -b 3-`
        TW=`echo ${TWCOUNT} | cut -b 3-`
        echo ${IPPAD} : ESTABLISHED:${ES} TIME_WAIT:${TW}
done
echo ; echo
netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n | sed 's/d)/d/'

Bunu çalıştırdığınızda, böyle bir şey görmelisiniz:

[root@*** ~]# /root/ShowConnProfiles.sh
10.48.22.4......................... : ESTABLISHED:00002 TIME_WAIT:00008
10.48.22.8......................... : ESTABLISHED:00000 TIME_WAIT:00002
10.64.51.130....................... : ESTABLISHED:00001 TIME_WAIT:00000
10.64.51.133....................... : ESTABLISHED:00000 TIME_WAIT:00079
10.64.51.134....................... : ESTABLISHED:00002 TIME_WAIT:00001
10.64.51.17........................ : ESTABLISHED:00003 TIME_WAIT:01160
10.64.51.171....................... : ESTABLISHED:00002 TIME_WAIT:00000
10.64.51.174....................... : ESTABLISHED:00000 TIME_WAIT:00589
10.64.51.176....................... : ESTABLISHED:00001 TIME_WAIT:00570


      1 established
      1 Foreign
     11 LISTEN
     25 ESTABLISHED
   1301 TIME_WAIT

TIME_WAITsHerhangi bir web sunucusu için hala çok fazla mysql görüyorsanız, atmanız gereken iki adım:

ESCALATION # 1

Sorunlu web sunucusuna giriş yapın ve apache'yi aşağıdaki gibi yeniden başlatın:

service httpd stop
sleep 30
service httpd start

Gerekirse, bunu tüm web sunucularına yapın

service httpd stop (on all web servers)
service mysql stop
sleep 120
service mysql start
service httpd start (on all web servers)

ESCALATION # 2

İşletim sistemini mysql için TIME_WAITs veya aşağıdakilerle birlikte başka bir uygulamayı öldürmeye zorlayabilirsiniz:

SEC_TO_TIMEWAIT=1
echo ${SEC_TO_TIMEWAIT} > /proc/sys/net/ipv4/tcp_tw_recycle
echo ${SEC_TO_TIMEWAIT} > /proc/sys/net/ipv4/tcp_tw_reuse

Bu, TIME_WAIT'lerin 1 saniye içinde zaman aşımına uğramasını sağlar.

Kredinin vadesinde kredi vermek ...


1
Bunun için yaklaşık 2k görüş ve sadece 2 oy (benimki, yani 1 de dahil), wtf ?! Bu harika bir cevap. Üzgünüm sadece 1 oy verebilirim!
jwbensley

Bu tekniği denedim ve çok sayıda CLOSE_WAIT bağlantım vardı (2622), ancak TIME_WAIT bağlantım yoktu. Bu sonucu nasıl yorumlamalıyım?
Robguinness

4

MySQL Sunucusunda çok sayıda TIME_WAIT bağlantısı alıyorsanız, bu MySQL sunucusunun bağlantıyı kapattığı anlamına gelir. Bu durumda en muhtemel durum, bir ev sahibi veya birkaç ev sahibinin bir blok listesine girmesi olabilir. Bunu çalıştırarak temizleyebilirsiniz:

mysqladmin flush-hosts

IP çalıştırması başına sahip olduğunuz bağlantı sayısının listesini görmek için:

 netstat -nat | awk {'print $5'} | cut -d ":" -f1 | sort | uniq -c | sort -n

Bunun, 3306 numaralı bağlantı noktasına bağlanması ve telnet ile bağlanması zor olan müşterilerinizden birine giderek de doğrulayabilirsiniz. Aşağıdaki gibi bir mesaj gösterecektir:

telnet mysqlserver 3306
Trying 192.168.1.102...
Connected to mysqlserver.
Escape character is '^]'.
sHost 'clienthost.local' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'Connection closed by foreign host.

1

MySQL sunucunuzla çok sayıda TIME_WAIT bağlantınız varsa, kodunuzun DB’nize karşı çok fazla sorgu çalıştırdığını ve her sorgu için bir bağlantı açıp / kapattığını gösterir.

Bu durumda, MySQLi uzantısını kullanarak DB sunucunuza kalıcı bağlantı kullanmalısınız.

http://php.net/manual/en/mysqli.persistconns.php

MySQLi kullanamıyorsanız, bunun yerine MySQL yapılandırmanızda thread_cache_size parametresini kullanmalısınız.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.