jeudi 23 février 2012

Construction d'une standby à froid (Warm) en PostgreSQL 8.2

La version Postgresql 8.2 introduit une nouvelle fonctionnalité de haute disponibilité, le log shipping.

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

  1. 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.

    1. Sauvegarde de la base de Production
    Comme sur Oracle, il est possible de signaler à l'instance Postgres que nous allons débuter un backup afin qu'un point de cohérence puisse être positionné sur le WAL courant.

    [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
    1. 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.
    2. 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:  starting archive recovery
    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