MySQL abbassa il valore wait_timeout a un numero inferiore di connessioni aperte

Ho un sito piuttosto occupato e durante le ore di punta vedo oltre 10.000 connessioni aperte al mio server di database sul mio server web quando eseguo un command netstat. Il 99% dei collegamenti si trova nello stato TIME_WAIT .

Ho appreso questa variabile mysql: wait_timeout http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout oggi. La miniera è ancora impostata al 28.800 secondi di default.

Abbassa questo valore sicuro?

Non delle mie domande prende solitamente un secondo. Quindi sembra sciocco mantenere una connessione aperta per 480 minuti.

Ho anche sentito parlare dell'utilizzo di mysql_pconnect invece di mysql_connect , ma non ho letto nient'altro che storie horror su di esso, quindi penso di stare lontano da questo.

  • Scegliendo il diritto innodb_buffer_pool_size
  • Come identificare i bottleneck di I / O su un server Linux?
  • scoprire la localizzazione NUMA della RAM di process
  • kjournald motivi per un utilizzo elevato
  • Sintonizzazione dello stack IPv6 di Linux
  • File system / Opzioni per I / O casuali intenzionali
  • Perché un'applicazione pesante ad alta intensità di disco funziona più velocemente su una SAN che su un disco fisico?
  • Come si può qualificare un server?
  • 3 Solutions collect form web for “MySQL abbassa il valore wait_timeout a un numero inferiore di connessioni aperte”

    Abbassare il valore è piuttosto banale senza un riavvio di mysql

    Diciamo che si desidera ridurre i timeout a 30 secondi

    Innanzitutto, aggiungi questo a my.cnf

     [mysqld] interactive_timeout=30 wait_timeout=30 

    Quindi puoi fare qualcosa di simile

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

    Tutte le connessioni DB dopo questa operazione si distriggersno in 30 secondi

    AVVERTIMENTO

    Assicurati di usare esplicitamente mysql_close. Non mi fido di Apache come molti sviluppatori fanno. Altrimenti, talvolta, c'è una condizione di corsa in cui Apache chiude un collegamento DB ma non informa mysqld e mysqld mantengono la connessione aperta finché non si esaurisce. Ancora peggio, puoi vedere TIME_WAIT più spesso. Scegli i tuoi valori timeout con saggezza.

    AGGIORNAMENTO 2012-11-12 10:10 EDT

    AVVERTIMENTO

    Dopo aver applicato i miei suggerimenti pubblicati, crea uno script chiamato /root/show_mysql_netstat.sh con le seguenti righe:

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

    Quando si esegue questa operazione, si dovrebbe vedere qualcosa del genere:

     [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 

    Se ancora vedete molti TIME_WAITs mysql per un determinato server Web, qui ci sono due passaggi di escalation da intraprendere:

    ESCALAZIONE # 1

    Accedere al server Web offendente e riavviare apache come segue:

     service httpd stop sleep 30 service httpd start 

    Se necessario, fare questo a tutti i server web

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

    ESCALAZIONE # 2

    È ansible forzare il sistema operativo per uccidere TIME_WAITs per mysql o qualsiasi altra applicazione con quanto segue:

     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 

    Questo renderà il timeout di TIME_WAIT in 1 secondo.

    Per dare credito in cui il credito è dovuto …

    • Ho ottenuto questa idea da questo post: Come forzare chiudere una presa in TIME_WAIT?
    • La risposta accettata ha una rappresentazione pittorica quando un TIME_WAIT viene in esistenza.
    • La risposta con l'idea che mi è piaciuta è quella che sto suggerendo .

    Se si ottengono molte connessioni TIME_WAIT sul server MySQL, ciò significa che il server MySQL sta chiudendo la connessione. Il caso più probabile in questo caso sarebbe che un host o più host si trovasse in un elenco di blocchi. È ansible eliminare questa operazione eseguendo:

     mysqladmin flush-hosts 

    Per get un elenco del numero di connessioni che hai per IP:

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

    È anche ansible confermare che questo accade andando in uno dei tuoi clienti che ha problemi a connettere e telnet alla port 3306. Mostrerà un messaggio con qualcosa di simile:

     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. 

    Se hai un sacco di connessioni TIME_WAIT al tuo server MySQL, significa che il codice sta eseguendo molte query al tuo DB e apre / chiude una connessione per each query.

    In questo caso, utilizzare la connettività persistente al server DB utilizzando l'estensione MySQLi.

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

    Se non è ansible utilizzare MySQLi, utilizzare invece il parametro thread_cache_size nella configuration MySQL.

    Suggerimenti per Linux e Windows Server, quali Ubuntu, Centos, Apache, Nginx, Debian e argomenti di rete.