
Mercredi 12 février 2025 à 10:44
En travaillant sur le projet Projet 23 - "Ajouter le support pg_basebackup incremental à restic-pg_dump-docker", j'ai découvert que PostgreSQL propose deux protocoles de communication :
- Le premier est le plus connu "Frontend/Backend Protocol". C'est celui qui est utilisé par la commande
psql
ou les librairies telles que Postgres.js (en NodeJS), Psycopg (en Python)… - Le second nommé "Streaming Replication Protocol"
Sans vraiment comprendre, en 2020, j'avais activé le protocole streaming replication dans ce POC postgresql-streaming-replication-playground
. Mais je n'avais jamais pris conscience de l'existence de ce second protocole.
Les développeurs de PostgreSQL semblent avoir décidé de créer un second protocole parce qu'ils n'ont pas du tout le même objectif.
Streaming Replication Protocol est optimisé dans la transmission des WAL et des snapshots (copie de l'intégralité du dossier PGDATA
).
Le protocole Streaming Replication Protocol est entre autres utilisé par pg_basebackup, barman, pgBackRest, ou Patroni.
Comment activer Streaming Replication Protocol ?
Les images Docker Postgres setup par défaut le fichier pg_hba.conf suivant :
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all trust
host replication all 127.0.0.1/32 trust
host replication all ::1/128 trust
host all all all scram-sha-256
J'ai compris que par défaut, toutes ces lignes configurent l'accès au Frontend/Backend Protocol.
Seules les lignes qui contiennent replication
configurent l'accès au Streaming Replication Protocol.
Pour permettre l'accès au Streaming Replication Protocol par réseau TCP/IP en dehors du container Docker il est nécessaire d'ajouter la ligne suivante :
host replication all all scram-sha-256
Suite à cette découverte, j'ai repensé à :
Pour faire face à ce problème, j'ai exploré fin 2023 une solution basée sur pgBackRest : Implémenter un POC de pgBackRest.
Je suis plus ou moins arrivé au bout de ce POC mais je n'ai pas été satisfait du résultat.
Je n'ai pas réussi à configurer pgBackRest en "pure Docker sidecar".
De plus, j'ai trouvé la restauration du backup difficile à exécuter.
et je me suis demandé si mon échec de configuration de pgBackRest en Docker sidecar n'était pas seulement dû au fait que je n'avais pas activé Streaming Replication Protocol 🤔.
La réponse semble être "oui" et "non".
Je suis tombé sur l'issue suivante : pgbackrest with postgresql in docker.
The problem might be harder than you think unfortunately. If the pgBackRest process is running on the VM (docker host), it will try to connect to PG locally using the unix socket, not the tcp "localhost" connection.
Je pense comprendre que pgBackRest ne permet pas d'utiliser des INET sockets pour communiquer avec PostgreSQL.
Toutefois, je me dis que je pourrais partager le volume PGDATA
avec le sidecar pgBackRest pour lui donner accès à l'Unix Socket du Streaming Replication Protocol 🤔.
Entre mon exploration de pg_basebackup, mes envies de tester barman et de continuer mon POC pgBackRest… je me dis que je ne suis pas encore au bout de ce Yak!.
Journaux liées à cette note :
Journal du jeudi 13 février 2025 à 14:09
Suite de mes notes 2025-02-09_1705, 2025-02-12_1044, 2025-02-12_1511, 2025-02-12_1534 et 2025-02-12_2305 au sujet de barman pour sauvegarder des bases de données PostgreSQL
Je ne sais pas pourquoi je dois lancer
select pg_switch_wal();
.
J'ai découvert dans ce commentaire qu'il existe une commande nommée : barman switch-wal
.
Je pense avoir compris qu'avant d'exécuter barman backup…
il est nécessaire d'exécuter :
$ barman switch-wal
$ barman cron
$ barman check postgres1
Server postgres1:
PostgreSQL: OK
superuser or standard user with backup privileges: OK
PostgreSQL streaming: OK
wal_level: OK
replication slot: OK
directories: OK
retention policy settings: OK
backup maximum age: OK (no last_backup_maximum_age provided)
backup minimum size: OK (0 B)
wal maximum age: OK (no last_wal_maximum_age provided)
wal size: OK (0 B)
compression settings: OK
failed backups: OK (there are 0 failed backups)
minimum redundancy requirements: OK (have 0 backups, expected at least 0)
pg_basebackup: OK
pg_basebackup compatible: OK
pg_basebackup supports tablespaces mapping: OK
systemid coherence: OK (no system Id stored on disk)
pg_receivexlog: OK
pg_receivexlog compatible: OK
receive-wal running: OK
archiver errors: OK
$ barman backup postgres1 --immediate-checkpoint
Starting backup using postgres method for server postgres1 in /var/lib/barman/postgres1/base/20250213T100353
Backup start at LSN: 0/4000000 (000000010000000000000004, 00000000)
Starting backup copy via pg_basebackup for 20250213T100353
Copy done (time: 1 second)
Finalising the backup.
This is the first backup for server postgres1
WAL segments preceding the current backup have been found:
000000010000000000000002 from server postgres1 has been removed
Backup size: 22.3 MiB
Backup end at LSN: 0/6000000 (000000010000000000000006, 00000000)
Backup completed (start time: 2025-02-13 10:03:53.072228, elapsed time: 1 second)
Processing xlog segments from streaming for postgres1
000000010000000000000003
000000010000000000000004
WARNING: IMPORTANT: this backup is classified as WAITING_FOR_WALS, meaning that Barman has not received yet all the required WAL files for the backup consistency.
This is a common behaviour in concurrent backup scenarios, and Barman automatically set the backup as DONE once all the required WAL files have been archived.
Hint: execute the backup command with '--wait'
total 4.0K
$ ls /var/lib/barman/postgres1/base/ -lha
total 8.0K
drwxr-xr-x 1 barman barman 60 Feb 13 10:00 .
drwxr-xr-x 1 barman barman 88 Feb 13 09:59 ..
drwxr-xr-x 1 barman barman 30 Feb 13 09:59 20250213T095917
$ barman list-backups postgres1
postgres1 20250213T103723 - F - Thu Feb 13 10:37:24 2025 - Size: 22.3 MiB - WAL Size: 0 B - WAITING_FOR_WALS
J'ai réussi dans le POC https://github.com/stephane-klein/poc-barman à dérouler toutes les étapes du backup complet jusqu'à la restauration d'une base de données.
Toutefois, pour le moment, je n'ai toujours pas réussi à restaurer un backup incrémental 🙁.
À cet endroit, j'ai l'erreur suivante :
$ docker compose up postgres2
postgres2-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization
postgres2-1 |
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: starting PostgreSQL 17.2 (Debian 17.2-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres2-1 | 2025-02-13 13:20:07.594 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres2-1 | 2025-02-13 13:20:07.596 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres2-1 | 2025-02-13 13:20:07.598 UTC [1] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.600 UTC [29] LOG: database system was interrupted; last known up at 2025-02-13 13:20:03 UTC
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: starting backup recovery with redo LSN 0/8000028, checkpoint LSN 0/8000080, on timeline ID 1
postgres2-1 | 2025-02-13 13:20:07.643 UTC [29] LOG: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.649 UTC [29] FATAL: could not open directory "pg_tblspc": No such file or directory
postgres2-1 | 2025-02-13 13:20:07.651 UTC [1] LOG: startup process (PID 29) exited with exit code 1
postgres2-1 | 2025-02-13 13:20:07.651 UTC [1] LOG: aborting startup due to startup process failure
postgres2-1 | 2025-02-13 13:20:07.652 UTC [1] LOG: database system is shut down
Journal du mercredi 12 février 2025 à 11:41
En rédigeant la note 2025-02-12_1044, je me suis demandé quelle est la différence de performance entre un Unix Socket et un INET socket.
Durant mes recherches, j'ai découvert qu'Unix Socket est plus rapide que INET sockets. Je n'ai pas été surpris, j'avais cette intuition.
Toutefois, j'ai été surpris d'apprendre que le gain est non négligeable, de 30% à 50% de gains !
Exemple :
On my machine, Ryzen 3900X, Ubuntu 22,
A basic C++ TCP server app that only sends 64K packets, and a basic c++ receiver that pulls 100GB of these packets and copies them to it's internal buffer only, single-threaded:
- achieves
~30-33 GBit/sec
for TCP connection (~4.0GB/sec
) (not MBit)- and
~55-58GBit/sec
for a socket connection, (~7.3 GB/sec
)- and
~492Gbit/sec
for in-process memcopy (~61GB /sec
)
Conséquence : je vais essayer d'utiliser des Unix sockets autant que je peux.