Mise à jour de PostgreSQL 13

:warning: ATTENTION ! Si votre base de données est très volumineuse, vous aurez besoin d’un espace disque supplémentaire important (2x la taille de la base de données) et devez être extrêmement prudent avec cette mise à niveau !

Nous venons d’apporter des modifications pour mettre à niveau notre image Docker vers PostgreSQL 13. Tout administrateur de site reconstruisant Discourse en ligne de commande sera mis à niveau vers PostgreSQL 13 depuis la version précédente, PostgreSQL 12. Notez que si vous avez différé la mise à jour lors de la mise à jour de PostgreSQL 12 survenue en mai, vous pouvez sauter cette mise à jour et passer directement à PostgreSQL 13.

Si vous aviez précédemment différé la mise à jour, modifiez le modèle PostgreSQL dans app.yml de templates/postgres.10.template.yml à templates/postgres.template.yml.

Comme pour toute mise à niveau, il est fortement conseillé de faire une sauvegarde avant d’entreprendre quoi que ce soit.

Mise à jour

Guide d’installation officiel (conteneur unique)

Lors de votre prochaine reconstruction, vous verrez ce message à la fin :

-------------------------------------------------------------------------------------
MISE À NIVEAU DE POSTGRES TERMINÉE

L'ancienne base de données 12 est stockée dans /shared/postgres_data_old

Pour terminer la mise à niveau, reconstruisez à nouveau en utilisant :

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

Cela signifie que tout s’est bien passé lors de la mise à niveau ! Vous devez simplement lancer une nouvelle reconstruction pour remettre votre site en ligne.

Installation avec conteneur de données

Si vous exécutez une configuration avec un conteneur de données dédié basé sur l’exemple fourni dans notre dépôt discourse_docker, assurez-vous d’arrêter PostgreSQL de manière sûre et propre.

De nos jours, nous avons des tâches en arrière-plan exécutant des requêtes sur plusieurs minutes, donc arrêter le conteneur web aidera à arrêter le conteneur de données en toute sécurité.

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

Avant de lancer la première reconstruction du conteneur de données, vous pouvez suivre le journal PostgreSQL pour voir s’il a été arrêté correctement.

Exécuter tail -f shared/data/log/var-log/postgres/current devrait vous donner le journal suivant si l’arrêt était propre :

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

Effectuer une mise à jour manuelle / environnements à espace contraint

:warning::warning::warning:
VOUS DEVEZ SAUVEGARDER LES DONNÉES DE POSTGRES AVANT D’ESSAYER CECI
:warning::warning::warning:

Si vous êtes dans un environnement à espace contraint sans moyen d’obtenir plus d’espace, vous pouvez essayer ce qui suit :

./launcher stop app #(ou les deux web_only et data si c'est votre cas)
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 #(ou d'abord data puis web_only si c'est votre cas)

Selon mes tests, cette procédure nécessite moins de 1x la taille actuelle de votre base de données en espace libre.

Report de la mise à jour

Si vous devez reporter la mise à jour lors de votre prochaine reconstruction, vous pouvez remplacer le modèle PostgreSQL dans votre fichier app.yml en changeant "templates/postgres.template.yml" par "templates/postgres.12.template.yml".

Ce n’est pas recommandé, car certains administrateurs de site oublieront d’inverser le changement par la suite.

Tâches optionnelles après la mise à jour

Optimisation des statistiques PostgreSQL

Après la mise à jour, le nouveau PostgreSQL n’aura pas les statistiques de table à portée de main. Vous pouvez les générer en utilisant :

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

Ou cette version en une ligne de ce qui précède :

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

Recréation des index

La fonctionnalité principale de cette mise à niveau est une grande économie de fichiers dans notre plus grande table sur chaque instance, la table post_timings et ses index. Après avoir effectué une mise à jour réussie, vous devrez exécuter une commande pour reconstruire les index et en tirer parti.

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

Si vous pouvez vérifier la taille de post_timings avant et après le REINDEX, ce serait une statistique intéressante à partager ici !

Vous pouvez utiliser la requête ci-dessous pour vérifier les 20 plus grands objets de données, exécutez-la avant et après le reindex :

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;

Nettoyage des anciennes données

Pour une installation standard, vous pouvez supprimer les anciennes données au format PG12 avec la commande suivante :

cd /var/discourse
./launcher cleanup

Si vous avez un conteneur de données séparé, vous devrez supprimer la copie de sauvegarde comme ceci :

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

FAQ

Le cluster source n’a pas été arrêté proprement

Si vous obtenez un échec de mise à niveau avec le message ci-dessus, vous pouvez essayer une approche plus simple pour le remettre dans un meilleur état.

Redémarrez l’ancien conteneur avec ./launcher start app. Attendez quelques minutes jusqu’à ce qu’il soit de nouveau opérationnel.

Maintenant, arrêtez-le à nouveau avec ./launcher stop app. Ensuite, suivez les journaux pour voir si c’était propre :

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 les journaux ressemblent à ce qui précède, vous pouvez maintenant essayer de mettre à niveau à nouveau en utilisant ./launcher rebuild app.

Les valeurs lc_collate pour la base de données “postgres” ne correspondent pas

Cette erreur se produit si vous utilisez des paramètres régionaux non par défaut pour votre base de données. Il a été rapporté que vous avez besoin de 3 variables pour que cela réussisse. Assurez-vous que la section env: de votre fichier app.yml contient les 3 lignes :

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

En changeant en_US.UTF-8 par votre paramètre régional.

Chaque reconstruction effectue à nouveau la mise à niveau, c’est-à-dire une boucle de mise à niveau

Lorsque cela se produit, vos journaux de mise à niveau contiendront :

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

Cela signifie qu’il reste encore des fichiers de la dernière mise à niveau. Déplacez-les ailleurs avant de continuer.

Scripts de suggestion “Mise à niveau terminée” - dois-je faire quelque chose ?

Une fois la mise à niveau terminée, vous verrez une sortie du message pg_upgrade indiquant :

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

Vous pouvez ignorer en toute sécurité ce message.

J’ai sauté la mise à jour PostgreSQL 12, que faire maintenant ?

Vous pouvez suivre les instructions standard en haut de ce guide et elles mettront à niveau votre version vers 13 sans problème.

Si vous suivez les instructions pour les environnements à espace contraint, adaptez les numéros de version en conséquence.

38 « J'aime »
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