Fallo en la restauración de copia de seguridad, sidekiq no se detiene y luego se descontrola

Hice una reconstrucción esta mañana y luego intenté restaurar una copia de seguridad en el contenedor. Estoy en la versión 2.6.0.beta5 (75a893fd61), con todo dentro del contenedor.

Normalmente la restauración de la copia de seguridad funcionaría (de hecho ya lo ha hecho antes), pero hoy falló de la siguiente manera:

Starting restore: app-2020-11-06-033740-v20201009190955.tar.gz
[STARTED]
'system' ha iniciado la restauración.
Marcando la restauración como en curso...
Asegurando que /var/www/discourse/tmp/restores/default/2020-11-06-084354 existe...
Copiando el archivo comprimido al directorio temporal...
Descomprimiendo el archivo comprimido, esto puede tardar un rato...
Extrayendo el archivo volcado...
Validando los metadatos...
  Versión actual: 20201103103401
  Versión restaurada: 20201009190955
Habilitando el modo de solo lectura...
Pausando Sidekiq...
Esperando hasta 60 segundos a que Sidekiq termine de ejecutar los trabajos...
Esperando a que Sidekiq termine de ejecutar los trabajos... #2
Esperando a que Sidekiq termine de ejecutar los trabajos... #3
Esperando a que Sidekiq termine de ejecutar los trabajos... #4
Esperando a que Sidekiq termine de ejecutar los trabajos... #5
Esperando a que Sidekiq termine de ejecutar los trabajos... #6
Esperando a que Sidekiq termine de ejecutar los trabajos... #7
Esperando a que Sidekiq termine de ejecutar los trabajos... #8
Esperando a que Sidekiq termine de ejecutar los trabajos... #9
Esperando a que Sidekiq termine de ejecutar los trabajos... #10
EXCEPCIÓN: ¡Sidekiq no terminó de ejecutar todos los trabajos en el tiempo permitido!
/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>'
Intentando revertir...
No fue necesario revertir
Limpieza de archivos...
Eliminando el directorio temporal '/var/www/discourse/tmp/restores/default/2020-11-06-084354'...
Reanudando Sidekiq...
Deshabilitando el modo de solo lectura...
Marcando la restauración como finalizada...
Notificando a 'system' sobre el fin de la restauración...
¡Finalizado!
[FALLÓ]
Restauración completada.

Después de eso, tengo procesos de Ruby usando el 100% de la CPU durante horas. Este proceso se describe así:

# 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]

Si detengo y reinicio el contenedor, este Sidekiq vuelve al 100%. sidekiq.log está vacío y production.log no me muestra mucho.

¿Cómo puedo averiguar qué está haciendo este Sidekiq? ¿Alguien más ha encontrado problemas con la restauración de copias de seguridad en esta versión?

Un amable caballero me señaló la consola de Sidekiq y parece que Sidekiq está ocupado generando miniaturas:

Las copias de seguridad que utilizo no incluyen miniaturas, así que esto podría ser esperado, excepto que ya había ejecutado rake posts:rebake y luego rake posts:rebake_uncooked_posts después de la restauración previa de la copia de seguridad de prueba, por lo que pensé que eso habría realizado toda la generación de miniaturas (el rebake tomó aproximadamente 1 hora para algo como 100,000 publicaciones; el rebake_uncooked no hizo nada, ya que supongo que el rebake completo se encargó de todo).

Asumiendo que esta carga de trabajo es lo que impide que la copia de seguridad tenga éxito, ¿no debería restaurar una copia de seguridad primero para purgar las colas de tareas?

Además, ¿por qué Sidekiq está generando miniaturas cuando aparentemente no hay nada que hacer, o los comandos de rebake simplemente ponen el trabajo en cola?

# rake posts:rebake_uncooked_posts
Rebaking uncooked posts on default

0 posts done!

Eso es correcto. La regeneración (rebake) pone en cola un montón de cosas en lugar de ejecutarlas todas de inmediato.

Probablemente. Pero generalmente se asume que si sabes lo suficiente para restaurar una copia de seguridad, también sabes lo suficiente para limpiar primero la cola de Sidekiq; usualmente restaurarías en un sitio que estaba vacío.

Creo que ese es el caso.

Gracias, esto empieza a tener mucho más sentido.

Entonces, ¿la secuencia correcta sería destruir primero, luego (re)crear el contenedor, entrar en él y restaurar la copia de seguridad?

Si es así, genial, aunque quizás Discourse podría ofrecer esa pista o advertencia al iniciar una restauración en un contenedor que no está vacío.

Esa es la opción nuclear (y supongo que solo necesitarías borrar los datos de Redis y luego reconstruir). Por lo general, no tienes un millón de trabajos en ejecución y simplemente no es un problema. Pero como aparentemente estás realizando dos restauraciones seguidas y la primera no ha terminado del todo cuando inicias la segunda, eres un caso especial.

La otra opción sería ir a /sidekiq y eliminar todos esos trabajos en cola. Solo toma unos pocos clics.

Entonces, una buena prueba para la recuperación ante desastres :smiley:

Tienes razón, probablemente sea un caso un poco especial. He estado intentando reducir el tiempo de regeneración, así que estoy restaurando copias de seguridad y midiendo el tiempo en diferentes circunstancias (¡restaurar sin miniaturas tarda de 2 a 3 días en completar la regeneración por defecto!). Todo esto es trabajo preliminar para una migración del sitio.

Creo que ahora entiendo mucho más, gracias. Pero para algo tan crítico como las copias de seguridad, creo que sería sensato que Discourse se asegurara de que sea lo más fiable posible (por ejemplo, purgar las colas de Sidekiq antes de iniciar) o emitir advertencias claras de que se necesitan otros pasos si detecta problemas potenciales para la restauración.

Solo tú sabes cuál es ese clic.

Te sugiero crear una copia de seguridad con miniaturas (configuración del sitio include_thumbnails_in_backups) cuando quieras migrar a un servidor diferente.

¡Gracias! Esta es una opción que también he probado, pero la copia de seguridad, aunque solo ocupa unos 6 GB adicionales, tarda aproximadamente una hora más en crearse. Parece que el paso de tar es el que consume el tiempo; quizás en mi hardware más antiguo, el acceso a muchos archivos pequeños sea lento. El nivel de compresión gzip está configurado en 1, así que creo que el cuello de botella es la entrada/salida y no la CPU. El nuevo servidor puede realizar la misma copia de seguridad en 30-40 minutos.

Posiblemente solo estoy siendo un poco impaciente con esto y debería aceptar que la copia de seguridad tarde más, aunque, dado que el sitio principal queda en modo de solo lectura durante este proceso, tengo mucho interés en minimizar ese tiempo.