Passage Howto PostgreSQL en Debian 10 + ajout réplication logique

This commit is contained in:
Gregory Colpart 2019-09-17 23:28:05 +02:00
parent 877ff6fcca
commit f86c551a23
3 changed files with 139 additions and 16 deletions

View file

@ -3,7 +3,7 @@ title: Howto PostgreSQL
categories: databases categories: databases
... ...
* Documentation : <https://www.postgresql.org/docs/9.6/static/index.html> * Documentation : <https://www.postgresql.org/docs/11/>
* Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/postgresql> * Rôle Ansible : <https://forge.evolix.org/projects/ansible-roles/repository/show/postgresql>
* The Internals of PostgreSQL : <http://www.interdb.jp/pg/> * The Internals of PostgreSQL : <http://www.interdb.jp/pg/>
@ -16,8 +16,8 @@ categories: databases
# apt install postgresql # apt install postgresql
# /usr/lib/postgresql/9.6/bin/postgres -V # /usr/lib/postgresql/11/bin/postgres -V
postgres (PostgreSQL) 9.6.6 postgres (PostgreSQL) 11.5 (Debian 11.5-1+deb10u1)
# systemctl status postgresql # systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS ● postgresql.service - PostgreSQL RDBMS
@ -30,7 +30,7 @@ postgres (PostgreSQL) 9.6.6
# pg_lsclusters # pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file Ver Cluster Port Status Owner Data directory Log file
9.6 main 5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log 11 main 5432 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
~~~ ~~~
> *Note* : il faut s'assurer d'avoir configuré sa locale système `dpkg-reconfigure locales` avant installation car l'initialisation des bases de données est faite avec la locale du système. > *Note* : il faut s'assurer d'avoir configuré sa locale système `dpkg-reconfigure locales` avant installation car l'initialisation des bases de données est faite avec la locale du système.
@ -43,31 +43,31 @@ Le dépôt **apt.postgresql.org** permet d'installer des versions différentes d
Ajouter le dépôt un fichier `/etc/apt/sources.list.d/postgresql.list` : Ajouter le dépôt un fichier `/etc/apt/sources.list.d/postgresql.list` :
~~~ ~~~
deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main
~~~ ~~~
Puis récupérer la clé GPG : Puis récupérer la clé GPG :
~~~ ~~~
# wget --quiet -O - https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | apt-key add - # wget https://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc -O /etc/apt/trusted.gpg.d/postgresql-org.asc
~~~ ~~~
On peut ainsi installer proprement PostgresSQL 10 - par exemple - en définissant les priorités via `/etc/apt/preferences.d/postgresql` : On peut ainsi installer proprement PostgresSQL 11 - par exemple - en définissant les priorités via `/etc/apt/preferences.d/postgresql` :
~~~ ~~~
Package: postgresql postgresql-client-common postgresql-common libpq5 libdbd-pg-perl ptop Package: postgresql postgresql-client-common postgresql-common libpq5 libdbd-pg-perl ptop
Pin: release a=stretch-pgdg Pin: release a=buster-pgdg
Pin-Priority: 999 Pin-Priority: 999
~~~ ~~~
Puis : Puis :
~~~ ~~~
# apt install postgresql-10 # apt install postgresql-11
# pg_lsclusters # pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file Ver Cluster Port Status Owner Data directory Log file
10 main 5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log 11 main 5432 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
~~~ ~~~
## Administration basique ## Administration basique
@ -79,6 +79,7 @@ Ver Cluster Port Status Owner Data directory Log file
Ver Cluster Port Status Owner Data directory Log file Ver Cluster Port Status Owner Data directory Log file
9.6 main 5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log 9.6 main 5432 online postgres /var/lib/postgresql/9.6/main /var/log/postgresql/postgresql-9.6-main.log
10 main 5433 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log 10 main 5433 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
11 main 5433 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
~~~ ~~~
### Lister les requêtes actives ### Lister les requêtes actives
@ -1167,20 +1168,26 @@ huge_pages = on
Plusieurs solutions de réplication plus ou moins avancées existent avec PostgreSQL : Plusieurs solutions de réplication plus ou moins avancées existent avec PostgreSQL :
* _Streaming Replication_ ou _Physique_ : les données sont transférées immédiatement par un processus dédié (_walsender_) dans une connexion réseau établie avec le réplica. Contrairement aux autres solutions, cela nécessite une légère charge supplémentaire par réplica sur le maître pour faire tourner le processus _walsender_. En général ce système est couplé à l'envoi des *WAL* car si le réplica est trop en retard par rapport au master, il va lire les *WAL* jusqu'à avoir rattrapé son retard puis basculera tout seul sur la *streaming replication*
* _Logique_ : les données sont répliquées au niveau des objets par un système de publication/abonnement
* _PITR_, _Point In Time Recovery_ : copie des logs de transaction (_WAL_) sur un serveur distant pour archivage. Ils peuvent ensuite être rejoués jusqu'à un point précis en cas de perte de données par exemple. * _PITR_, _Point In Time Recovery_ : copie des logs de transaction (_WAL_) sur un serveur distant pour archivage. Ils peuvent ensuite être rejoués jusqu'à un point précis en cas de perte de données par exemple.
* _Warm Standby_ : les _WAL_ sont copiés sous forme d'archive sur un second serveur sur lequel tourne un PostgreSQL en mode _recovery_ constant. Chaque segment reçu est rejoué par PostgreSQL. Il est alors prêt à prendre le relais en cas de panne sur le serveur maître. * _Warm Standby_ : les _WAL_ sont copiés sous forme d'archive sur un second serveur sur lequel tourne un PostgreSQL en mode _recovery_ constant. Chaque segment reçu est rejoué par PostgreSQL. Il est alors prêt à prendre le relais en cas de panne sur le serveur maître.
* _Hot Standby_ : le principe est le même que pour le _Warm Standby_, mais le réplica peut être interrogé en lecture. Il y a néanmois une légère différence perpétuelle entre le master et le réplica car le *WAL* est transféré seulement lorsque l'archive a fini d'être écrite. * _Hot Standby_ : le principe est le même que pour le _Warm Standby_, mais le réplica peut être interrogé en lecture. Il y a néanmois une légère différence perpétuelle entre le master et le réplica car le *WAL* est transféré seulement lorsque l'archive a fini d'être écrite.
* _Streaming Replication_ : les données sont transférées immédiatement par un processus dédié (_walsender_) dans une connexion réseau établie avec le réplica. Contrairement aux autres solutions, cela nécessite une légère charge supplémentaire par réplica sur le maître pour faire tourner le processus _walsender_. En général ce système est couplé à l'envoi des *WAL* car si le réplica est trop en retard par rapport au master, il va lire les *WAL* jusqu'à avoir rattrapé son retard puis basculera tout seul sur la *streaming replication*
* _Slony_ : système de réplication basé sur l'ajout de triggers sur chaque table à répliquer. Cela nécessite une gestion assez complexe mais c'était la seule façon d'avoir une réplication immédiate avant l'arrivée de la _Streaming Replication_. Cela reste la seule solution pour avoir une réplication au niveau des tables et non de la base entière (par exemple si vous voulez répliquer une table d'un serveur A vers un serveur B, et répliquer une autre table du serveur B vers A). * _Slony_ : système de réplication basé sur l'ajout de triggers sur chaque table à répliquer. Cela nécessite une gestion assez complexe mais c'était la seule façon d'avoir une réplication immédiate avant l'arrivée de la _Streaming Replication_. Cela reste la seule solution pour avoir une réplication au niveau des tables et non de la base entière (par exemple si vous voulez répliquer une table d'un serveur A vers un serveur B, et répliquer une autre table du serveur B vers A).
Pour plus de détails sur ces solutions, voir ce post sur [dba.stackexange.com](https://dba.stackexchange.com/questions/73812/postgresql-streaming-versus-file-based-replication-in-terms-of-server-behavior). Pour d'autres types de solutions pour avoir de la haute disoponibilite, PostgreSQL a [une page sur cela dans leur documentation](https://www.postgresql.org/docs/current/static/different-replication-solutions.html). Pour plus de détails sur ces solutions, voir ce post sur [dba.stackexange.com](https://dba.stackexchange.com/questions/73812/postgresql-streaming-versus-file-based-replication-in-terms-of-server-behavior). Pour d'autres types de solutions pour avoir de la haute disponibilité, PostgreSQL a [une page sur cela dans leur documentation](https://www.postgresql.org/docs/current/static/different-replication-solutions.html).
> *Note* : l'expédition des logs entre des serveurs pgsql nécessite qu'ils soient à la même version majeure. > *Note* : l'expédition des logs entre des serveurs pgsql nécessite qu'ils soient à la même version majeure.
### Streaming Replication ### Streaming Réplication
Voir [/HowtoPostgreSQL/Replication](). Voir [/HowtoPostgreSQL/ReplicationPhysique]().
### Réplication Logique
Voir [/HowtoPostgreSQL/ReplicationLogique]().
### Slony ### Slony

View file

@ -0,0 +1,114 @@
# _Réplication Logique_ avec PostgreSQL
<https://www.postgresql.org/docs/11/logical-replication.html>
## Mise en place
Sur le serveur primaire et réplica, on s'assure d'avoir deux bases :
~~~
postgres $ createuser -p 5432 -P foo
Enter password for new role:
postgres $ createdb -p 5432 -O foo foo
~~~
Sur le serveur primaire, on modifie la directive `wal_level` :
~~~
wal_level = logical
~~~
Puis l'on crée un utilisateur `replication` et une publication liée à cette base :
~~~
postgres $ createuser -p 5432 -P --replication replication
postgres $ psql -p 5432 foo
foo=# GRANT SELECT on ALL TABLES IN SCHEMA public TO replication;
GRANT
foo=# CREATE PUBLICATION alltables FOR ALL TABLES;
CREATE PUBLICATION
~~~
Sur le serveur réplica, on crée une subscription liée à cette base :
~~~
postgres $ psql -p 5432 foo
foo=# CREATE SUBSCRIPTION mysub CONNECTION 'dbname=foo host=192.0.2.1 port=5436 user=replication password=PASSWORD' PUBLICATION alltables;
NOTICE: created replication slot "mysub" on publisher
CREATE SUBSCRIPTION
~~~
Attention, contrairement à la réplication physique, rien n'empêche d'écrire sur le serveur réplica.
Ensuite, il faut créer les tables de façon identique sur les deux bases :
~~~
postgres $ psql -U foo -h 127.0.0.1 -p 5432 foo
foo=> CREATE TABLE t (a INT);
~~~
Enfin, l'insertion de données sur le serveur primaire, devrait provoquer le transfert de ces données sur le serveur réplica :
~~~
LOG: logical replication table synchronization worker for subscription "mysub", table "t" has started
~~~
Si besoin, on peut « rafraichir » la subscription sur le serveur replica via la commande :
~~~
postgres $ psql -p 5432 foo
foo=# ALTER SUBSCRIPTION mysub REFRESH PUBLICATION;
~~~
## Administration
### Ajout / modification d'une table
Si l'on veut ajouter ou modifier une table, il faut :
- créer / modifier la table sur les 2 serveurs maître et réplica
- relancer la commande suivante sur le serveur maître :
~~~
postgres $ psql -p 5432 foo
foo=# GRANT SELECT on ALL TABLES IN SCHEMA public TO replication;
GRANT
~~~
- relancer la commande suivante sur le serveur réplica :
~~~
postgres $ psql -p 5432 foo
foo=# ALTER SUBSCRIPTION mysub REFRESH PUBLICATION;
~~~
On peut ensuite insérer des données sur la nouvelle table qui sera répliquée.
## Monitoring
Sur le serveur replica, on peut surveiller le bon fonctionnement de la réplication ainsi :
~~~
postgres=# select * from pg_subscription ;
subdbid | subname | subowner | subenabled | subconninfo | subslotname | subsynccommit | subpublications
---------+---------+----------+------------+----------------------------------------------------------------------------+-------------+---------------+-----------------
16385 | mysub | 10 | t | dbname=foo host=192.0.2.1 port=5432 user=replication password=PASSWORD | mysub | off | {alltables}
(1 row)
postgres=# select * from pg_stat_subscription ;
subid | subname | pid | relid | received_lsn | last_msg_send_time | last_msg_receipt_time | latest_end_lsn | latest_end_time
-------+---------+-------+-------+--------------+-------------------------------+-------------------------------+----------------+-------------------------------
16388 | mysub | 12767 | | 0/16A58D8 | 2019-09-17 21:09:16.512057+00 | 2019-09-17 21:09:16.512241+00 | 0/16A58D8 | 2019-09-17 21:09:16.512057+00
~~~

View file

@ -1,6 +1,8 @@
# _Streaming Replication_ avec PostgreSQL # _Streaming Replication_ avec PostgreSQL
La réplication en flux (_Streaming Replication_) est disponible à partir de la version 9.0 de PostgreSQL. Celle-ci est différente de la réplication logique apparue dans la version 10. <https://www.postgresql.org/docs/11/warm-standby.html#STREAMING-REPLICATION>
La réplication en flux (_Streaming Replication_) est disponible à partir de la version 9.0 de PostgreSQL. Celle-ci est aussi appelée _Réplication Physique_ en opposition à la _Réplication Logique_ apparue dans la version 10.
## Caractéristiques ## Caractéristiques
@ -16,7 +18,7 @@ Par rapport au mode de réplication _Hot Standby_, l'avantage avec la réplicati
Pré-requis pour pouvoir mettre en place une infra avec 1 maître et 1 réplicat : Pré-requis pour pouvoir mettre en place une infra avec 1 maître et 1 réplicat :
* même architecture (32 bits/64 bits) sur les 2 serveurs ; * même architecture (32 ou 64 bits) sur les 2 serveurs ;
* même version majeure de PostgreSQL sur les 2 serveurs (et même version mineure est conseillé) ; * même version majeure de PostgreSQL sur les 2 serveurs (et même version mineure est conseillé) ;
## Installation de PostgreSQL ## Installation de PostgreSQL