Esiste un riavvio grazioso o sicuro per mysql come per apache httpd?


29

Vorrei riavviare mysql con grazia, proprio come httpd, dove i thread vengono serviti prima del riavvio. Non mi piacerebbe interrompere le query.

Risposte:


37

Qualsiasi sequenza di arresto "richiesta" in MySQL (a corto di kill -9) è in qualche modo aggraziata , poiché le transazioni in corso (sulle tabelle transazionali) vengono ripristinate, ma qui ci sono un paio di modi per rendere il riavvio il più pulito possibile.

Nota: se si sta spegnendo il server per un aggiornamento, non utilizzare questo processo; segui invece la procedura dettagliata in questa risposta .

Altrimenti, se stai semplicemente riavviando un server altrimenti integro in modo da poter modificare una variabile globale di sola lettura o qualcosa di simile, ecco un percorso grazioso:

Innanzitutto, abilita innodb_fast_shutdownse non lo è già. Questo non è direttamente correlato alla grazia dell'arresto, ma dovrebbe riportare il tuo server più velocemente.

mysql> SHOW VARIABLES LIKE 'innodb_fast_shutdown';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| innodb_fast_shutdown | 0     |
+----------------------+-------+
1 row in set (0.00 sec)

mysql> SET GLOBAL innodb_fast_shutdown = 1;
Query OK, 0 rows affected (0.01 sec)

Quindi, indicare al server di chiudere tutte le tabelle aperte non appena nessuna query attualmente in esecuzione le fa riferimento. Questo passaggio non ha nulla a che fare con l'arresto grazioso, ma renderà il passaggio successivo più veloce:

mysql> FLUSH LOCAL TABLES;
Query OK, 0 rows affected (41.12 sec)

L' FLUSH TABLESistruzione (con la LOCALparola chiave facoltativa , che evita lo svuotamento inutile ma altrimenti innocuo di tutti gli slave) verrà bloccata e il prompt non tornerà fino a quando tutte le tabelle non possono essere chiuse. Una volta che ogni tabella è stata "svuotata" (chiusa), se una query fa successivamente riferimento alla tabella, verrà automaticamente riaperta, ma va bene. Ciò che stiamo realizzando con questo passaggio è rendere meno lavoro per il passaggio finale:

mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (13.74 sec)

mysql>

Questa affermazione elimina tutte le tabelle (quindi il vantaggio di toglierne alcune in modo meno distruttivo con il passaggio precedente) e acquisisce un blocco globale (a livello di server) di sola lettura su di esse.

Non è possibile avere un blocco di lettura globale fino a quando non viene eseguita ogni query di "scrittura" attualmente in esecuzione (ovvero praticamente tutto ma SELECT). L'emissione della richiesta di blocco consentirà il completamento delle query esistenti ma non consentirà l'avvio di nuove.

Il tuo prompt non ritorna fino a quando non mantieni questo blocco globale, quindi ogni query che è in corso quando richiedi il blocco è in grado di terminare e sai che sono finiti, perché ricevi il prompt. Qualsiasi query successiva che tenta di scrivere qualsiasi cosa su qualsiasi tabella si bloccherà, non modificherà i dati, attenderà indefinitamente il blocco, fino a quando ...

  • cambi idea sul riavvio e rilasci manualmente il blocco ( UNLOCK TABLES;)
  • si riavvia il server o
  • disconnetti accidentalmente o intenzionalmente il client della riga di comando da questo thread (quindi non farlo). Tieni questa finestra connessa e seduta al prompt di mysql:

Resistere alla tentazione di chiudere questo.

mysql>

Questo prompt della console inattiva è ciò che detiene il blocco globale per te. Perdi questo, perdi il lucchetto.

Da un'altra finestra della console, riavvia MySQL come faresti normalmente, con initscripts (ad esempio, la tua variante locale di service mysql.server restart) o con mysqladmin shutdownseguito da un riavvio manuale.


L'utilizzo innodb_fast_shutdown = 1garantisce davvero che MySQL si avvii più velocemente? Guardando i documenti, sembra che questo migliora la velocità di spegnimento (a scapito della velocità di avvio?).
Chris,

L'idea di @Chris è che aiuta a garantire che l'intero arresto + avvio sia rapido quanto pratico, ma è un po 'aneddotico poiché la quantità di lavoro svolto è teoricamente la stessa - appena spostata dall'altra parte della sequenza - eppure per qualche ragione, nel complesso è sempre sembrato più veloce, come forse c'è qualche inefficienza nel modo in cui si verifica allo spegnimento che non è presente all'avvio. Difficile da dire.
Michael - sqlbot,

2

In breve, alcune delle migliori pratiche da considerare prima di chiudere MySQL sono:

  1. Conferma l'istanza che stai per chiudere per evitare di arrestare un'altra istanza per errore.
  2. Interrompere la replica se si intende arrestare uno slave mysql> STOP SLAVE;.
  3. Lavare in anticipo le pagine sporche per ridurre i tempi di spegnimento mysql> SET GLOBAL innodb_max_dirty_pages_pct = 0;.
  4. Controlla le query a esecuzione prolungata mysql> SHOW PROCESSLIST;, uccidile mysql> kill thread_id;o attendi il completamento.
  5. Scaricare il pool buffer all'arresto mysql> SET GLOBAL innodb_buffer_pool_dump_at_shutdown = ON;e ricaricarlo all'avvio # vi /etc/my.cnf innodb_buffer_pool_load_at_startup = ON per riscaldare il pool buffer.

Quindi, dopo aver confermato i punti precedenti, è possibile riavviare MySQL in sicurezza shell$ service mysql restart

Per maggiori dettagli, vedi il mio post Controlla questi prima di chiudere MySQL!


Perché questo è stato downvoted? Non so abbastanza per riconoscere quali comandi sono cattivi, ma voglio sapere in modo da poterli evitare.
Jon,

Non so che nessuna delle precedenti sia un cattivo comando. Sto seguendo i passaggi precedenti e così tante persone. Solo il passaggio 4 dovrebbe essere con cautela, non dovresti uccidere alcuna query fino a quando non sei sicuro di ciò che stai facendo, altrimenti attendi il completamento delle query a esecuzione prolungata. Provalo e se ti ha aiutato, votalo, se no, votalo!
Moll,
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.