Actualización de PostgreSQL 13

:warning: ¡ADVERTENCIA! Si tu base de datos es muy grande, necesitarás mucho espacio extra en el disco (2x el tamaño de la base de datos) y debes tener mucho cuidado con esta actualización.

Acabamos de implementar cambios para actualizar nuestra imagen Docker a PostgreSQL 13. Cualquier administrador de sitio que reconstruya Discourse desde la línea de comandos será actualizado a PostgreSQL 13 desde la versión anterior, PostgreSQL 12. Ten en cuenta que si te abstuviste de actualizar cuando se produjo la actualización de PostgreSQL 12 hace un tiempo en mayo, puedes saltarte esa actualización e ir directamente a PostgreSQL 13.

Si habías pospuesto la actualización anteriormente, cambia la plantilla de PostgreSQL en app.yml de templates/postgres.10.template.yml a templates/postgres.template.yml.

Como con cualquier actualización, se recomienda encarecidamente realizar una copia de seguridad antes de hacer cualquier cosa.

Actualización

Guía de instalación oficial (contenedor único)

En tu próxima reconstrucción, verás este mensaje al final:

-------------------------------------------------------------------------------------
ACTUALIZACIÓN DE POSTGRES COMPLETADA

La base de datos antigua 12 se almacena en /shared/postgres_data_old

Para completar la actualización, vuelve a reconstruir usando:

./launcher rebuild app
-------------------------------------------------------------------------------------

¡Eso significa que todo salió bien en la actualización! Solo necesitas ejecutar una nueva reconstrucción para que tu sitio vuelva a estar operativo.

Instalación con contenedor de datos

Si estás ejecutando una configuración con un contenedor de datos dedicado basado en el ejemplo proporcionado en nuestro repositorio discourse_docker, debes asegurarte de que PostgreSQL se detenga de manera segura y limpia.

Actualmente, tenemos trabajos en segundo plano ejecutando consultas que duran varios minutos, por lo que detener el contenedor web ayudará a que el contenedor de datos se apague de forma segura.

./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only

Antes de ejecutar la primera reconstrucción en el contenedor de datos, puedes seguir el registro de PostgreSQL para ver si se apagó correctamente.

Ejecutar tail -f shared/data/log/var-log/postgres/current debería mostrarte el siguiente registro si fue limpio:

2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

Realizar una actualización manual / entornos con espacio limitado

:warning::warning::warning:
DEBES HACER UNA COPIA DE SEGURIDAD DE POSTGRES_DATA ANTES DE INTENTAR ESTO
:warning::warning::warning:

Si estás en un entorno con espacio limitado y no tienes forma de obtener más espacio, puedes probar lo siguiente:

./launcher stop app #(o ambos web_only y data si ese es tu caso)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
	-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/12/data \
	-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/13/data \
	tianon/postgres-upgrade:12-to-13
mv /var/discourse/shared/standalone/postgres_data /var/discourse/shared/standalone/postgres_data_old
mv /var/discourse/shared/standalone/postgres_data_new /var/discourse/shared/standalone/postgres_data
./launcher rebuild app #(o primero data y luego web_only si ese es tu caso)

En mis pruebas, este procedimiento requiere menos de 1x el tamaño actual de tu base de datos en espacio libre.

Posponer la actualización

Si necesitas posponer la actualización durante tu próxima reconstrucción, puedes cambiar la plantilla de PostgreSQL en tu archivo app.yml modificando "templates/postgres.template.yml" a "templates/postgres.12.template.yml".

Esto no se recomienda, ya que algunos administradores de sitios podrían olvidar revertir el cambio posteriormente.

Tareas opcionales posteriores a la actualización

Optimización de estadísticas de PostgreSQL

Después de la actualización, el nuevo PostgreSQL no tendrá estadísticas de tablas a mano. Puedes generarlas usando:

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
VACUUM VERBOSE ANALYZE;
\q
exit
exit

