Actualización 2.6.0b2 MUY lenta

Solo un aviso para todos: no intenten esta actualización en horario pico.

La actualización 2.6.0b2 lleva más de 40 minutos ejecutándose en nuestro servidor, cuando normalmente solo toma un par de minutos, usualmente termina antes de que vuelvas a revisarla. Me preocupé de que estuviera rota, pero al iniciar sesión en PostgreSQL puedo ver una actualización masiva en ejecución; parece que está modificando los datos de búsqueda de posts para mensajes privados.

Espero que no esté rota. Supongo que lo sabré pronto. Realmente no quiero detenerla ni reiniciar el contenedor en medio de la actualización.

Consulta en ejecución:

postgres=# SELECT pid, age(clock_timestamp(), query_start), usename, query 
FROM pg_stat_activity 
WHERE query != '<IDLE>' AND query NOT ILIKE '%pg_stat_activity%' 
ORDER BY query_start desc;
  pid  |       age       |  usename  |                                            query                          
                   
-------+-----------------+-----------+---------------------------------------------------------------------------
-------------------
   698 |                 |           | 
   701 |                 | postgres  | 
   699 |                 |           | 
   697 |                 |           | 
   696 |                 |           | 
 14572 | 00:10:31.484201 | discourse | UPDATE post_search_data                                                   
                  +
       |                 |           | SET private_message = X.private_message                                   
                  +
       |                 |           | FROM                                                                      
                  +
       |                 |           | (                                                                         
                  +
       |                 |           |   SELECT post_id,                                                         
                  +
       |                 |           |     CASE WHEN t.archetype = 'private_message' THEN TRUE ELSE FALSE END pri
vate_message      +
       |                 |           |   FROM posts p                                                            
                  +
       |                 |           |   JOIN post_search_data pd ON pd.post_id = p.id                           
                  +
       |                 |           |   JOIN topics t ON t.id = p.topic_id                                      
                  +
       |                 |           |   WHERE pd.private_message IS NULL OR                                     
                  +
       |                 |           |     pd.private_message <> CASE WHEN t.archetype = 'private_message' THEN T
RUE ELSE FALSE END+
       |                 |           |   LIMIT 3000000                                                           
                  +
       |                 |           | ) X                                                                       
                  +
       |                 |           | WHERE X.post_id = post_search_data.post_id                                
                  +
       |                 |           | 
 14573 | 00:47:02.814489 | discourse | SELECT pg_try_advisory_lock(2859260972035668690)
(7 filas)

La actualización acaba de finalizar con éxito justo cuando mi pánico alcanzó su punto máximo. Buenos momentos, buenos momentos.

La actualización fue bastante lenta para mí, incluso en hardware colocalizado de alto rendimiento. No estoy completamente seguro de por qué, pero definitivamente es algo a tener en cuenta.

Sí, sugiero añadir una nota en el registro de cambios advirtiendo a los usuarios que esta actualización probablemente tomará mucho más tiempo que la mayoría y que no deben cerrarla ni realizar acciones drásticas, ya que eso es esperado.

@Wingtip ¿Puedo verificar la cantidad de publicaciones que tienes en tu foro? Lamentablemente, esto será lento en sitios con un gran número de publicaciones.

Sí, tenemos más de 5 millones.

Mi sitio local no tenía tantas publicaciones y aun así era bastante lento. No lento 40 minutos, pero notablemente más lento que las actualizaciones anteriores, quizás de 3 a 4 veces.

Solo para dar contexto:

Acabo de reconstruir y ahora estoy ejecutando 2.6.0.beta2 ( 2aa1482421 )

El proceso de construcción no fue notablemente más lento en nuestro servidor.

Gracias @Wingtip, ¡pensé que solo nos estaba pasando a nosotros!

En realidad, tuve que cancelar la reconstrucción y reiniciar la aplicación porque pensé que se había quedado atascada en esa consulta que mencionas. Tenemos 6 millones de publicaciones y, después de unos 45 minutos, aún no había terminado, así que supongo que tendré que estar preparado para al menos una hora de reconstrucción y avisar a nuestros usuarios antes de que comience.

Se ha añadido una nota sobre el tiempo extendido del Administrador de Docker y/o la reconstrucción a través de SSH a las notas de la versión.

