MySQL 降低 wait_timeout 值以减少打开的连接数

Mr.*_*oon 41 mysql tuning

我运行一个相当繁忙的站点,在偷看时间,当运行 netstat 命令时,我在我的网络服务器上看到超过 10.000 个到我的数据库服务器的打开连接。99% 的连接都在TIME_WAIT状态中。

我今天了解了这个 mysql 变量:wait_timeout http : //dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout。我的仍然设置为默认的 28.800 秒。

降低这个值安全吗?

我的查询通常不会超过一秒钟。因此,将连接保持打开 480 分钟似乎很愚蠢。

我也听说过使用mysql_pconnect而不是mysql_connect,但我一直在读关于它的恐怖故事,所以我想我会远离它。

Rol*_*DBA 77

在没有重启 mysql 的情况下降低该值非常简单

假设您想将超时降低到 30 秒

首先,将此添加到 my.cnf

[mysqld]
interactive_timeout=30
wait_timeout=30
Run Code Online (Sandbox Code Playgroud)

然后,你可以做这样的事情

mysql -uroot -ppassword -e"SET GLOBAL wait_timeout=30; SET GLOBAL interactive_timeout=30"
Run Code Online (Sandbox Code Playgroud)

此后的所有数据库连接将在 30 秒后超时

警告

确保使用显式使用 mysql_close。我不像大多数开发人员那样信任 Apache。如果没有,有时会出现竞争条件,即 Apache 关闭数据库连接但不通知 mysqld 并且 mysqld 保持该连接打开直到超时。更糟糕的是,您可能会更频繁地看到 TIME_WAIT。明智地选择超时值。

更新 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/'
Run Code Online (Sandbox Code Playgroud)

当你运行它时,你应该看到这样的东西:

[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
Run Code Online (Sandbox Code Playgroud)

如果您仍然看到TIME_WAITs任何给定 Web 服务器的大量 mysql ,请执行以下两个升级步骤:

升级 #1

登录到有问题的 Web 服务器并重新启动 apache,如下所示:

service httpd stop
sleep 30
service httpd start
Run Code Online (Sandbox Code Playgroud)

如有必要,请对所有 Web 服务器执行此操作

service httpd stop (on all web servers)
service mysql stop
sleep 120
service mysql start
service httpd start (on all web servers)
Run Code Online (Sandbox Code Playgroud)

升级#2

您可以使用以下命令强制操作系统终止 mysql 或任何其他应用程序的 TIME_WAITs:

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
Run Code Online (Sandbox Code Playgroud)

这将使 TIME_WAITs 在 1 秒内超时。

在信用到期时给予信用......