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

113 lines
3.7 KiB
Markdown

+++
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 😇