Come uccidere correttamente MySQL?


28

Ho CentOS 64 bit con CPanel installato e utilizzo:

service mysql stop

Mantiene solo i periodi di ticchettio e non sembra mai fermarsi. Nei registri pubblica solo un sacco di:

130303 17:42:38 [Warning] /usr/sbin/mysqld: Forcing close of thread

Nel err.logfile, vedo molti di questi:

[Warning] /usr/sbin/mysqld: Forcing close of thread

Prima era istantaneo. Qualche idea sul perché lo faccia e come risolverlo?

In questo momento devo fare killall -9 mysqlma c'è un modo migliore?

Anche il server è molto molto attivo.

È un problema di configurazione? Le impostazioni della memoria sono troppo alte?

[mysqld]
default-storage-engine=MyISAM
local-infile=0
symbolic-links=0
skip-networking
max_connections = 500
max_user_connections = 20
key_buffer = 512M
myisam_sort_buffer_size = 64M
join_buffer_size = 64M
read_buffer_size = 12M
sort_buffer_size = 12M
read_rnd_buffer_size = 12M
table_cache = 2048
thread_cache_size = 16K
wait_timeout = 30
connect_timeout = 15
tmp_table_size = 64M
max_heap_table_size = 64M
max_allowed_packet = 64M
max_connect_errors = 10
query_cache_limit = 1M
query_cache_size = 64M
query_cache_type = 1
low_priority_updates=1
concurrent_insert=ALWAYS
log-error=/var/log/mysql/error.log
tmpdir=/home/mysqltmp
myisam_repair_threads=4
[mysqld_safe]
open_files_limit = 8192
log-error=/var/log/mysql/error.log

[mysqldump]
quick
max_allowed_packet = 512M

[myisamchk]
key_buffer = 64M
sort_buffer = 64M
read_buffer = 16M
write_buffer = 16M

Risposte:


37

Il modo più semplice per spegnere mysql quando lo fa è semplicemente quello di eseguire

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Ecco perché:

Il file di servizio mysql (/etc/init.d/mysql ) si basa sulla presenza del file socket. Storicamente parlando, risalendo a MySQL 4.0, il file socket a volte scompare inspiegabilmente. Ciò ostacola il funzionamento di uno standard service mysql stop.

Non è abbastanza da dire

mysqladmin -uroot -p -h127.0.0.1 shutdown

perché itinerario mysqld volontà di un utente che entra come root@127.0.0.1a root@localhostse il protocollo TCP / IP non è esplicitamente abilitato. Per impostazione predefinita, mysqld sceglierà il percorso minimo di resistenza e di connettersi root@127.0.0.1alla root@localhosttramite il file di socket. Tuttavia, se non esiste un file socket, root@localhostnon si connetterà mai.

Anche la documentazione MySQL su mysqladmin dice questo:

Se si esegue l'arresto di mysqladmin durante la connessione a un server locale utilizzando un file socket Unix, mysqladmin attende fino alla rimozione del file ID processo del server, per garantire che il server si sia arrestato correttamente.

Ecco perché è indispensabile abilitare TCP / IP:

mysqladmin -uroot -p -h127.0.0.1 --protocol=tcp shutdown

Il 30 settembre 2011, ho scritto la mia versione di mysqld_multichiamata mysqlservice(Vedi il mio post: Esecuzione di più istanze sullo stesso host ). Serve come motore virtuale per la connessione a mysqld da diverse porte. Devi solo portare il tuo my.cnfcon parametri personalizzati. In quello script, eseguo arresti di questo tipo:

stop() {
  ${ECHO} -n $"Stopping ${PROGNAME}"
  ${MYSQLD_STOP}
  ATTEMPTS=0
  STOPPING_MYSQLD=1
  MINUTES_TO_TRY=10
  (( TICKS_TO_TRY = MINUTES_TO_TRY*240 ))
  while [ ${STOPPING_MYSQLD} -eq 1 ]
  do
    ${ECHO} -n "."
    ${SLEEP} 0.25
    MYSQLD_HAS_BEEN_SHUTDOWN=`${TAIL} ${MYSQL_ERROR_LOG} | ${GREP} -c "Shutdown complete$"`
    (( ATTEMPTS++ ))
    if [ ${ATTEMPTS} -eq ${TICKS_TO_TRY}   ] ; then STOPPING_MYSQLD=0 ; fi
    if [ ${MYSQLD_HAS_BEEN_SHUTDOWN} -eq 1 ] ; then STOPPING_MYSQLD=2 ; fi
  done
  ${ECHO}
  if [ ${STOPPING_MYSQLD} -eq 2 ]
  then
    ${ECHO} "Stopped ${PROGNAME}"
  else
    ${TAIL} -30 ${MYSQL_ERROR_LOG}
  fi
}

Ma cos'è ${MYSQLD_STOP}?

MYSQL_CONN="-uroot -p<rootpassword> -P${MYSQLD_PORT} -h127.0.0.1 --protocol=tcp"
MYSQLD_STOP="${MYSQLADMIN} ${MYSQL_CONN} shutdown"

