Ripristino del backup fallito, sidekiq non si ferma e poi va fuori controllo

Ho eseguito un rebuild stamattina e poi ho provato a ripristinare un backup nel container. Sono sulla versione 2.6.0.beta5 (75a893fd61), con tutto all’interno del container.

Il ripristino del backup di solito funziona (cioè lo ha fatto in passato), ma oggi è fallito in questo modo:

Starting restore: app-2020-11-06-033740-v20201009190955.tar.gz
[STARTED]
'system' ha avviato il ripristino!
Marcatura del ripristino come in corso...
Verifica che /var/www/discourse/tmp/restores/default/2020-11-06-084354 esista...
Copia dell'archivio nella directory tmp...
Decompressione dell'archivio, potrebbe richiedere del tempo...
Estrazione del file dump...
Validazione dei metadati...
  Versione corrente: 20201103103401
  Versione ripristinata: 20201009190955
Attivazione della modalità sola lettura...
Sospensione di Sidekiq...
Attesa fino a 60 secondi affinché Sidekiq termini l'esecuzione dei lavori...
Attesa che Sidekiq termini l'esecuzione dei lavori... #2
Attesa che Sidekiq termini l'esecuzione dei lavori... #3
Attesa che Sidekiq termini l'esecuzione dei lavori... #4
Attesa che Sidekiq termini l'esecuzione dei lavori... #5
Attesa che Sidekiq termini l'esecuzione dei lavori... #6
Attesa che Sidekiq termini l'esecuzione dei lavori... #7
Attesa che Sidekiq termini l'esecuzione dei lavori... #8
Attesa che Sidekiq termini l'esecuzione dei lavori... #9
Attesa che Sidekiq termini l'esecuzione dei lavori... #10
ECCEZIONE: Sidekiq non ha terminato l'esecuzione di tutti i lavori nel tempo consentito!
/var/www/discourse/lib/backup_restore/system_interface.rb:89:in `block in wait_for_sidekiq'
/var/www/discourse/lib/backup_restore/system_interface.rb:84:in `loop'
/var/www/discourse/lib/backup_restore/system_interface.rb:84:in `wait_for_sidekiq'
/var/www/discourse/lib/backup_restore/restorer.rb:47:in `run'
script/discourse:143:in `restore'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/command.rb:27:in `run'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/invocation.rb:127:in `invoke_command'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor.rb:392:in `dispatch'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/thor-1.0.1/lib/thor/base.rb:485:in `start'
script/discourse:284:in `<top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:63:in `kernel_load'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:476:in `exec'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor.rb:399:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:30:in `dispatch'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/vendor/thor/lib/thor/base.rb:476:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/cli.rb:24:in `start'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:46:in `block in <top (required)>'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/lib/bundler/friendly_errors.rb:123:in `with_friendly_errors'
/usr/local/lib/ruby/gems/2.6.0/gems/bundler-2.1.4/exe/bundle:34:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tentativo di rollback...
Non è stato necessario eseguire un rollback
Pulizia dei file...
Rimozione della directory tmp '/var/www/discourse/tmp/restores/default/2020-11-06-084354'...
Riattivazione di Sidekiq...
Disattivazione della modalità sola lettura...
Marcatura del ripristino come completato...
Notifica a 'system' della fine del ripristino...
Completato!
[FAILED]
Ripristino eseguito.

Dopo questo, ho un processo Ruby che utilizza il 100% della CPU da ore. Questo processo è descritto come:

# ps aux | grep sidekiq
discour+    141  100  5.0 9302596 401484 ?      SNl  06:34 127:46 sidekiq 6.1.2 discourse [5 of 5 busy]

Se arresto e riavvio il container, questo Sidekiq torna al 100%. sidekiq.log è vuoto, production.log non mi mostra molto.

Come posso scoprire cosa sta facendo questo Sidekiq? Qualcun altro ha riscontrato problemi con il ripristino dei backup su questa versione?

Un gentile signore mi ha indicato la console di Sidekiq e sembra che Sidekiq sia impegnato nella generazione delle miniature:

I backup che utilizzo non includono le miniature, quindi questo potrebbe essere previsto; tuttavia, avevo già eseguito rake posts:rebake e successivamente rake posts:rebake_uncooked_posts dopo il ripristino del backup di test precedente, quindi pensavo che ciò avrebbe completato tutta la generazione delle miniature (il rebake ha richiesto circa 1 ora per circa 100.000 post, mentre rebake_uncooked non ha fatto nulla, presumibilmente perché il rebake completo aveva già gestito tutto).

Supponendo che questo carico di lavoro sia ciò che impedisce il successo del backup, non dovrebbe il ripristino di un backup prima di tutto svuotare le code dei task?

Inoltre, perché Sidekiq sta generando miniature quando apparentemente non c’è nulla da fare, o i comandi rebake si limitano a mettere in coda il lavoro?

# rake posts:rebake_uncooked_posts
Rigenerazione dei post non cotti su default

0 post elaborati!

Esatto. La ricottura mette in coda un sacco di cose invece di eseguirle tutte immediatamente.

Probabilmente sì. Ma si dà per scontato che, se sai abbastanza da ripristinare un backup, sappia anche come pulire prima la coda di Sidekiq; di solito si ripristina su un sito vuoto.

Credo che sia così.

Grazie, ora sta iniziando a avere molto più senso.

Quindi la sequenza corretta sarebbe prima distruggere, poi (ri)costruire il contenitore, quindi entrarci e ripristinare il backup?

Se è così, ottimo, anche se forse Discourse potrebbe fornire quell’indicazione/avviso quando si avvia un ripristino in un contenitore non vuoto.

Quella è l’opzione nucleare (e probabilmente ti basterebbe solo cancellare i dati di Redis e poi ricostruire). Di solito, non hai un numero enorme di job in esecuzione e non è un problema. Ma dato che apparentemente stai eseguendo due ripristini di fila e il primo non è ancora completamente terminato quando ne avvii un altro, sei un caso particolare.

L’altra cosa da fare sarebbe andare su /sidekiq e cancellare tutti i job in coda. Ci vogliono solo pochi clic.

Allora è un buon test per il ripristino di emergenza :smiley:

Hai ragione, probabilmente è un caso piuttosto particolare. Stavo cercando di ridurre il tempo di rigenerazione, quindi sto ripristinando i backup e misurando i tempi in diverse condizioni (il ripristino senza miniature richiede in genere 2-3 giorni per completare la rigenerazione!). Tutto questo è una premessa per una migrazione del sito.

Penso di aver capito molto di più ora, grazie. Ma per qualcosa di critico come i backup, ritengo che sarebbe sensato che Discourse garantisca la massima affidabilità possibile (ad esempio, svuotando le code di Sidekiq prima di iniziare) o emetta avvisi chiari se rileva potenziali problemi per il ripristino, indicando quali ulteriori passaggi sono necessari.

Solo chi sa che bisogna farlo.

Ti suggerisco di creare un backup con le miniature (impostazione del sito include_thumbnails_in_backups) quando desideri migrare su un server diverso.

Grazie! Anche io ho provato questa opzione, ma il backup, pur essendo di circa 6 GB in più, richiede circa un’ora in più per essere creato. Sembra che sia la fase di tar a richiedere più tempo: forse sul mio hardware più vecchio l’accesso a molti file piccoli è lento. Il livello di gzip è impostato a 1, quindi penso che il collo di bottiglia sia l’I/O e non la CPU. Il nuovo host riesce a eseguire lo stesso backup in 30-40 minuti.

Forse sto solo un po’ perdendo la pazienza in questo caso e dovrei accettare che il backup richieda più tempo, anche se, dato che il sito principale è in modalità sola lettura durante questo processo, tengo molto a ridurre al minimo tale durata.