Log shipping

From Tuxunix
Jump to: navigation, search

Mise en place du log shipping (Installation sous RH6 64Bits)

Installation de Postgresql sur les deux serveurs

#> yum install postgresql-server-8.4.11-1.el6_2.x86_64

Installation de pg_standby sur le serveur de secours

  • Si vous avez installer postgresql en package, il vous faudra le contrib pour avoir le pg_standby module indispensable pour la réplication des journaux de transaction.
#> yum install postgresql-contrib.x86_64

Transfert de fichiers depuis le serveur primaire vers le serveur de secours

  • Server 1
#> su - postgres
$> ssh-keygen
-bash-4.1$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/pgsql/.ssh/id_rsa):
Created directory '/var/lib/pgsql/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /var/lib/pgsql/.ssh/id_rsa.
Your public key has been saved in /var/lib/pgsql/.ssh/id_rsa.pub.
The key fingerprint is:
15:1a:57:09:24:26:ff:f6:b8:5f:f7:42:18:ce:d6:8c postgres@Server1
The key's randomart image is:
+--[ RSA 2048]----+
|      . +.=o..   |
|       + = ..    |
|        o .      |
|         o  .    |
|        S oo *   |
|         . oE +  |
|          ..... .|
|           . ....|
|          ...  ..|
+-----------------+
-bash-4.1$ ssh-copy-id
Usage: /usr/bin/ssh-copy-id [-i [identity_file]] [user@]machine
-bash-4.1$ ssh-copy-id postgres@Server2
The authenticity of host 'ecriteltest2 (X.X.X.X)' can't be established.
RSA key fingerprint is 39:c7:71:9b:6c:b0:9d:2e:7c:4c:d2:d1:3d:fb:e0:02.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ecriteltest2,X.X.X.X' (RSA) to the list of known hosts.
postgres@ecriteltest2's password:
Now try logging into the machine, with "ssh 'postgres@Server2'", and check in:

 .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

Configuration du serveur primaire pour l'envoi des WALs (write ahead log)

  • PostgreSQL™ maintient en permanence des journaux WAL (write ahead log) dans le sous-répertoire pg_xlog/ du répertoire de données du cluster.
  • Editer sur le serveur primaire le fichier de configuration "postgresql.conf" :
archive_mode = on
archive_command = 'scp %p postgres@srv2:/var/lib/pgsql/xlogServer1/%f'
archive_timeout = 300 # on force l'archivage au bout de 300 secondes au maximum quand au moins une transaction a été committée
log_destination = 'stderr'
log_directory = 'pg_log'
log_filename = 'postgresql.log'

et

Sur le serveur 2 :

su - postgres -c 'mkdir -p /var/lib/pgsql/xlogServer1'
  • Démarrer Postgresql
#>/etc/init.d/postgresql start
  • Vérifier que les WALs sont bien présent et envoyés sur le secondaire :

Serveur1 :

#> ls -al data/pg_xlog/

Serveur2 :

#> ls -al /var/lib/pgsql/xlogServer1

Préparation du serveur de secondaire

  • Mettre le Postgresql en mode backup sur le serveur primaire, puis recopier l'arborescence de chaque tablespace sur le serveur de secours, au même emplacement.

Sur server1 :

[postgres@srv1] psql -c "select pg_start_backup('pour_init_srv2')"
pg_start_backup
-----------------
0/4000020
(1 row)
[postgres@srv1] tar zcvf /tmp/bkp_pour_init_srv2.tar.gz data
[postgres@srv1] psql -c "select pg_stop_backup()"
pg_stop_backup
----------------
0/4000084
(1 row)
[postgres@srv1] scp /tmp/bkp_pour_init_srv2.tar.gz postgres@srv2:/tmp

Sur server2 :

[postgres@srv2] cd /
[postgres@srv2] tar zxvf /tmp/bkp_pour_init_srv2.tar.gz
  • Editer le fichier de configuration sur le serveur 2 :
archive_mode = '0'
archive_command =  # double quote
archive_timeout = 0
log_destination = 'stderr'
log_directory = 'pg_log'
log_filename = 'postgresql.log'

Créer sur le serveur de secours un fichier "data/recovery.conf" (pour pg_standby, ce fichier doit être à la racine du répertoire /db/data) contenant la ligne suivante (toute la commande est sur une seule ligne) :

restore_command='/usr/bin/pg_standby -d -k 255 -t /var/lib/pgsql/stoprestore.file /var/lib/pgsql/xlogServer1 %f %p 2>> /var/log/pg_standby.log'

