yann.verry.org/content/posts/postgresql/postgresql-14-upgrade.md
2022-04-24 16:03:30 +02:00

3.7 KiB

+++ author = "Yann Verry" categories = ["db", "postgres"] date = 2021-12-06T22:46:52Z description = "" draft = false image = "https://images.unsplash.com/photo-1483736762161-1d107f3c78e1?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGRhdGFiYXNlfGVufDB8fHx8MTYzODEyOTc3OA&ixlib=rb-1.2.1&q=80&w=2000" slug = "postgresql-14-upgrade" tags = ["db", "postgres"] title = "PostgreSQL 14 upgrade avec une replication logique"

+++

Comme chaque année une nouvelle version majeur de PG est sorti. Nous en sommes à la 14.

L'upgrade debian mode est toujours aussi simple si on a bien clean les dossiers 14 générés

pg_ctlcluster 14 main stop
mv /etc/postgresql/14/main /etc/postgresql/14/old
rm -rf /var/lib/postgresql/14/main
pg_upgradecluster 13 main /var/lib/postgresql/14/main

On retiens le petit warning, car il va falloir s'en occuper après :

WARNING:  tables were not subscribed, you will have to run ALTER SUBSCRIPTION ... REFRESH PUBLICATION to subscribe the tables

Depuis plusieurs années j'utilise aussi côté docker l'image tianon/postgres-upgrade :

docker volume create postgres-14
docker run --rm \
-v postgres-13:/var/lib/postgresql/13/data \
-v postgres-14:/var/lib/postgresql/14/data \
tianon/postgres-upgrade:13-to-14

Enfin, je met à jour mon docker-compose.yml pour avoir que du 14 :

postgres:
	image: postgres:14-alpine
    volumes:
    	- postgres-14:/var/lib/postgresql/data
        - ssl:/ssl:ro
    dns: fd00::3:2
    networks:
    default:
	    ipv6_address: 2a01:e0a:49e:2b81::5432
    restart: always

Je reload et c'est bon!

Hop hop hop et le warning ?

Facile, facile qu'il disait mais je possède des SUBSCRIPTION pour répliquer des morceaux de ma base de donnée, notamment la partie powerdns sur l'ensemble de mes slaves (ns2 et ns3). Sur un slave il y a donc du travail en plus. Coupons pdns durant toute l'opération de maintenance. Il est important de ne rien répondre plutôt que d'avoir en cache une absence de réponse (= le backend étant indisponible).

Lors du réimport qui est sous forme de SQL like il y a une tentative de re-création de la souscription de notre réplication logique. Ça ne marche pas comme prévu.

Il faut donc la supprimer puis recréer afin de la réinitialiser n'ayant pas trouvé mieux.

yverry=# drop subscription <subscription name> ;
ERROR:  could not drop the replication slot "<subscription name>" on publisher
DETAIL:  The error was: ERROR:  replication slot "<subscription name>" does not exist

La solution est de modifier le nom du slot à une valeur null/none

alter subscription <subscription name> set (slot_name = NONE);

Et ensuite la recréer

create subscription pdns_ns3 connection 'host=<host> dbname=yverry user=replication_pdns password=<super password> port=5432' publication <subscription name> ;

Et voila ! Oui mais non ... Il reste une dernière erreur de duplicate entry, la table étant déjà peuplé j'ai donc un problème de duplicate en atteste le log

ERROR:  duplicate key value violates unique constraint

La solution n'est pas optimal mais j'ai préféré truncate ma table qui ne comporte que quelques centaines de lignes

TRUNCATE TABLE domains tb1 CASCADE;
NOTICE:  truncate cascades to table "tb2"
NOTICE:  truncate cascades to table "tb3"
NOTICE:  truncate cascades to table "tb4"
NOTICE:  truncate cascades to table "tb5"

La réplication essayant sans cesse, un process à très rapidemment rempli les tables recemment vidé :

LOG:  logical replication table synchronization worker for subscription

Et c'est enfin fini ! J'ai relancé mon serveur PowerDNS. Testé bien sur que tout étant comme avant.

Ready pour postgres 15 😇