O esta versión de una sola línea de la anterior:

/var/discourse/launcher run app "echo 'vacuum verbose analyze;' | su postgres -c 'psql discourse'"

Volver a crear los índices

La característica principal de esta actualización es un gran ahorro de espacio en nuestra tabla más grande en cada instancia, la tabla post_timings y sus índices. Después de realizar una actualización exitosa, necesitarás ejecutar un comando para reconstruir los índices y aprovechar los beneficios.

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;
\q
exit
exit

Si puedes verificar el tamaño de post_timings antes y después del REINDEX, ¡sería una estadística genial para compartir aquí!

Puedes usar la siguiente consulta para verificar los 20 objetos de datos más grandes; ejecútala antes y después del reíndice:

WITH RECURSIVE pg_inherit(inhrelid, inhparent) AS
    (select inhrelid, inhparent
    FROM pg_inherits
    UNION
    SELECT child.inhrelid, parent.inhparent
    FROM pg_inherit child, pg_inherits parent
    WHERE child.inhparent = parent.inhrelid),
pg_inherit_short AS (SELECT * FROM pg_inherit WHERE inhparent NOT IN (SELECT inhrelid FROM pg_inherit))
SELECT table_schema
    , TABLE_NAME
    , row_estimate
    , pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
    SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes
    FROM (
         SELECT c.oid
              , nspname AS table_schema
              , relname AS TABLE_NAME
              , SUM(c.reltuples) OVER (partition BY parent) AS row_estimate
              , SUM(pg_total_relation_size(c.oid)) OVER (partition BY parent) AS total_bytes
              , SUM(pg_indexes_size(c.oid)) OVER (partition BY parent) AS index_bytes
              , SUM(pg_total_relation_size(reltoastrelid)) OVER (partition BY parent) AS toast_bytes
              , parent
          FROM (
                SELECT pg_class.oid
                    , reltuples
                    , relname
                    , relnamespace
                    , pg_class.reltoastrelid
                    , COALESCE(inhparent, pg_class.oid) parent
                FROM pg_class
                    LEFT JOIN pg_inherit_short ON inhrelid = oid
                WHERE relkind IN ('r', 'p')
             ) c
             LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
  ) a
  WHERE oid = parent
) a
ORDER BY total_bytes DESC LIMIT 20;

Limpieza de datos antiguos

Para una instalación estándar, puedes eliminar los datos antiguos en formato PG12 con el siguiente comando:

cd /var/discourse
./launcher cleanup

Si tienes un contenedor de datos separado, necesitarás eliminar la copia de seguridad así:

rm -fr /var/discourse/shared/data/postgres_data_old/

Preguntas frecuentes (FAQ)

El clúster de origen no se apagó limpiamente

Si obtienes un error de actualización con el mensaje anterior, puedes probar un enfoque más sencillo para devolverlo a un estado mejor.

Reinicia el contenedor antiguo con ./launcher start app. Espera unos minutos hasta que vuelva a estar activo.

Ahora apágalo nuevamente con ./launcher stop app. Después, sigue los registros para ver si fue una apagada limpia:

tail -f shared/data/log/var-log/postgres/current
2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

Si los registros se ven como los de arriba, ahora puedes intentar actualizar nuevamente usando ./launcher rebuild app.

Los valores de lc_collate para la base de datos “postgres” no coinciden

Este error ocurre si estás usando configuraciones regionales (locales) no predeterminadas para tu base de datos. Se reportó que necesitas 3 variables para que tenga éxito. Asegúrate de que la sección env: de tu archivo app.yml tenga las 3 líneas:

  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

Cambiando en_US.UTF-8 por tu configuración regional.

Cada reconstrucción realiza la actualización nuevamente (bucle de actualización)

Cuando esto sucede, tus registros de actualización contendrán:

