+++ 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 ; ERROR: could not drop the replication slot "" on publisher DETAIL: The error was: ERROR: replication slot "" does not exist ``` La solution est de modifier le nom du slot à une valeur _null/none_ ``` alter subscription set (slot_name = NONE); ``` Et ensuite la recréer ``` create subscription pdns_ns3 connection 'host= dbname=yverry user=replication_pdns password= port=5432' publication ; ``` 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 😇