MySQL은 wait_timeout 값을 낮추어 열린 연결 수를 줄입니다.


39

다소 바쁜 사이트를 운영하고 있으며 엿보기 시간 동안 netstat 명령을 실행할 때 웹 서버의 데이터베이스 서버에 10 만 개 이상의 연결이 열려 있습니다. 연결의 99 %가 TIME_WAIT상태에 있습니다.

나는이 mysql 변수에 대해 배웠다 : wait_timeout http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout 오늘. 광산은 여전히 ​​기본 28.800 초로 설정되어 있습니다.

이 값을 낮추는 것이 안전합니까?

내 쿼리 중 일반적으로 1 초 이상이 걸립니다. 따라서 480 분 동안 연결을 유지하는 것은 어리석은 것 같습니다.

나는 mysql_pconnect대신 에 사용 하는 것에 대해 들었지만, 그것에 관한 mysql_connect공포 이야기 만 읽지 않았습니다. 그래서 나는 그것을 멀리 할 것이라고 생각합니다.


3
쿼리와 연결에는 차이가 있습니다. 소프트웨어가 wait_timeout열려있을 것으로 예상 할 때 연결 이 짧아 지면 웹 사이트 소프트웨어가 중단되지 않도록해야합니다 .
John Gardeniers

답변:


74

값을 낮추는 것은 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가 DB 연결을 닫지 만 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/'

이것을 실행하면 다음과 같이 보일 것입니다 :

[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_WAITs주어진 웹 서버에 대해 여전히 많은 mysql이 표시되는 경우 다음 두 가지 에스컬레이션 단계를 수행하십시오.

에스컬레이션 # 1

문제가있는 웹 서버에 로그인하고 다음과 같이 아파치를 다시 시작하십시오.

service httpd stop
sleep 30
service httpd start

필요한 경우 모든 웹 서버에이를 수행하십시오.

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_WAITs가 1 초 안에 시간 초과됩니다.

크레딧이 필요한 곳에 크레딧을 제공하려면 ...


1
이것에 대한 거의 2k 조회수와 2 업 투표 (내를 포함하여 1 포함), wtf ?! 이것은 좋은 대답입니다. 죄송 합니다만 1 표를 포기할 수 있습니다!
jwbensley 2016

이 기술을 시도했지만 CLOSE_WAIT 연결 (2622)이 많지만 TIME_WAIT 연결은 없습니다. 이 결과를 어떻게 해석해야합니까?
robguinness 2013

4

MySQL 서버에서 많은 TIME_WAIT 연결을 얻는다면 MySQL 서버가 연결을 닫고 있음을 의미합니다. 이 인스턴스에서 가장 가능성이 높은 경우는 호스트 또는 여러 호스트가 차단 목록에있는 것입니다. 다음을 실행하여이를 지울 수 있습니다.

mysqladmin flush-hosts

IP 실행 당 연결 수 목록을 얻으려면 다음을 수행하십시오.

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

포트 3306에 연결하고 텔넷하는 데 문제가있는 클라이언트 중 한 곳으로 이동하여 이러한 상황이 발생했는지 확인할 수도 있습니다. 다음과 같은 메시지가 표시됩니다.

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 서버에 대한 TIME_WAIT 연결이 많으면 DB에 대해 많은 쿼리를 실행하고 각 쿼리에 대한 연결을 열고 닫는다는 의미입니다.

이 경우 MySQLi 확장을 사용하여 DB 서버에 지속적으로 연결해야합니다.

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

MySQLi를 사용할 수 없으면 MySQL 구성에서 thread_cache_size 매개 변수를 대신 사용해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.