Mai riavviare un mistero: cosa catturare prima di un restart
Un restart cancella il sintomo e, con esso, le prove. Su un sistema stateful, i cinque minuti spesi a catturare lo stato prima decidono se i dati sopravvivono.
In questo articolo 6 sezioni
- Riavviare un servizio stateless è una correzione. Riavviare un servizio stateful prima di conoscere la causa è un esperimento condotto sui vostri dati, e un arresto non pulito è il meccanismo con cui alcuni table engine si corrompono.
- Un reboot cancella lo stato dei processi, i proprietari dei socket, il ring buffer del kernel e la distinzione tra un crash e un avvio fallito. Catturateli prima: richiede minuti.
- Snapshot prima della riparazione, riparazione prima del restore, e verifica al confine che ha ceduto, non a «il servizio è su».
Dove il riflesso è giusto, e dove non lo è
Spegnere e riaccendere funziona su un web worker incastrato, su un consumer di coda bloccato, su un laptop. Lo stato sbagliato viene scartato e ricostruito dal nulla, perché nulla di valore ci viveva dentro. Database, message broker, daemon di storage e qualsiasi cosa con un write-ahead log sono il caso opposto. Lo stato è il prodotto. Un restart non scarta lo stato cattivo: scarta l'informazione su come è diventato cattivo, e su alcuni engine aggiunge danni propri.
Cosa cancella un restart
La tabella dei processi e i suoi tempi: quale processo gira da quando, quale è in uninterruptible sleep e su cosa. Il proprietario di ogni socket e file handle aperto, che vi dice chi teneva il lock o la porta. Il ring buffer del kernel, che in un'installazione predefinita non sopravvive a un reboot ed è dove un out-of-memory kill, un errore del filesystem o un disco che sta cedendo si annunciano. Il contenuto della memoria del servizio, che un core dump può conservare e un restart no. La cronologia di arresto e avvio che separa un crash da un avvio fallito. E su un table engine senza crash recovery, l'arresto non pulito stesso è il modo in cui un header dell'indice si danneggia, quindi il restart che doveva sistemare il servizio può essere l'evento che corrompe le tabelle.
Il kit delle prove, in minuti
Tutto ciò che segue è in sola lettura. Eseguitelo da una shell sulla macchina, redirigete l'output in un file con timestamp e copiate quel file fuori dalla macchina prima che qualcuno tocchi qualsiasi altra cosa.
$ uptime; last -x | head -20; journalctl --list-boots | tail -3
$ dmesg -T | tail -200
$ ps -eo pid,ppid,stat,etime,wchan:24,cmd --sort=-etime | head -60
$ ss -tnp state established | head -100
$ free -m; df -h; df -i
$ vmstat 1 5
$ top -b -n 1 | head -40Per un database, aggiungete la visione che l'engine ha di sé stesso finché risponde ancora, e la coda del suo error log, che risponda o no.
mysql> SHOW FULL PROCESSLIST;
mysql> SHOW ENGINE INNODB STATUS\G
mysql> SHOW GLOBAL STATUS LIKE 'Threads_%';
$ tail -500 /var/log/mariadb/mariadb.logIl primo blocco risponde se la macchina ha già fatto reboot, se il kernel ha ucciso qualcosa, cosa è bloccato e su cosa, chi tiene quale connessione, e se la macchina è sotto pressione di memoria o di I/O. Il secondo risponde a cosa il database pensa stia succedendo: una transazione lunga che tiene dei lock, un thread di replica fermo, un deadlock, una tabella segnalata come crashed.
Crash, o avvio fallito
La distinzione più utile nel log è tra un servizio che è andato in crash e un servizio che si è arrestato in modo pulito e poi non è riuscito a ripartire. Il primo richiede che il trigger venga trovato prima di riavviare qualsiasi cosa, perché riavviare dentro un trigger ancora attivo riproduce il crash. Il secondo è un problema di avvio o di policy: una configurazione cambiata, un disco pieno, un permesso, una unit non abilitata. Nel secondo caso i dati non sono a rischio, e trattarlo come un crash spreca il tempo che avrebbe riportato su il servizio. La coda del log del servizio mostra quale dei due è: una riga di arresto completato seguita da un abort all'avvio è il secondo caso.
Il percorso reversibile
Una volta noto il trigger, la sequenza è la stessa su ogni sistema stateful. Fermate il trigger, così la correzione non può essere annullata da un altro crash a metà del recupero. Fate lo snapshot gratuito: fermate le scritture, rinominate la directory dei dati da parte o fate lo snapshot del volume, e tenete una copia fuori dalla macchina. Da quel punto ogni passo può essere invertito. Riparate prima di fare il restore, perché un backup trasporta fedelmente qualunque cosa il sistema trasportasse quando è stato fatto, e se il difetto è entrato insieme ai dati, il restore lo ripianta scartando tutto ciò che è stato scritto da allora. Verificate al confine che ha ceduto: la query che è andata in abort, la tabella che riportava zero righe, la posizione della replica, non semplicemente che la porta è aperta. Applicate il tuning pianificato solo dopo che il paziente è sano: recupero e cambiamento sono due operazioni diverse.
| Il riflesso | Cosa succede davvero |
|---|---|
| Riavviare il servizio | Con il trigger ancora attivo va di nuovo in crash, e il secondo arresto è non pulito quanto il primo |
| Restore da ieri sera | Tutto ciò che è stato scritto da ieri sera è perso, e un difetto entrato insieme ai dati viene ripristinato con essi |
| Aggiungere memoria, sembra memoria | Se l'abort è software che percorre metadati danneggiati, l'hardware non cambia nulla |
| È andato in crash, quindi qualcosa è rotto | Un arresto pulito seguito da un avvio fallito è un problema di restart senza dati a rischio |
Un conteggio di righe azzerato dopo un hard reboot è di solito un indice danneggiato sopra righe intatte. Sugli engine senza crash recovery, una riparazione ricostruisce l'indice dai dati; un restore butta via i dati.
La cura, distinta dal recupero
Una riparazione è recupero. La cura è rimuovere ciò che causa arresti non puliti, e convertire le tabelle che non ne reggono uno a un engine che lo regge. Entrambe appartengono al follow-up, non all'emergenza.
Risposte dirette
Devo riavviare il mio database andato in crash?+
Non finché il log non vi ha detto se è andato in crash o non è riuscito ad avviarsi, e quale era il trigger. Riavviare dentro un trigger attivo riproduce il crash e, su un engine non crash-safe, può danneggiare le tabelle. Catturate in sola lettura prima, poi decidete.
La mia tabella mostra zero righe dopo un crash. I dati sono persi?+
Spesso no. Sui table engine senza crash recovery, un arresto non pulito danneggia l'header dell'indice mentre le righe restano su disco, e l'engine riporta il conteggio dall'header. Fate lo snapshot della directory dei dati, poi eseguite la riparazione dell'engine; una riparazione di norma ricostruisce l'indice dalle righe ancora presenti. Restore solo se la riparazione fallisce.
Il restore da backup è il recupero più sicuro?+
Di solito è il più distruttivo. Tutto ciò che è stato scritto dopo il backup viene scartato, e se il difetto era già nei dati quando il backup è stato eseguito, torna con esso. Il restore è l'ultimo passo dopo la diagnosi e la riparazione.
Cosa va catturato prima che qualcuno riavvii qualsiasi cosa?+
La tabella dei processi con i tempi, i proprietari dei socket aperti, il ring buffer del kernel, la pressione di memoria e di I/O, l'uso di disco e inode, la cronologia dei boot, e lo stato e l'error log del servizio stesso. Scritti in un file e copiati fuori dalla macchina. Richiede minuti, ed è l'unica copia di quelle prove che avrete.
Siete giù in questo momento, con il dito sul pulsante di restart?
Parlate con un ingegnere: diagnostichiamo in sola lettura prima e facciamo lo snapshot prima di qualsiasi cosa che scriva.
Parla con un ingegnereSiete arrivati alla fine.
Mettete la lettura al lavoro
Cosa fate girare?
Raccontateci il carico di lavoro, il traffico e i requisiti di ripristino. Partite dal configuratore di server, oppure discutete i dettagli con un ingegnere.
Scritto dagli ingegneri che costruiscono e gestiscono l'infrastruttura che descrive.Parla con un ingegnere
