Différences entre versions de « Replication PostgreSQL multi slaves »
Ligne 506 : | Ligne 506 : | ||
[[category:PostgreSQL]] | [[category:PostgreSQL]] | ||
[[category:Linux]] | [[category:Linux]] | ||
+ | [[Catégorie:Serveur VPS]] | ||
+ | [[Catégorie:Serveur dédié]] | ||
<br /> | <br /> | ||
<comments /> | <comments /> |
Version actuelle datée du 1 janvier 2021 à 04:02
fr:Replication PostgreSQL multi slaves he:PostgreSQL שכפול עבדים רב ro:PostgreSQL replicare sclavi multi ru:PostgreSQL репликации рабы multi pl:PostgreSQL replikacji niewolników multi ja:PostgreSQL のレプリケーション スレーブ マルチ ar:كيو النسخ المتماثل العبيد متعددة zh:PostgreSQL 复制奴隶多 de:PostgreSQL Replikation Sklaven multi nl:PostgreSQL replicatie slaven multi it:PostgreSQL replica schiavi multi pt:Multi de escravos de replicação PostgreSQL es:PostgreSQL replicación esclavos multi en:PostgreSQL replication slaves multi
Introduction
Cette page traite de la mise en place d'une réplication PostgreSQL streaming asynchrone avec un master et deux slaves. Nos slaves seront configurés comme hot standby, c'est à dire qu'il sera possible d'exécuter des requêtes (en lecture uniquement) sur ceux-ci.
Contexte de cette mise en place :
Nous avons 3 serveurs Debian 8 (mis à jour) :
Postgres01 (10.1.1.75) : sera notre Master
Postgres02 (10.1.1.90) : sera un slave
Postgres03 (10.1.1.199) : sera un second slave
Les commandes indiquées seront à effectuer en root quand elles sont précédées de "#" et en tant qu'utilisateur système postgres quand elles sont précédées de "$".
Installation de PostgreSQL et pré-configuration des trois serveurs
Toutes les commandes de cette partie sont à faire sur chacun des serveurs.
Dans un premier temps, il est recommandé d'avoir un fichier /etc/hosts peuplé avec les correspondances de chaque serveur, comme ceci (en adaptant avec les hostnames et adresses ip de vos propres serveurs) :
# cat /etc/hosts 127.0.0.1 localhost 10.1.1.75 postgres01 10.1.1.90 postgres02 10.1.1.199 postgres03
On ajoute le dépôt APT PostgreSQL :
# echo "deb http://apt.postgresql.org/pub/repos/apt/ jessie-pgdg main" > /etc/apt/sources.list.d/postgres.list
On importe la clé public de ce dépôt :
# gpg --keyserver pgpkeys.mit.edu --recv-key 7FCC7D46ACCC4CF8 && gpg -a --export 7FCC7D46ACCC4CF8 | apt-key add -
gpg: directory `/root/.gnupg' created
gpg: new configuration file `/root/.gnupg/gpg.conf' created
gpg: WARNING: options in `/root/.gnupg/gpg.conf' are not yet active during this run
gpg: keyring `/root/.gnupg/secring.gpg' created
gpg: keyring `/root/.gnupg/pubring.gpg' created
gpg: requesting key ACCC4CF8 from hkp server pgpkeys.mit.edu
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key ACCC4CF8: public key "PostgreSQL Debian Repository" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
OK
On met à jour le cache APT pour prendre en compte le dépôt :
# apt-get update
On installe le paquet postgresql (installera la dernière version stable soit la 9.5 au moment où sont écrites ces lignes) :
# apt-get install postgresql
On définit un mot de passe (de son choix mais sécurisé) et génère une paire de clé ssh (sans passphrase) pour l’utilisateur système postgres :
# passwd postgres
# su - postgres
$ ssh-keygen
On copie la clé ssh public de l’utilisateur postgres depuis et entre chaque serveur :
Depuis le premier serveur (postgres01 dans notre cas) vers le second (postgres02 pour nous) et troisisème (postgres03) :
root@postgres01:~# su - postgres
postgres@postgres01:~$ ssh-copy-id postgres02
postgres@postgres01:~$ ssh-copy-id postgres03
Depuis le second serveur vers le premier et troisième :
root@postgres02:~# su - postgres
postgres@postgres02:~$ ssh-copy-id postgres01
postgres@postgres02:~$ ssh-copy-id postgres03
Depuis le troisième serveur vers le premier et second :
root@postgres03:~# su - postgres
postgres@postgres03:~$ ssh-copy-id postgres01
postgres@postgres03:~$ ssh-copy-id postgres02
Configuration du Master
A faire uniquement sur le master (postgres01 dans notre cas) :
On crée le rôle/utilisateur de réplication :
# su - postgres
$ psql -c "CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT 2 ENCRYPTED PASSWORD '<mot de passe repuser>';"
Note : on définit une limite de connexion de 2 car nous avons 2 slaves
On édite le fichier de configuration principal de postgresql /etc/postgresql/9.5/main/postgresql.conf pour configurer les directives suivantes :
listen_addresses = '*'
wal_level = hot_standby
archive_mode = on
archive_command = 'rsync -av %p postgres@<ip du premier slave>:/var/lib/postgresql/wal_archive/%f'
max_wal_senders = 2
wal_keep_segments = 256
hot_standby = on
Note: nous activons l’archivage vers notre second serveur (adaptez l’adresse ip par celle de votre serveur) pour encore plus de précautions mais cela n'est pas une obligation. Nous définissons également les paramètres hot_standby, bien que ignorés sur un master, dans le cas où celui-ci devait être rétrogradé en slave dans l’avenir.
On édite maintenant le fichier d’authentification de postgresql /etc/postgresql/9.5/main/pg_hba.conf pour ajouter l’autorisation de notre utilisateur de réplication à se connecter depuis nos slaves soit la ligne suivante à la fin du fichier :
hostssl replication repuser <ip du réseau de vos serveurs>/24 md5
Veuillez adapter cette ligne en fonction du nom de votre utilisateur de réplication et du réseau (ou adresses ip respectives) de vos slaves
On redémarre le service postgresql pour prendre en compte notre configuration (en root) :
# systemctl restart postgresql
On s’assure que le service a démarré correctement :
root@postgres01:~# systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/lib/systemd/system/postgresql.service; enabled)
Active: active (exited) since Thu 2016-06-02 12:06:28 CEST; 22s ago
Process: 77056 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 77056 (code=exited, status=0/SUCCESS)
root@postgres01:~# ps -u postgres u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
postgres 77038 0.0 4.4 227300 21836 ? S 12:06 0:00 /usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/9.
postgres 77040 0.0 0.8 227300 4160 ? Ss 12:06 0:00 postgres: checkpointer process
postgres 77041 0.0 1.0 227300 4968 ? Ss 12:06 0:00 postgres: writer process
postgres 77042 0.0 1.7 227300 8776 ? Ss 12:06 0:00 postgres: wal writer process
postgres 77043 0.0 1.3 227728 6708 ? Ss 12:06 0:00 postgres: autovacuum launcher process
postgres 77044 0.0 0.6 82244 3392 ? Ss 12:06 0:00 postgres: archiver process
postgres 77045 0.0 0.8 82244 4244 ? Ss 12:06 0:00 postgres: stats collector process
Configuration des slaves
Sur le premier slave
On commence par stopper le service postgresql :
# systemctl stop postgresql
On édite le fichier de configuration principal de postgresql /etc/postgresql/9.5/main/postgresql.conf pour configurer les même directives que sur le master, en adaptant juste l’ip du premier slave par celle du second slave dans la commande rsync d’archivage si vous souhaitez l'activer soit :
listen_addresses = '*'
wal_level = hot_standby
archive_mode = on
archive_command = 'rsync -av %p postgres@<ip du second slave>:/var/lib/postgresql/wal_archive/%f'
max_wal_senders = 2
wal_keep_segments = 256
hot_standby = on
On édite maintenant le fichier d’authentification de postgresql /etc/postgresql/9.5/main/pg_hba.conf pour ajouter l’autorisation de notre utilisateur de réplication à se connecter depuis nos autres serveurs (cela ne servira que dans le cas où ce slave devrait promu master) :
hostssl replication repuser <ip du réseau de vos serveurs>/24 md5
Note : Avec cette configuration similaire à celle de notre master cela permettra de promouvoir facilement ce slave en tant que master en cas de besoin.
Pour les opérations ci-dessous, connectez-vous en tant qu’utilisateur système postgres :
# su – postgres
On crée le répertoire de destination des archives wal du master :
$ mkdir /var/lib/postgresql/wal_archive
On supprime le répertoire de données postgresql :
$ rm -rf /var/lib/postgresql/9.5/main
On fait le base backup (adaptez l’ip par celle de votre master et le nom de votre utilisateur de réplication), le mot de passe de votre utilisateur de réplication vous sera demandé :
$ pg_basebackup -h <ip de votre master> -D /var/lib/postgresql/9.5/main -U repuser -v -P --xlog
On configure la réplication en créant le fichier /var/lib/postgresql/9.5/main/recovery.conf avec les paramètres suivants :
standby_mode = on
primary_conninfo = 'host=<ip de votre master> port=5432 user=repuser password=<mot de passe de repuser> sslmode=require application_name=<hostname de votre slave>'
trigger_file = '/var/lib/postgresql/9.5/postgres.trigger'
Note : Le fichier trigger est le fichier qu’on ne crée que lorsque l’on veut que son slave arrête la réplication et commence à accepter les écritures c’est-à-dire quand on veut le promouvoir comme master. Avant de promouvoir un slave en cas de crash de son master, il faut s’assurer que le master initial ne remontera pas pour éviter toute corruption.
On repasse root et on démarre le service :
# systemctl start postgresql
On s’assure que le service a correctement démarré :
# systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
Loaded: loaded (/lib/systemd/system/postgresql.service; enabled)
Active: active (exited) since Thu 2016-06-02 12:53:42 CEST; 1min 6s ago
Process: 8894 ExecStart=/bin/true (code=exited, status=0/SUCCESS)
Main PID: 8894 (code=exited, status=0/SUCCESS)
# ps -u postgres u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
postgres 8878 0.0 4.4 227308 21892 ? S 12:53 0:00 /usr/lib/postgresql/9.5/bin/postgres -D /var/lib/postgresql/9.
postgres 8879 0.0 1.1 227376 5700 ? Ss 12:53 0:00 postgres: startup process recovering 00000001000000000000000
postgres 8880 0.0 0.8 227308 4140 ? Ss 12:53 0:00 postgres: checkpointer process
postgres 8881 0.0 1.0 227308 5236 ? Ss 12:53 0:00 postgres: writer process
postgres 8882 0.0 0.6 82252 3316 ? Ss 12:53 0:00 postgres: stats collector process
postgres 8883 0.0 1.7 238064 8520 ? Ss 12:53 0:00 postgres: wal receiver process streaming 0/30003E0
Si on se connecte à notre master, on peut déjà vérifier que notre réplication entre le master et le premier slave est fonctionnelle :
On se connecte sur notre master et on se connecte en utilisateur système postgres :
# su - postgres
Puis on se connecte à postgresql :
$ psql
On active l’affichage étendu et on vérifie notre réplication :
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 78879
usesysid | 16384
usename | repuser
application_name | postgres02
client_addr | 10.1.1.90
client_hostname |
client_port | 49009
backend_start | 2016-06-02 12:53:36.641823+02
backend_xmin |
state | streaming
sent_CRElocation | 0/30004C0
write_location | 0/30004C0
flush_location | 0/30004C0
replay_location | 0/30004C0
sync_priority | 0
sync_state | async
Notre réplication streaming asynchrone avec notre premier slave s’est bien faite. A ce stade on a une réplication Master/slave classique (un seul slave en streaming asynchrone)
Sur le second slave
On refait à l’identique ce qui a été fait sur le premier slave en adaptant évidemment son hostname dans le fichier recovery.conf et l’adresse ip dans la commande d’archivage dans le fichier de configuration principal si vous souhaitez également activer l'archivage sur ce second slave.
Vérification et test de notre réplication master multi slaves
On se connecte sur le master et on se loggue en utilisateur postgres :
# su – postgres
Puis on se connecte à postgresql :
$ psql
On active l’affichage étendu et on vérifie notre réplication :
postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid | 78879
usesysid | 16384
usename | repuser
application_name | postgres02
client_addr | 10.1.1.90
client_hostname |
client_port | 49009
backend_start | 2016-06-02 12:53:36.641823+02
backend_xmin |
state | streaming
sent_location | 0/5000140
write_location | 0/5000140
flush_location | 0/5000140
replay_location | 0/5000140
sync_priority | 0
sync_state | async
-[ RECORD 2 ]----+------------------------------
pid | 82725
usesysid | 16384
usename | repuser
application_name | postgres03
client_addr | 10.1.1.199
client_hostname |
client_port | 51754
backend_start | 2016-06-02 14:31:43.759683+02
backend_xmin |
state | streaming
sent_location | 0/5000140
write_location | 0/5000140
flush_location | 0/5000140
replay_location | 0/5000140
sync_priority | 0
sync_state | async
On a donc bien nos 2 réplications avec nos deux serveurs slaves (postgres02 et postgres03).
Toujours connecté à postgresql sur le master, on crée une base de données de test (ex : checkrep) pour confirmer que la réplication est fonctionnelle :
postgres=# CREATE DATABASE checkrep;
On vérifie que cette base de données s’est bien répliquée sur nos 2 slaves :
root@postgres02:~# su - postgres
postgres@postgres02:~$ psql
psql (9.5.3)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
checkrep | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
root@postgres03:~# su - postgres
postgres@postgres03:~$ psql
psql (9.5.3)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
checkrep | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
La base de données que nous avons crée sur notre master s’est donc bien automatiquement répliquée sur nos deux slaves.
Pour la supprimer, depuis le master :
postgres=# DROP DATABASE checkrep;
Activer l'actualisation automatique des commentaires