Acabo de sacar un cronómetro y probar una reconstrucción (sitio con alrededor de 1 millón de publicaciones) de la versión 2.6.0b1 a b2; y de principio a fin, tardó 170 segundos.

Esta es mi segunda reconstrucción hoy, pasando de b1 a b2, y parece muy bien, sin diferencias notables en la velocidad de construcción.

Nota: Siempre actualizamos desde la línea de comandos y no utilizamos la interfaz de usuario.

Tampoco uso el gestor de Docker y prefiero usar la reconstrucción desde la línea de comandos. Es mejor así para ver el registro por si algo sale mal. También creo que es más rápido.

Sí, parece que es principalmente un problema en los foros con muchas publicaciones.

Estúpida y temerariamente, actualicé a través de la consola web, por lo que no tuve un registro actualizado durante todo el proceso. La última vez que cometo ese error.

Tuve un sitio grande que falló repetidamente al iniciar. Es una instalación de 2 contenedores, por lo que el contenedor antiguo siguió ejecutándose mientras se realizaba la migración durante el arranque. Finalmente resolví el problema activando SKIP_POST_DEPLOYMENT_MIGRATIONS=1 para el arranque y luego ejecutando las migraciones una vez que se inició el nuevo contenedor. Con SKIP_POST_DEPLOYMENT_MIGRATIONS=1 en la sección ENV, la migración fue muy rápida; el sitio pudo funcionar con normalidad (aunque quizás más lentamente) mientras se ejecutaban las migraciones, lo cual tomó, creo, más de 20 minutos.

Creo, aunque aún no lo he probado, que usar este mismo truco permitiría minimizar el tiempo de inactividad también en una instalación de un solo contenedor. Si tengo razón, lo que harías sería:

  • agregar SKIP_POST_DEPLOYMENT_MIGRATIONS=1 a tu app.yml
  • ./launcher rebuild app
  • ./launcher enter app
  • SKIP_POST_DEPLOYMENT_MIGRATIONS=0 rake db:migrate
  • deshacer la edición en app.yml, a menos que planees recordar ejecutar las migraciones después de cada actualización
  • quizás volver a reconstruir para asegurarte de que no haya ningún problema mientras aún recuerdas qué podría haber roto tu sitio; si esperas 4 meses para intentarlo de nuevo, no tendrás idea y será difícil que alguien adivine cuál podría ser el problema

Si existiera una forma de que ./launcher pasara SKIP_POST_DEPLOYMENT_MIGRATIONS=1 a los componentes sin requerir una edición en app.yml, facilitaría las cosas para quienes tienen dificultades con la edición.

Si logro realizar el trabajo sobre esto que creo que haré, crearé un nuevo tema informando sobre lo que he descubierto. Aunque el humo me ha confinado a una habitación donde no tengo mi monitor grande. (¿Acaso la pandemia no fue suficiente? ¿Ahora también tenemos que lidiar con el humo? Y ni siquiera estoy particularmente cerca del maldito fuego.)

Buena idea, lo he implementado:

https://github.com/discourse/discourse_docker/pull/481

¡Esa es una noticia fantástica! (Dos proyectos más interfirieron hoy y, de alguna manera, mi instancia multisitio ya no funciona ni se lleva bien con S3. :gato_llorando:) Muchas gracias.

¿Existe una razón técnica por la que los cambios en la base de datos posteriores a la actualización deban ser bloqueantes de forma predeterminada? ¿Hay alguna manera de cambiar ese comportamiento para que las futuras actualizaciones restauren el sitio rápidamente y luego ejecuten las tareas posteriores a la actualización en segundo plano?

En mi opinión, cualquier cosa esencial para que la aplicación actualizada funcione, como las DDL, debería formar parte de la propia actualización, no de los scripts posteriores a la actualización.

¡Hace siete horas que comenzamos nuestra reconstrucción desde la línea de comandos y aún sigue en marcha… ¡Sigue ahí!

¿Alguna idea?

Edición: Mientras tanto, he matado el proceso para volver a tener el sitio en línea para nuestros usuarios. Pero debe haber una mejor manera de realizar esta actualización.

¿Tienes una base de datos grande?