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