Si prega di notare che uso 127.0.0.1 e una porta esplicita. In questo modo, non sto facendo affidamento su un file socket.

Ho sempre usato mysqladmin --protocol=tcp shtudownl'alternativa corretta agli arresti di mysql se si service mysql stopblocca. Andare kill -9avantimysqld emysqld_safe dovrebbe l'ultimo degli ultimi degli ultimi villaggi. (Sì, ho detto le ultime tre volte).

Molte volte, mysqld ha eliminato mysql.sock senza preavviso. Altre persone hanno avuto questo problema anche nel corso degli anni:

EPILOGO

Il segreto è proprio come ho affermato: connettiti a mysql usando mysqladmin via TCP / IP ( --protocol=tcp) e risolvi il problema shutdown. Questo deve funzionare perché il privilegio di spegnimento è attivomysql.user esclusivamente per gli arresti autenticati. Ciò ha salvato il mio giorno di lavoro un paio di volte quando sono stato in grado di emettere un arresto remoto dal mio computer Windows quando spegnevo mysqld su un server Linux.

AGGIORNAMENTO 2013-03-06 22:48 EST

Se sei preoccupato per quello che sta succedendo durante l'arresto, c'è un modo per manipolare il tempo di spegnimento e il modo in cui i dati vengono scaricati su disco, specialmente se hai molti dati InnoDB nel pool di buffer

SUGGERIMENTO N. 1

Se hai molte pagine sporche, puoi abbassare innodb_max_dirty_pages_pct a 0:

SET GLOBAL innodb_max_dirty_pages_pct = 0;

Impostare questo circa 15-30 minuti prima dell'arresto. Ciò fornirà a mysqld la minor quantità possibile di pagine sporche da scrivere su disco.

SUGGERIMENTO # 2

Per impostazione predefinita, innodb_fast_shutdown è 1. Esistono tre valori per questa opzione

  • 0: InnoDB esegue un arresto lento, un'eliminazione completa e un'unione del buffer di inserimento prima dell'arresto.
  • 1: InnoDB salta queste operazioni allo spegnimento, un processo noto come arresto rapido.
  • 2: InnoDB svuota i suoi log e si spegne a freddo, come se MySQL si fosse bloccato; nessuna transazione impegnata viene persa, ma l'operazione di ripristino in caso di arresto prolungato richiede l'avvio successivo.

La documentazione afferma inoltre che:

L'arresto lento può richiedere minuti o addirittura ore in casi estremi in cui sono ancora bufferate quantità sostanziali di dati. Utilizzare la tecnica di arresto lento prima di eseguire l'aggiornamento o il downgrade tra le versioni principali di MySQL, in modo che tutti i file di dati siano completamente preparati nel caso in cui il processo di aggiornamento aggiorni il formato del file.

Utilizzare innodb_fast_shutdown = 2 in situazioni di emergenza o di risoluzione dei problemi, per ottenere l'arresto assoluto più rapido se i dati sono a rischio di corruzione.

I valori predefiniti per innodb_max_dirty_pages_pct e innodb_fast_shutdown dovrebbero andare bene nella maggior parte dei casi.


2
Il file socket scompare sui derivati ​​Red Hat perché lo tmpwatchelimina, insieme a tutto il resto /tmpche ha un tempo superiore alla soglia configurata.
Michael - sqlbot

Grazie, @ Michael-sqlbot, avevo bisogno di sentirlo da qualcuno, finalmente. Immagino sia per questo che qualcuno di MySQL AB (pre-Oracle, pre-Sun) ha deciso di aggiungere il privilegio SHUTDOWN mysql.userper aggirare il mal di testa in questo modo.
RolandoMySQLDBA

Su Debian o Ubuntu usa mysqladmin --defaults-file=/etc/mysql/debian.cnf shutdown... quel file contiene credenziali per un account MySQL simile a root.
0xC0000022L,

Come al solito, @RolandoMySQLDBA sei una delle migliori risorse DBA sui siti Stack Exchange. Ottimo lavoro qui che mi ha aiutato più di 6 anni dopo.
Jake Gould il

5

Sembra che la tua domanda sia meno su "come" chiudere MySQL e più sul perché la tua si sta spegnendo così lentamente.

Nella mia risposta a una domanda simile , ho offerto alcuni suggerimenti per un riavvio regolare, che aiutano a ridurre la quantità di attività che deve avvenire dopo aver richiesto a MySQL di avviare il processo di spegnimento .

Se non sei un utente frequente di SHOW FULL PROCESSLIST;questo articolo n. 1, perché devi avere un'idea di cosa sta succedendo nel tuo server che sta rendendo l'arresto così lento. Se ci sono query di lunga durata che possono essere interrotte in modo sicuro, puoi eliminarleKILL <thread-id> .

Ricapitolando gli altri suggerimenti:

L'impostazione della variabile globale innodb_fast_shutdown = 1(impostazione predefinita) velocizzerà la parte dell'arresto di InnoDB. Questo è solo sicuro, tuttavia, se si stanno chiudendo il server per motivi estranei alla eseguire un aggiornamento. Se stai chiudendo per un aggiornamento, questo deve essere impostato su 0.

