Le but est d'avoir un serveur de secours en attente permanente, qui va rejouer en quasi temps réel les journaux
de transaction (appelés WALs pour Write Ahead Log'') du serveur primaire, et qui est prêt à prendre le relai à tout
moment, en cas d'incident sur le serveur primaire.
Deux serveurs sont donc nécessaires :
- Un serveur primaire (maître) qui archive les WALs et les envoie sur le serveur de secours (esclave)
- Un serveur de secours qui lui est en mode recovery permanent et les rejoue dès leur réception.
Un lien réseau entre les deux serveurs doit donc exister, pour que l'envoi des WALs puisse se faire.
La réplication concerne l'instance Postgresql entière, c'est-à-dire toutes les bases de données Postgresql existantes sur le serveur primaire.
Pré-requis
- Les serveurs Postgresql doivent être en même niveau de version.
- Les user et group postgres doivent être identiques (UID et GID) si l'on utilise des volumes NFS.
- L'arborescence doit être identique (pas obligatoire mais fortement conseillé)
Serveur de Production
- Mise en place de l'archivage : Cette étape est comparable à mettre une base de données Oracle en mode archivelog et de définir une commande système sur l'évènement d'écriture du WAL.
Pour le mettre en place, il faut modifier le fichier postgresql.conf se trouvant dans le répertoire data de l'instance Postgresql.
# - Archiving -
archive_mode = on
# allows archiving to be done
# (change requires restart)
archive_command = 'cp %p /nfs_wal/%f'
# command to use to archive a logfile segment
archive_timeout = 60
# force a logfile segment switch after this
# number of seconds; 0 disables
La variable archive_command stocke la commande système executée pour l'archivage, cependant cela peut être un script plus complexe permettant d'archiver les WAL sur un autre serveur ou sur bande.
Dans le cas présent, le WAL est copié sur un volume NFS du serveur de secours.
L'activation de la variable archive_mode implique un redémarrage de l'instance.
- Sauvegarde de la base de Production
[root@prod-server 17022]# psql -U postgres
psql (8.4.7.20)
Type "help" for help.
postgres=# SELECT pg_start_backup('Standby_construct');
pg_start_backup
----------------
18/D6521288
(1 row)
Passé cette étape (qui peut être plus ou moins longue), il est donc possible d'effectuer un backup système de la base.
Dans le cadre de la construction d'un serveur de standby un simple rsync fera amplement l'affaire.
[root@prod-server] rsync -avz . root@stb-server:`pwd`/
Il est important de noter qu'il faut donc copier le répertoire data mais aussi tous les tablespaces créés ailleurs sur le disque.
En fin de copie signaler à postgres la fin du backup.
[root@prod-server 17022]# psql -U postgres
psql (8.4.7.20)
Type "help" for help.
postgres=# SELECT pg_stop_backup();
pg_stop_backup
----------------
18/D6521299
(1 row)
Serveur de secours
- Modification de l’environnement : Editer le fichier postgresql.conf présent dans le repertoire data et commenter la partie archivage mise en place précédemment sur le serveur de production.
Ensuite nous allons mettre en place le recovery et le traitement des WALs archivés.
Pour ce faire, il faut créer un fichier recovery.conf dans le repertoire data:
restore_command = 'pg_standby -s 5 -t $PGDATA/do_failover /data/PG/wal %f %p'
recovery_end_command = 'rm -f $PGDATA/do_failover'
restore_command correspond à la commande utilisée pour appliquer les wals.
L'option '-s' correspond au temps de pause en deux checks, '-t' fait référence au fichier "verrou" permettant de sortir du recover et d'ouvrir la base.
* %f : nextwalfile, emplacement de stockage des wals issus de la base primaire.
* %p : xlogfilepath, repertoire local pg_xlog
* %r : restartwalfile, permet la supression du wal traité dans archivelocation (optionnel)
pg_standby [ option ... ] archivelocation nextwalfile xlogfilepath [ restartwalfile ]
recovery_end_command correspond à la commande exécutée lors de la sortie du recover. - Démarrage de la standby : Il est possible de démarrer l'instance Postgres via le script présent dans /etc/init.d ou bien en tant qu'utilisateur UNIX postgres :
-bash-3.2$ pg_ctl start
server starting
-bash-3.2$ 2011-08-19 08:01:34 GMTLOG:
** EnterpriseDB Dynamic Tuning Agent ********************************************
* System Utilization: 66 % *
* Database Version: 8.4.7.20 *
* Operating System Version: *
* Number of Processors: 0 *
* Processor Type: *
* Processor Architecture: *
* Database Size: 0.1 GB *
* RAM: 15.7 GB *
* Shared Memory: 16054 MB *
* Max DB Connections: 103 *
* Autovacuum: on *
* Autovacuum Naptime: 60 Seconds *
* InfiniteCache: off *
* InfiniteCache Servers: 0 *
* InfiniteCache Size: 0.000 GB *
*********************************************************************************
2011-08-19 10:01:35 CESTLOG: loaded library "$libdir/edb_gen"
2011-08-19 10:01:35 CESTLOG: loaded library "$libdir/plugins/plugin_debugger"
2011-08-19 10:01:35 CESTLOG: loaded library "$libdir/plugins/plugin_spl_debugger"
-bash-3.2$
-bash-3.2$ ps auwx | grep postgres
root 24312 0.0 0.0 101036 1340 pts/1 S 09:57 0:00 su - postgres
postgres 24313 0.0 0.0 66040 1540 pts/1 S 09:57 0:00 -bash
postgres 24379 2.1 0.2 1837044 42520 pts/1 S 10:01 0:00 /opt/PostgresPlus/8.4AS/bin/edb-postgres
postgres 24380 0.0 0.0 105488 1508 ? Ss 10:01 0:00 postgres: logger process
postgres 24381 0.0 0.0 1837868 1672 ? Ss 10:01 0:00 postgres: startup process
postgres 24382 0.0 0.0 30456 1792 ? S 10:01 0:00 /opt/PostgresPlus/8.4AS/bin/pg_standby -d -s 5 -t /opt/PostgresPlus/8.4AS/data/do_failover /data/PG/wal 00000001.history pg_xlog/RECOVERYHISTORY 000000000000000000000000
postgres 24386 0.0 0.0 65572 968 pts/1 R+ 10:01 0:00 ps auwx
postgres 24387 0.0 0.0 61132 732 pts/1 S+ 10:01 0:00 grep postgres
-bash-3.2$ pg_ctl status
pg_ctl: server is running (PID: 24379)
/opt/PostgresPlus/8.4AS/bin/edb-postgres
-bash-3.2$
On constate ici que l'instance postgres a démarré un processus pg_standby en charge de l'application des WALs.
Pour vérifier que la base reste bien synchronisée, regarder le log le plus récent dans data/pg_log, on doit voir une sortie de ce type :
2011-08-18 16:30:28 CESTLOG: restore_command = '/opt/PostgresPlus/8.4AS/bin/pg_standby -d -s 60 -t /opt/PostgresPlus/8.4AS/data/do_failover /data/PG/wal %f %p %r'
2011-08-18 16:30:28 CESTLOG: recovery_end_command = 'rm -f /opt/PostgresPlus/8.4AS/data/do_failover'
Trigger file : /opt/PostgresPlus/8.4AS/data/do_failover
Waiting for WAL file : 00000001.history
WAL file path : /data/PG/wal/00000001.history
Restoring to : pg_xlog/RECOVERYHISTORY
Sleep interval : 60 seconds
Max wait interval : 0 forever
Command for restore : cp "/data/PG/wal/00000001.history" "pg_xlog/RECOVERYHISTORY"
Keep archive history : 000000000000000000000000 and later
running restore :cp: cannot stat `/data1/EDB/wal/00000001.history': No such file or directory
cp: cannot stat `/data1/EDB/wal/00000001.history': No such file or directory
2011-08-18 16:30:28 CESTLOG:
** EnterpriseDB Dynamic Tuning Agent ********************************************
* System Utilization: 66 % *
* Database Version: 8.4.7.20 *
* Operating System Version: *
* Number of Processors: 0 *
* Processor Type: *
* Processor Architecture: *
* Database Size: 21.6 GB *
* RAM: 15.7 GB *
* Shared Memory: 16054 MB *
* Max DB Connections: 103 *
* Autovacuum: on *
* Autovacuum Naptime: 60 Seconds *
* InfiniteCache: off *
* InfiniteCache Servers: 0 *
* InfiniteCache Size: 0.000 GB *
*********************************************************************************
2011-08-18 16:30:29 CESTFATAL: the database system is starting up
running restore : OK
2011-08-18 16:31:27 CESTLOG: restored log file "000000010000001B0000009E" from archive
Trigger file : /opt/PostgresPlus/8.4AS/data/do_failover
Waiting for WAL file : 000000010000001B0000009F
WAL file path : /data1/EDB/wal/000000010000001B0000009F
Restoring to : pg_xlog/RECOVERYXLOG
Sleep interval : 5 seconds
Max wait interval : 0 forever
Command for restore : cp "/data/PG/wal/000000010000001B0000009F" "pg_xlog/RECOVERYXLOG"
Keep archive history : 000000010000001B00000096 and later
WAL file not present yet. Checking for trigger file...
WAL file not present yet. Checking for trigger file...
Failover / Switchover
Postgresql ou EnterpriseDB ne gère pas de mécanisme de switchover.
La seule possibilité est de promouvoir manuellement le serveur de secours via la création du trigger file définit précédemment dans la commande restore_command, ici ''/opt/PostgresPlus/8.4AS/data/do_failover''.
Le fait de créer ce fichier sur la standby stoppera l'application des WALs et ouvrira la base de données en lecture écriture.
Limites
- Il n'est pas possible de faire de switchover
- Lors d'un failover l'ancienne production est considérée comme perdue, à restaurer
- Il n'est pas possible d'ouvrir cette base en lecture seule
- Lors d'un failover les transactions du WAL courant sur la production sont perdues
Aucun commentaire:
Enregistrer un commentaire