Réplication en flux avec un secondaire en hot standby (accepte les requêtes en lecture seule) – Part 4

Dans le précédent article nous avons abordé la réplication en flux (Streaming réplication) avec un secondaire en warm standby. On a donc un secondaire qui réplique les données du maitre, malheureusement le secondaire n’accepte pas les connexion. Il est tentant de lire les données du secondaire, ainsi on pourrait avoir des applicatifs qui envoient les requêtes d’écriture au maitre et les requêtes de lecture au secondaire ou encore effectuer les tâches de backup sur le secondaire afin de ne pas impacter le serveur de production.

Il est possible de mettre en place en hot standby, un serveur qui accepterait les requêtes en lecture et qui serait prêt à tout moment de passer en master.

Configuration du maître

Il faut passer le niveau des wal de archive à hot_standby :

Vu que nous avons du changer le niveau des wal on doit supprimer l’instance secondaire et la recréer.

Supprimer les ancien wal :

rm -rf /var/lib/postgresql/9.3/wal_archive/*

Activation du mode hot_standby dans le fichier postgres.conf :

hot_standby = on                        # "on" allows queries during recovery

Lancer le maitre, on peut voir dans la vue pg_settings que le paramètre a bien été pris en compte :

Lancer pg_start_backup

select pg_start_backup('hotstandby',true);

Recréer l’instance sur le secondaire :

une fois le rsync fini faire le pg_stop_backup

select pg_stop_backup();

Lancer le secondaire et controler :

On remarque la ligne qui indique que le secondaire accepte des connexions.

Quelques requêtes sur le secondaire :

Sur le maître :

Le sync_state est important, il nous indique que la réplication est asynchrone.  On peut définir ce comportement avec le paramètre synchronous_commit :

  • on (par défaut) : paramètre recommandé en général. Attention si vous spécifiez un esclave dans « synchronous_standby_names », les écritures seront synchrones avec l’esclave ce qui impacte fortement les performances. Le maitre indique que la transaction s’est bien passée seulement quand elle a été écrite sur l’esclave.
  • On peut choisir d’avoir des écritures synchrones sur le maitre et asynchrone sur les esclave en spécifiant le paramètre à « local ». Attention, j’ai remarqué que si on laisse l’esclave dans « synchronous_standby_names » la vue pg_stat_replication indique que les écritures sont toujours synchrones. Il faut donc enlever l’esclave de la ligne.
  • On peut aussi choisir le mode « remote_write » qui contrairement à ce qu’on peut penser, le maitre attend juste que l’esclave a bien pris en compte la transaction et il n’attends pas que la requête ait été écrite sur le disque de l’esclave. C’est un peu un compromis entre le synchrone et asynchrone.
  • Enfin la dernière valeur est off, à déconseiller car il y a un risque de perte de données en cas de crash du serveur.

synchronous_commit (enum)

Specifies whether transaction commit will wait for WAL records to be written to disk before the command returns a « success » indication to the client. Valid values are on, remote_write, local, and off. The default, and safe, setting is on. When off, there can be a delay between when success is reported to the client and when the transaction is really guaranteed to be safe against a server crash. (The maximum delay is three times wal_writer_delay.) Unlike fsync, setting this parameter to off does not create any risk of database inconsistency: an operating system or database crash might result in some recent allegedly-committed transactions being lost, but the database state will be just the same as if those transactions had been aborted cleanly. So, turning synchronous_commit off can be a useful alternative when performance is more important than exact certainty about the durability of a transaction. For more discussion see Section 29.3.

If synchronous_standby_names is set, this parameter also controls whether or not transaction commits will wait for the transaction’s WAL records to be replicated to the standby server. When set to on, commits will wait until a reply from the current synchronous standby indicates it has received the commit record of the transaction and flushed it to disk. This ensures the transaction will not be lost unless both primary and standby suffer corruption of their database storage. When set to remote_write, commits will wait until a reply from the current synchronous standby indicates it has received the commit record of the transaction and written it out to the standby’s operating system, but the data has not necessarily reached stable storage on the standby. This setting is sufficient to ensure data preservation even if the standby instance of PostgreSQL were to crash, but not if the standby suffers an operating-system-level crash.

When synchronous replication is in use, it will normally be sensible either to wait for both local flush to disk and replication of WAL records, or to allow the transaction to commit asynchronously. However, the setting local is available for transactions that wish to wait for local flush to disk, but not synchronous replication. If synchronous_standby_names is not set, the settings on, remote_write and local all provide the same synchronization level: transaction commits only wait for local flush to disk.

This parameter can be changed at any time; the behavior for any one transaction is determined by the setting in effect when it commits. It is therefore possible, and useful, to have some transactions commit synchronously and others asynchronously. For example, to make a single multistatement transaction commit asynchronously when the default is the opposite, issue SET LOCAL synchronous_commit TO OFF within the transaction.

 

Source : http://www.postgresql.org/docs/9.3/static/runtime-config-wal.html#GUC-SYNCHRONOUS-COMMIT

La fonction pg_last_xact_replay_timestamp() nous indique la date de la dernière transaction rejouée. Cette fonction retourne NULL si aucune transaction n’a été rejouée (ça arrive quand on vient de mettre en place la réplication et qu’il n’y a pas d’activité).

Quand on lance un pgbench sur le maître on peut avoir :

On peut jouer avec cette vue :

Durant un pgbench, on peut voir que le delta est très faible.

J’ai trouvé cette requête dans l’excellent plugin de bucardo pour nagios check_postgres :

https://github.com/bucardo/check_postgres/

Grace à cette requête on peut voir les derniers journaux rejoués et le temps depuis la dernière transaction rejouée.

Si on lance au même moment cette requête sur le maitre :

On observe que les serveurs en sont au même fichier journal.

Share

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *