Vous n'êtes pas identifié(e).
Bonjour,
J'ai monté une maquette PG 9 pour évaluer la nouvelle feature de streaming replication. Je souhaite disposer d'un moyen de remonter très rapidement une base, avec un minimum de pertes de transactions, donc pour ça, la réplication par flux me semble toute indiquée. J'ai donc monté un master sur lequel vient se connecter un slave en hot standby. J'ai bootstrappé le slave et faisant un backup comme indiqué en §24.3.2. La réplication se fait correctement (par contre, bizarrement sur le slave j'ai l'impression que le recovery.conf n'a pas été renommé en recovery.done...)
J'ai deux questions.
Je constate dans un premier temps qu'à l'issue du restore, les fichiers WAL sont toujours shippés par le primary vers mon slave. Mis à part pour "faire le PITR", êtes-vous d'accord avec moi pour dire que faire du log-shipping ne me sert (dans mon cas) plus a rien puisque le streaming fait deja jouer les transactions sur le slave via une connexion TCP/IP (donc pas besoin d'avoir ces WAL en backup non ?) ? L'inconvénient est qu'on va arriver rapidement à saturer le disque à conserver des WAL non ? J'imagine que l'utilisation standard est de faire un backup tous les x jours et donc ne ne conserver que x jours de WAL, c'est ça ?
D'autre part, je me pose une question sur le fonctionnement attendu lorsque le serveur slave tombe, et que le log-shipping n'est pas utilisé (uniquement le streaming l'étant).
Je me demandais comment se récupère le standby quand il revient :
- il tente de rejouer ses WAL en local (il n'y en a pas dans mon cas, étant donné que je ne fais pas de log shipping)
- il tente de rejouter le pg_xlog (éventuellement il y a des trucs, qui sont des transactions streamées depuis le master mais pas encore commitées dans la base slave au moment de l'interruption)
- il se reconnecte au master et remet en place la réplication par streaming. C'est là où intervient ma question : le slave sait-il reprendre le streaming là où il en était [dans ce cas, on tombe bien dans le cas du keep_wal_segments a configurer proprement pour s'assurer un historique suffisant ?) ou bien a-t'on forcément un gap irrécupérable ? On est d'accord que je n'ai pas besoin du 'restore_command' dans le recovery.conf ?
Merci pour vos lumières !
Hors ligne
Point par point :
- Normal qu'il n'ait pas renommé recovery.conf en recovery.done: la récupération est toujours en cours, vous streamez toujours des journaux du maître vers l'esclave. Vous n'aurez un recovery.done que le jour où vous ouvrirez la base secondaire en lecture écriture (en créant le fichier trigger par exemple)
- Les fichiers WAL sont toujours transférés: le maître ne sait pas où en est l'esclave. Seul l'esclave sait ce qu'il a à faire. Le maître continue donc à archiver, en utilisant votre script d'archivage (qui, je le présume, recopie les fichiers). Ce mécanisme a un autre intérêt: si vous aviez une déconnexion de la réplication pendant 'trop longtemps', il se pourrait que la streaming replication ne puisse plus être utilisée: les journaux seraient archivés, et donc plus accessibles par le maître, pour être mis à disposition de l'esclave, via SR. Vous serez donc très content, ce jour là, d'avoir encore les fichiers archivés: il suffira de les rejouer jusqu'au dernier, puis reprendre la SR (tout cela est automatique).
- Comment il se récupère : répondu au dessus: l'algo est expliqué dans la doc, mais grosso modo c'est : essayer d'appliquer les archives aussi loin que possible, puis se connecter en SR au maître et appliquer les journaux via SR, puis si échec repasser en mode 'application' d'archive, etc… en boucle (avec une tempo quand même). Il vous faut donc le log shipping, si vous voulez pouvoir vous sortir de ce cas de figure.
- Le slave sait reprendre le streaming où il en était, SI LE WAL EST ENCORE EN LIGNE. Sinon, il faut qu'il aille le chercher dans l'«archive», via sa restore_command. Ça peut très bien être cette 'restore_command' qui va chercher le fichier sur le maître, si vous ne voulez transférer qu'au moment où ça devient nécessaire. Vous pouvez aussi limiter ce cas de figure en augmentant le paramètre wal_keep_segments, qui demande au maître de garder davantage de fichiers WAL en ligne, justement dans l'optique de ce cas de figure.
- On n'est pas d'accord pour l'absence de restore_command dans le recovery.conf: vous serez content, justement dans ces cas de figure, de l'avoir et d'avoir cette faculté de 'réparation automatique'
Marc.
Hors ligne
- Normal qu'il n'ait pas renommé recovery.conf en recovery.done: la récupération est toujours en cours, vous streamez toujours des journaux du maître vers l'esclave. Vous n'aurez un recovery.done que le jour où vous ouvrirez la base secondaire en lecture écriture (en créant le fichier trigger par exemple)
Effectivement, vu sous cet angle là je comprends mieux. Dans mon esprit, la récupération ne concernait que la relecture des fichiers WAL locaux, pas le streaming via socket.
- Les fichiers WAL sont toujours transférés: le maître ne sait pas où en est l'esclave. Seul l'esclave sait ce qu'il a à faire. Le maître continue donc à archiver, en utilisant votre script d'archivage (qui, je le présume, recopie les fichiers). Ce mécanisme a un autre intérêt: si vous aviez une déconnexion de la réplication pendant 'trop longtemps', il se pourrait que la streaming replication ne puisse plus être utilisée: les journaux seraient archivés, et donc plus accessibles par le maître, pour être mis à disposition de l'esclave, via SR. Vous serez donc très content, ce jour là, d'avoir encore les fichiers archivés: il suffira de les rejouer jusqu'au dernier, puis reprendre la SR (tout cela est automatique).
Assurément, mais cela représente un coût de stockage énorme : avec un archive_timeout a 1800, pour une base de 300Mo, dans ma configuration actuelle en trois jours de tests, et pour une base avec un volume d'activité plutot faible j'en suis deja a plus de 13 Go de WAL. Je pense baisser la taille des segments de 16Mo à par exemple 2Mo. D'ailleurs pourquoi les segments WAL dont on force le flush avec archive_timeout doivent ils nécessairement faire 16 Mo (sauf si configuré autrement bien sur) ? La prix a payer pour pouvoir se dire "je peux restaurer ma base au pire telle qu'elle etait a t-1800secondes" n'est-il pas un peu cher ?
- Comment il se récupère : répondu au dessus: l'algo est expliqué dans la doc, mais grosso modo c'est : essayer d'appliquer les archives aussi loin que possible, puis se connecter en SR au maître et appliquer les journaux via SR, puis si échec repasser en mode 'application' d'archive, etc… en boucle (avec une tempo quand même). Il vous faut donc le log shipping, si vous voulez pouvoir vous sortir de ce cas de figure.
Et oui, il me faut le log shipping !
- Le slave sait reprendre le streaming où il en était, SI LE WAL EST ENCORE EN LIGNE. Sinon, il faut qu'il aille le chercher dans l'«archive», via sa restore_command. Ça peut très bien être cette 'restore_command' qui va chercher le fichier sur le maître, si vous ne voulez transférer qu'au moment où ça devient nécessaire. Vous pouvez aussi limiter ce cas de figure en augmentant le paramètre wal_keep_segments, qui demande au maître de garder davantage de fichiers WAL en ligne, justement dans l'optique de ce cas de figure.
Ah, je n'avais pas bien compris, au temps pour moi ! Pour moi, le slave commençait par relire ses WAL en local (ceux archivés par le maitre), puis redémarrait le streaming, mais que le streaming ne pouvait pas "revenir en arrière" en relisant les journaux du maître. C'est bien plus clair maintenant !
Merci beaucoup Marc pour toutes ces précisions qui couplées à une doc somme toute vraiment très bien m'ont bien éclairci l'esprit.
Hors ligne
Assurément, mais cela représente un coût de stockage énorme : avec un archive_timeout a 1800, pour une base de 300Mo, dans ma configuration actuelle en trois jours de tests, et pour une base avec un volume d'activité plutot faible j'en suis deja a plus de 13 Go de WAL. Je pense baisser la taille des segments de 16Mo à par exemple 2Mo. D'ailleurs pourquoi les segments WAL dont on force le flush avec archive_timeout doivent ils nécessairement faire 16 Mo (sauf si configuré autrement bien sur) ? La prix a payer pour pouvoir se dire "je peux restaurer ma base au pire telle qu'elle etait a t-1800secondes" n'est-il pas un peu cher ?
Ils ne doivent pas 'nécessairement' faire 16Mo. C'est juste que la commande d'archivage cp se contente de recopier le WAL. On peut en réduire la taille avec pg_lesslog. Mais ça reste un contrib pour le moment. C'est effectivement un des défauts de l'archivage tel qu'il est. Toutefois, dans vos 13Go, il n'y a que 2,3Go dus à l'archive_timeout (16Mo toutes les 1800s, ça fait 48 WAL par jour, soit 144 en 3 jours). Que vaut checkpoint_timeout et checkpoint_segments ? Cela aussi peut avoir un gros impact (parce qu'après chaque checkpoint PostgreSQL doit à nouveau écrire des images complètes de bloc, ce qui est beaucoup plus volumineux).
Marc.
Hors ligne
Ils ne doivent pas 'nécessairement' faire 16Mo. C'est juste que la commande d'archivage cp se contente de recopier le WAL. On peut en réduire la taille avec pg_lesslog. Mais ça reste un contrib pour le moment. Que vaut checkpoint_timeout et checkpoint_segments ? Cela aussi peut avoir un gros impact (parce qu'après chaque checkpoint PostgreSQL doit à nouveau écrire des images complètes de bloc, ce qui est beaucoup plus volumineux).
Hmmm, je n'avais jamais entendu parler de pg_lesslog, très intéressant ! Combiné avec l'ouverture permise par le 'archive_command' s'est vrai que c'est un excellent compromis temps de restauration/espace disque.
J'ai dis des bêtises, j'avais configuré le archive_timeout a 5 minutes, ceci expliquant cela. Bon 2,3Go ca reste énorme, mais couplé a pg_lesslog, "it does the job!".
Merci encore !
Hors ligne
Par contre, attention, pg_lesslog est un projet annexe. Il est donc moins bien testé, pas forcément à jour, etc… Je ne conseillerais pas forcément de le mettre en prod, c'était plus comme exemple de solution au problème, mais ce n'est pas aussi bien intégré que le reste.
Marc.
Hors ligne