Usando si FLUSH TABLES;chiude con grazia tutte le tabelle aperte. Saranno riaperti se referenziati da query successive, ma questa azione alla fine dovrebbe comunque ridurre il tempo che intercorre tra il momento in cui si richiede l'arresto e il tempo in cui l'arresto è completo, perché esegue alcune pulizie iniziali e, soprattutto, pone le basi per l'ultimo passaggio ...

FLUSH TABLES WITH READ LOCK;chiude tutte le tabelle aperte e ottiene un blocco esclusivo di proprietà della connessione client corrente che impedisce a qualsiasi altra connessione di scrivere su qualsiasi tabella dell'intero server. Non riceverai il tuo mysql>prompt fino a quando non sarai il proprietario di questo blocco, a quel punto puoi emettere la richiesta di arresto, ma non disconnetterti da questa sessione.

Su un server occupato, questi passaggi dovrebbero ridurre il livello di attività sul server, rendere le cose molto più silenziose e contribuire a rendere più fluido l'arresto o il riavvio.


2

È probabile che MySQL non sia semplicemente bloccato, ma sta eseguendo attività di pulizia (rollback, ecc.) Durante lo spegnimento. Se non lo lasci fare tutto questo allo spegnimento, spesso dovrai aspettare all'avvio.

Ecco qualcosa da guardare: spegni mysql in una finestra del terminale mentre guardi il registro degli errori (tail -f [yourerror.log]) in un'altra finestra del terminale. Il registro degli errori ti mostrerà cosa sta facendo MySQL.


1

Mi dispiace conoscere la tua esperienza e spero che la mia esperienza con stupidi scenari MySQL, simili a questo, possa aiutarti.

Invece di provare a capire come eliminare il servizio MySQL dal server, in alcuni casi, dovrai verificare lo stato del tuo sistema attraverso quanto segue per determinare se c'è un abuso del servizio (il presupposto si basa sulla nozione di un Ambiente CentOS / RHEL ):

 /usr/bin/iostat
 /usr/bin/uptime
 top -c

Utilizzare quanto segue per identificare il carico medio del sistema e le risorse che consumano maggiormente all'interno del sistema.

Sarà inoltre necessario installare mytopper ottenere una visione d'insieme delle istruzioni SQL che vengono elaborate dal sistema.

Per installare mytop, eseguire semplicemente le seguenti operazioni:

 cd /root
 wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
 tar -zxvf /root/mytop-1.6.tar.gz
 cd /root/mytop-1.6
 perl Makefile.pl
 make
 make install
 chmod 644 /usr/local/bin/mytop
 vi /usr/local/bin/mytop 

(usa qualsiasi editor di testo che preferisci)

Cerca "long|!" => \$config{long_nums},

Commentalo come #"long|!" => \$config{long_nums},

chmod 555 /usr/local/bin/mytop

E tu sei bravo ad andare con mytop . Usalo per controllare le dichiarazioni di MySQL che controllano il tuo servizio MySQL e fermarle.

L'esecuzione delle istruzioni sopra ti fornirà le seguenti capacità:

  • Diagnosi dello stato / dell'integrità del server
  • Diagnosi della causa della strozzatura

Dopo aver eliminato la causa del collo di bottiglia, si dovrebbe avere una giornata più facile quando si tenta di riavviare il servizio MySQL. Spero che troverai utili le informazioni di cui sopra.

Nota: mytop è antico e non mantenuto. Probabilmente dovresti usarlo innotopsu un sistema moderno.


0

L'implementazione standard dello script di init di MySQL segnala MySQL con SIGTERM e attende un certo periodo di tempo per lo spegnimento di MySQL.

MySQL, dopo aver ricevuto un SIGTERM, interromperà innanzitutto la ricezione di nuove connessioni, quindi completerà l'esecuzione di tutte le query ancora in sospeso (ciò può richiedere del tempo, a seconda del carico di lavoro e del numero di client simultanei), quindi inizia a scaricare i dati sul disco (ciò può richiedere molto tempo, sempre a seconda del carico di lavoro, delle configurazioni, della memoria disponibile e delle scelte del motore di archiviazione). Dopo aver eseguito il flushing dei dati, MySQL trasferirà quindi la memoria allocata durante la fase di inizializzazione (ciò può anche richiedere del tempo, a seconda della quantità di memoria allocata da MySQL), chiudere tutti gli handle di file ancora aperti e quindi chiamare "exit (0)".

Se dopo la richiesta di arresto MySQL impiega molto tempo a spegnersi, è possibile che uno o più di questi stadi richiedano molto tempo per essere completati. Se hai tempo, ti consiglio vivamente di attendere il completamento del processo (questo eviterà la perdita di dati o lunghi processi di recupero quando riavvii di nuovo l'istanza del database).

Purtroppo non ci sono abbastanza informazioni nella tua domanda per consentirmi di suggerire una soluzione adeguata al tuo problema. Spero che questo aiuti a capire il problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.