Ainsi, le fichier /db/pg_standby.log contiendra en permanence les informations sur les WALs rejoués, et celui en attente d'être rejoué. Pour stopper la réplication, il suffira simplement de créer sur le serveur de secours le fichier /home/postgres/stoprestore.file

#> touch /var/log/pg_standby.log && chmod 777 /var/log/pg_standby.log

Synchronisation du serveur secondaire

  • Démarrer le serveur postgres sur le serveur 2 :
#> /etc/init.d/postgresql start

Vous devez voir apparaitre le processus "pg_standby"

#> ps faux
postgres 24863  0.0  0.0 216240  1924 ?        Ss   10:38   0:00  \_ postgres: startup process
postgres 24864  0.0  0.0 106044  1288 ?        S    10:38   0:00      \_ sh -c /usr/bin/pg_standby -d -k 255 -t /var/lib/pgsql/stoprestore.file /var/lib/pgsql/data/pg_xlog 00000001.histor
postgres 24865  0.0  0.1  64564  2328 ?        S    10:38   0:00          \_ /usr/bin/pg_standby -d -k 255 -t /var/lib/pgsql/stoprestore.file /var/lib/pgsql/data/pg_xlog 00000001.history
  • Vérifier les logs :
#> tail -f /var/log/pg_standby.log
cp: impossible d'évaluer « /var/lib/pgsql/xlogServer1/00000001.history »: Aucun fichier ou dossier de ce type
not restored
history file not found
Trigger file            : /var/lib/pgsql/stoprestore.file
Waiting for WAL file    : 0000000100000000000000C9.00000020.backup
WAL file path           : /var/lib/pgsql/xlogServer1/0000000100000000000000C9.00000020.backup
Restoring to            : pg_xlog/RECOVERYHISTORY
Sleep interval          : 5 seconds
Max wait interval       : 0 forever
Command for restore     : cp "/var/lib/pgsql/xlogServer1/0000000100000000000000C9.00000020.backup" "pg_xlog/RECOVERYHISTORY"
Keep archive history    : No cleanup required
running restore         : OK
Trigger file            : /var/lib/pgsql/stoprestore.file
Waiting for WAL file    : 0000000100000000000000C9
WAL file path           : /var/lib/pgsql/xlogServer1/0000000100000000000000C9
Restoring to            : pg_xlog/RECOVERYXLOG
Sleep interval          : 5 seconds
Max wait interval       : 0 forever
Command for restore     : cp "/var/lib/pgsql/xlogServer1/0000000100000000000000C9" "pg_xlog/RECOVERYXLOG"
Keep archive history    : No cleanup required
running restore         : OK
Trigger file            : /var/lib/pgsql/stoprestore.file
Waiting for WAL file    : 0000000100000000000000CA
WAL file path           : /var/lib/pgsql/xlogServer1/0000000100000000000000CA
Restoring to            : pg_xlog/RECOVERYXLOG
Sleep interval          : 5 seconds
Max wait interval       : 0 forever
Command for restore     : cp "/var/lib/pgsql/xlogServer1/0000000100000000000000CA" "pg_xlog/RECOVERYXLOG"
Keep archive history    : No cleanup required
WAL file not present yet. Checking for trigger file...
WAL file not present yet. Checking for trigger file...


Le serveur 2 est va maintenant rejoué les WALs envoyés par le serveur 1 ;)


En cas de crash du serveur1

  • Il vous faut ajouter le fichier "stoprestore.file" sur le serveur 2 :
#> su - postgres
$> touch stoprestore.file (Chemin absolue /var/lib/pgsql/stoprestore.file)
  • Ensuite dans les logs vous verrez ceci :
trigger file found: smart failover
Trigger file            : /var/lib/pgsql/stoprestore.file
Waiting for WAL file    : 0000000100000000000000CA
WAL file path           : /var/lib/pgsql/xlogServer1/0000000100000000000000CA
Restoring to            : pg_xlog/RECOVERYXLOG
Sleep interval          : 5 seconds
Max wait interval       : 0 forever
Command for restore     : cp "/var/lib/pgsql/xlogServer1/0000000100000000000000CA" "pg_xlog/RECOVERYXLOG"
Keep archive history    : No cleanup required
trigger file found: smart failover
running restore         : OK
  • Vous pouvez maintenant requêter sur le secondaire avec les données à jour.

Enfin pour réduire le risque de perte de donnée vous pouvez diminuer le paramétre archive_timeout = 300 sur le serveur 1 (ici le transfert ce fait toutes les 5mins).

Pour repartir sur le serveur1

Reprendre le tuto en sens inverse, ou faite une restauration sur le serveur des données du 2. Puis supprimer le fichier "stoprestore.file" sur le serveur2 avant de redémarrer les 2 pgsql.