Mettre en Place Une Streaming Replication Avec PostgreSQL 10

!
Warning: This post is over 365 days old. The information may be out of date.

Dans ce post, je vais vous expliquer comment mettre en place une streaming replication avec PostgreSQL 10. Par contre, je n’expliquerais pas comment installer PostgreSQL donc je suppose que cela est déjà le cas.

Mon setup est le suivant :

  • master serveur : ip 172.17.0.2
  • slave serveur : ip 172.17.0.3

On sécurise et on met en place SSL

Cette étape n’est pas obligatoire mais elle est recommandée. Si vous avez déjà un certificat SSL, vous pouvez passer l’étape 1.

  • Génération d’un certificat auto signé, voir mon post précédent

  • Mettre en place SSL sous PostgreSQL:

    1. Copiez votre clef privée et votre certificat dans le répertoire de votre choix. Faîtes attention que l’utilisateur faisant tourner postgresql puisse les lire (généralement postgres sous Debian ou _postgresql sous OpenBSD.

    2. Editez le fichier postgresql.conf et changez ces lignes :

      ssl = on
      ssl_cert_file = '/etc/ssl/postgresql/cert/server.crt'
      ssl_key_file = '/etc/ssl/postgresql/private/server.key'
      

      Bien sûr, changez le répertoire par celui que vous avez choisi. Si vous ne spécifiez pas de répertoire mais seulement le nom du fichier, PostgreSQL ira les chercher dans le répertoire PGDATA.

Configuration du master

  • Création d’un rôle dédié à la réplication (au passage on en profite pour utiliser la nouvelle méthode d’authentification) :

    postgres=# CREATE ROLE replicate WITH REPLICATION LOGIN ;
    CREATE ROLE
    postgres=# set password_encryption = 'scram-sha-256';
    SET
    postgres=# \password replicate
    Enter new password: 
    Enter it again:
    
  • On vérifie que le serveur PostgreSQL écoute sur la bonne interface. Editez le fichier postgresql.conf et changez cette ligne :

    #listen_addresses = 'localhost'
    

    par quelque chose comme

    listen_addresses = '*'
    # ou
    listen_addresses = 'xxx.xxx.xxx.xxx'
    
  • Changez les paramêtres liés à la streaming replication dans le fichier postgresql.conf

    wal_level = replica
    max_wal_senders = 3 # max number of walsender processes
    wal_keep_segments = 64 # in logfile segments, 16MB each; 0 disables
    

Si vous pensez que le nombre que vous avez mis dans wal_keep_segments est suffisant, vous pouvez vous arrêter ici. Mais en cas d’incertitude, il vaut mieux configurer le archive_mode pour stocker les WAL (si jamais vous avez un pic d’écriture et que le slave ne va pas assez vite ou si votre slave doit être arrêté pendant une longue période)

```bash
archive_mode = on
archive_command = 'rsync -a %p postgres@slave:/home/postgresql_wal/%f' 
   # placeholders: %p = path of file to archive
   #               %f = file name only
```

Le paramêtre archive_command va copier les segments WAL dans un répertoire qui doit être accessible par le serveur slave. Dans l’exemple ci dessus, j’ai utilisé rsync pour les copier directement sur le slave. Rien ne vous empêche de les copier sur un NFS aussi.

**Attention** : Si comme moi, vous utilisez *rsync*, n'oubliez pas de configurer le ssh pour utiliser l"authentification par clef !!
  • Maintenant nous allons autoriser notre slave à se connecter au master. Editez le fichier pg_hba.conf et ajoutez une ligne comme ceci :

    hostssl		replication		replicate		xxx.xxx.xxx.xxx/yy		scram-sha-256
    

    Remplacez xxx.xxx.xxx.xxx/yy par l’ip de votre slave ou par un subnet si vous pensez mettre plusieurs slaves.

  • Redémarrez le service postgresql sur le master

Configuration du slave

Maintenant que le master est prêt, il est temps de configurer le slave.

  • On arrête postgresql sur le slave

  • Editez le fichier postgresql.conf et pg_hba.conf et reportez les changements faits sur le master (comme ça, le slave pourra repartir comme un master en cas de soucis).

  • Editez le fichier postgresql.conf et on change cette ligne :

    hot_standby = on
    
  • Maintenant allez dans votre répertoire PGDATA et supprimez tous les fichiers. ATTENTION : si les fichiers postgresql.conf et pg_hba.conf sont dans ce répertoire, vous devez les sauvegarder (même chose pour les fichiers de certificat).

  • Maintenant nous allons copier les données du master grâce à la commande pg_basebackup. Vous devez lancer cette commande en tant qu’utilisateur qui fait tourner le service postgresql (postgres sous Debian, _postgresql sous OpenBSD par exemple)

    # su - postgres
    $ pg_basebackup -h 172.17.0.2 -D /var/lib/postgresql/10/main/ -P -U replicate --wal-method=stream
    Password: 
    23908/23908 kB (100%), 1/1 tablespace
    

Et voila, toutes les données sont copiées sur le slave. Si vous avez du sauvegarder les fichiers postgresql.conf et pg_hba.conf, il faut les restaurer.

  • Maintenant il faut créer un fichier recovery.conf dans votre répertoire PGDATA

    standby_mode          = 'on'
    primary_conninfo      = 'host=172.17.0.2 port=5432 user=replicate password=MySuperPassword'
    trigger_file = '/tmp/MasterNow'
    #restore_command = 'cp /home/postgresql_wal/%f "%p"'
    

Voici une expliquation pour chaque ligne :

* standby_mode=on : indique à postgresql qu'il faut démarrer en mode standby
* primary_conninfo : les paramètres à utiliser pour se connecter au master
* trigger_file : si ce fichier existe, la réplication s'arrête et postgresql va devenir maître (donc acceptera les écritures)
* restore_command : cette ligne n'est nécessaire que si vous avez utilisé la commande *archive_mode* sur le master
  • Démarrez le serveur postgresql

    2018-03-11 19:08:55.777 UTC [8789] LOG:  listening on IPv4 address "127.0.0.1", port 5432
    

2018-03-11 19:08:55.777 UTC [8789] LOG: could not bind IPv6 address “::1”: Cannot assign requested address 2018-03-11 19:08:55.777 UTC [8789] HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. 2018-03-11 19:08:55.786 UTC [8789] LOG: listening on Unix socket “/var/run/postgresql/.s.PGSQL.5432” 2018-03-11 19:08:55.820 UTC [8790] LOG: database system was interrupted; last known up at 2018-03-11 18:58:20 UTC 2018-03-11 19:08:56.023 UTC [8790] LOG: entering standby mode 2018-03-11 19:08:56.034 UTC [8790] LOG: redo starts at 0/4000028 2018-03-11 19:08:56.039 UTC [8790] LOG: consistent recovery state reached at 0/40000F8 2018-03-11 19:08:56.040 UTC [8789] LOG: database system is ready to accept read only connections 2018-03-11 19:08:56.071 UTC [8794] LOG: started streaming WAL from primary at 0/5000000 on timeline 1 ```

Et voilà, votre serveur slave est prêt !
  • On peut voir l’utilisateur replicate sur le master :

    postgres=# select * from pg_stat_activity  where usename = 'replicate' ;
    

-[ RECORD 1 ]+++-+++++++++++++++++++++++++++++++ datid | datname | pid | 9134 usesysid | 16384 usename | replicate application_name | walreceiver client_addr | 172.17.0.3 client_hostname | client_port | 45234 backend_start | 2018-03-11 19:08:56.049113+00 xact_start | query_start | state_change | 2018-03-11 19:08:56.071363+00 wait_event_type | Activity wait_event | WalSenderMain state | active backend_xid | backend_xmin | query | backend_type | walsender ```

Related Posts