web-dev-qa-db-ja.com

MySQLはwait_timeout値を下げて、開いている接続の数を減らします

私はかなり忙しいサイトを実行しており、ピーク時間中に、netstatコマンドを実行すると、Webサーバー上のデータベースサーバーへの10.000を超える接続が開いていることがわかります。接続の99%はTIME_WAIT状態です。

私はこのmysql変数について学びました:wait_timeouthttp://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout 今日。鉱山は依然としてデフォルトの28.800秒に設定されています。

この値を下げても安全ですか?

通常、私のクエリは1秒もかかりません。したがって、480分間接続を開いたままにしておくのはばかげているようです。

mysql_pconnectの代わりにmysql_connectの使用についても聞いたことがありますが、ホラーストーリーだけを読んでいるので、これからは遠ざけるつもりです。

40
Mr.Boon

Mysqlを再起動しないと、値を下げるのはかなり簡単です

タイムアウトを30秒に下げたいとしましょう

まず、これをmy.cnfに追加します

[mysqld]
interactive_timeout=30
wait_timeout=30

その後、あなたはこのようなことをすることができます

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

これ以降のすべてのDB接続は30秒でタイムアウトします

警告

Mysql_closeを明示的に使用してください。ほとんどの開発者がそうであるように、私はApacheを信頼しません。そうでない場合、ApacheがDB接続を閉じるがmysqldに通知せず、mysqldがタイムアウトするまでその接続を開いたままにするという競合状態が発生することがあります。さらに悪いことに、TIME_WAITがより頻繁に表示される場合があります。タイムアウト値は慎重に選択してください。

UPDATE 2012-11-12 10:10 EDT

警告

投稿した提案を適用したら、次の行を含む/root/show_mysql_netstat.shというスクリプトを作成します。

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/'

これを実行すると、次のように表示されます。

[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

それでも多くのmysql TIME_WAITsが特定のWebサーバーに対して表示される場合は、次の2つのエスカレーション手順を実行します。

エスカレーション#1

問題のあるWebサーバーにログインし、次のようにApacheを再起動します。

service httpd stop
sleep 30
service httpd start

必要に応じて、すべてのWebサーバーに対してこれを実行します

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

エスカレーション#2

次のようにして、OSにmysqlまたはその他のアプリのTIME_WAITを強制終了させることができます。

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

これにより、TIME_WAITが1秒でタイムアウトになります。

クレジットが期日までにクレジットを与えるには...

75
RolandoMySQLDBA

MySQLサーバーで多数のTIME_WAIT接続を取得している場合、それはMySQLサーバーが接続を閉じていることを意味します。この場合の最も可能性の高いケースは、ホストまたは複数のホストがブロックリストに登録された場合です。これを実行すると、これをクリアできます。

mysqladmin flush-hosts

IPごとに実行している接続数のリストを取得するには、次のコマンドを実行します。

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

また、ポート3306への接続とtelnetに問題があるクライアントの1つにアクセスして、これが発生していることを確認することもできます。次のようなメッセージが表示されます。

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.
4
user2566717

MySQLサーバーへのTIME_WAIT接続が多数ある場合、コードがDBに対して多数のクエリを実行し、各クエリの接続を開いたり閉じたりしていることを意味します。

この場合、MySQLi拡張機能を使用して、DBサーバーへの永続的な接続を使用する必要があります。

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

MySQLiを使用できない場合は、代わりにMySQL設定でthread_cache_sizeパラメータを使用する必要があります。

1
Garreth McDaid