mv: cannot move '/shared/postgres_data' to '/shared/postgres_data_old/postgres_data': Directory not empty
mv: cannot move '/shared/postgres_data_new' to '/shared/postgres_data/postgres_data_new': Directory not empty

Esto significa que aún hay archivos de la última actualización flotando. Mueve esos archivos a otro lugar antes de continuar.

Scripts de sugerencia “Actualización completada” - ¿Necesito hacer algo?

Una vez que se complete la actualización, verás una salida del mensaje pg_upgrade que dice:

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh

Puedes ignorar este mensaje de forma segura.

Me salté la actualización de PostgreSQL 12, ¿qué hago ahora?

Puedes seguir las instrucciones estándar en la parte superior de esta guía y se actualizarán desde tu versión a la 13 sin problemas.

Si estás siguiendo las instrucciones para entornos con espacio limitado, adapta los números de versión en consecuencia.

38 Me gusta
PostgreSQL Details
Discourse 2.7.0.beta2 Release Notes
Forum offline due to failed rebuilds on Tests-Pass
Nginx upstream timed out (110: Connection timed out)
Firewall issue with running multiple containers after upgrade
Help! Problem with firewall/permissions and postgre?
PostgreSQL 13 update from PostgreSQL 10 fails
PostgreSQL 13 update from PostgreSQL 10 fails
Unrecognized error type (ActiveRecord::StatementInvalid: PG::ProgramLimitExceeded
Recover from filesystem backup: can't rebuild nor start
Rebuild error: Errno::ENOENT: No such file or directory @ rb_sysopen - /e tc/postgresql/13/main/pg_hba.conf
Discourse broken after upgrade
Upgrade Failed from 2.7.0.beta1 to 2.7.0.beta3
Invalid location error after update
Upgrade failed!
Upgrade failed: PostgreSQL version 13 ... not compatible with ... version 10.12
Improved Bookmarks with Reminders
Importing old database to latest version
Errors encountered when uploading images
What else do I need to take care of when self hosting?
Rebuild freezing when attempting to stop container
Backup failed due to PG/SQL errors
Restore Failing - Check Free Disk Space
Supported postgresql versions
Wrong Error Message for too short replies for Reply-by-Email
Upgrade Postgres with REALLY limited space
Upgrade Postgres with REALLY limited space
Postgres has 100% CPU for large databases, Discourse 2.7.7
Upgrade failing with FAILED TO BOOTSTRAP
Stuck in an update loop after PostgreSQL 13 update
Problem with rebuild Discourse at Docker
After Rebuild got error: postgres:10/main, Causes CPU to go high
Call AdminDashboardGeneralData.refresh_stats at boot?
ERROR: You are running an old version of the Discourse image
Failed to upgrade to v2.9.0beta3
Failed to upgrade to v2.9.0beta3
SMTP Settings in app.yml reset?
Upgrade container - keeping config and data
Site down after failed update: permission denied to create extension "unaccent"
Rebuild fails on db:migrate w/PG12
Update from 2.9.0 beta2 to beta4 failed (my site is down)
Performance optimisation tips
Upgrading from 2.4 to 2.9. Need slight assistance on what order to run the final commands & reboot in
Problem when updating Discourse Forum
Troubleshooting severe performance issues with latest Discourse?
Slow Profile Loads with 100GB+ database
Use Nginx Proxy Manager to manage multiple sites with Discourse
Horizontal loading slider
Upgrading Discourse from 2.6.0.beta2
PostgreSQL 15 update
Got a lot of "Failed to backfill 'Reader' badge" errors
Trouble updating discourse after some time - UPGRADE OF POSTGRES FAILED
Database size/maintenance
Upgrade gone sideways [deprecated Guest Gate plugin]
Upgrade Issues: Failed Upgrade due to Duplicate Key, Failed Snapshot Restore
2.7.0.beta2 upgrade failed with ERROR: duplicate key
Problem, rebuild to latest version
Urgent, upgraded build failed UniqueViolation