Hot Standby est le terme utilisé pour décrire la possibilité de se connecter et d'exécuter des requêtes en lecture seule alors que le serveur est en récupération d'archive ou mode standby. C'est utile à la fois pour la réplication et pour restaurer une sauvegarde à un état désiré avec une grande précision. Le terme Hot Standby fait aussi référence à la capacité du serveur à passer de la récupération au fonctionnement normal tandis-que les utilisateurs continuent à exécuter des requêtes et/ou gardent leurs connexions ouvertes.
Exécuter des requêtes en mode hot standby est similaire au fonctionnement normal des requêtes, bien qu'il y ait quelques différences d'utilisation et d'administration notées ci-dessous.
Quand le paramètre hot_standby est configuré à true sur un serveur en attente, le serveur commencera à accepter les connexions une fois que la restauration est parvenue à un état cohérent. Toutes les connexions qui suivront seront des connexions en lecture seule ; même les tables temporaires ne pourront pas être utilisées.
Les données sur le secondaire mettent un certain temps pour arriver du serveur primaire, il y aura donc un délai mesurable entre primaire et secondaire. La même requête exécutée presque simultanément sur le primaire et le secondaire pourrait par conséquent retourner des résultats différents. On dit que la donnée est cohérente à terme avec le primaire. Une fois que l'enregistrement de validation (COMMIT) d'une transaction est rejoué sur le serveur en attente, les modifications réalisées par cette transaction seront visibles par toutes les images de bases obtenues par les transactions en cours sur le serveur en attente. Ces images peuvent être prises au début de chaque requête ou de chaque transaction, suivant le niveau d'isolation des transactions utilisé à ce moment. Pour plus de détails, voir Section 13.2.
Les transactions exécutées pendant la période de restauration sur un serveur en mode hot standby peuvent inclure les commandes suivantes :
Accès par requête : SELECT
, COPY TO
Commandes de curseur : DECLARE
, FETCH
, CLOSE
Paramètres : SHOW
, SET
, RESET
Commandes de gestion de transaction :
BEGIN
, END
, ABORT
, START TRANSACTION
SAVEPOINT
, RELEASE
, ROLLBACK TO SAVEPOINT
Blocs d'EXCEPTION
et autres sous-transactions internes
LOCK TABLE
, mais seulement quand explicitement dans un de ces modes:
ACCESS SHARE
, ROW SHARE
ou ROW EXCLUSIVE
.
Plans et ressources : PREPARE
, EXECUTE
,
DEALLOCATE
, DISCARD
Plugins et extensions : LOAD
UNLISTEN
Les transactions lancées pendant la restauration d'un serveur en hot standby ne se verront jamais affectées un identifiant de transactions et ne peuvent pas être écrites dans les journaux de transactions. Du coup, les actions suivantes produiront des messages d'erreur :
Langage de Manipulation de Données (LMD ou DML) : INSERT
,
UPDATE
, DELETE
, MERGE
,
COPY FROM
, TRUNCATE
.
Notez qu'il n'y a pas d'action autorisée qui entraînerait l'exécution d'un
trigger pendant la récupération. Cette restriction s'applique même pour
les tables temporaires car les lignes de ces tables ne peuvent être
lues et écrites s'il n'est pas possible d'affecter un identifiant de
transactions, ce qui n'est actuellement pas possible dans un
environnement Hot Standby.
Langage de Définition de Données (LDD ou DDL) : CREATE
,
DROP
, ALTER
, COMMENT
.
Cette restriction s'applique aussi aux tables temporaires car, pour
mener à bien ces opérations, cela nécessiterait de mettre à jour les
catalogues systèmes.
SELECT ... FOR SHARE | UPDATE
, car les verrous de
lignes ne peuvent pas être pris sans mettre à jour les fichiers de
données.
Règles sur des ordres SELECT
qui génèrent des commandes LMD.
LOCK
qui demandent explicitement un mode supérieur à ROW EXCLUSIVE MODE
.
LOCK
dans sa forme courte par défaut, puisqu'il demande ACCESS EXCLUSIVE MODE
.
Commandes de gestion de transaction qui positionnent explicitement un état n'étant pas en lecture-seule :
BEGIN READ WRITE
,
START TRANSACTION READ WRITE
SET TRANSACTION READ WRITE
,
SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE
SET transaction_read_only = off
Commandes de two-phase commit : PREPARE TRANSACTION
,
COMMIT PREPARED
, ROLLBACK PREPARED
parce que même les transactions en lecture seule ont besoin d'écrire dans le WAL
durant la phase de préparation (la première des deux phases du two-phase commit).
Mise à jour de séquence : nextval()
, setval()
LISTEN
, NOTIFY
Dans le cadre normal, les transactions « en lecture seule »
permettent l'utilisation des instructions
LISTEN
et
NOTIFY
, donc les sessions Hot Standby ont des
restrictions légèrement inférieures à celles de sessions en lecture seule
ordinaires. Il est possible que certaines des restrictions soient encore
moins importantes dans une prochaine version.
Lors du fonctionnement en serveur hot standby, le paramètre
transaction_read_only
est toujours à true et ne peut
pas être modifié. Tant qu'il n'y a pas de tentative de modification sur
la base de données, les connexions sur un serveur en hot standby se
comportent de façon pratiquement identiques à celles sur un serveur normal.
Quand une bascule (failover ou
switchover) survient, la base de données
bascule dans le mode de traitement normal. Les sessions resteront
connectées pendant le changement de mode. Quand le mode hot standby est
terminé, il sera possible de lancer des transactions en lecture/écriture,
y compris pour les sessions connectées avant la bascule.
Les utilisateurs peuvent déterminer si le Hot Standby est actuellement
actif pour leur session en exécutant SHOW
in_hot_standby
. (Le paramètre in_hot_standby
n'existant pas avant la version 14, SHOW
transaction_read_only
est donc à utiliser sur les serveurs en
version plus ancienne.) De plus, un jeu de fonctions
(Tableau 9.96) permettent aux
utilisateurs d'accéder à des informations à propos du serveur secondaire.
Ceci vous permet d'écrire des programmes qui sont conscients de
l'état actuel de la base. Vous pouvez vous en servir pour superviser
l'avancement de la récupération, ou pour écrire des programmes complexes
qui restaurent la base dans des états particuliers.
Les nœuds primaire et secondaire sont faiblement couplés à bien des égards. Des actions sur le primaire auront un effet sur le secondaire. Par conséquent, il y a un risque d'interactions négatives ou de conflits entre eux. Le conflit le plus simple à comprendre est la performance : si un gros chargement de données a lieu sur le primaire, il générera un flux similaire d'enregistrements WAL sur le secondaire, et les requêtes du secondaire pourrait entrer en compétition pour les ressources systèmes, comme les entrées-sorties.
Il y a aussi d'autres types de conflits qui peuvent se produire avec le Hot Standby. Ces conflits sont des conflits durs dans le sens où des requêtes pourraient devoir être annulées et, dans certains cas, des sessions déconnectées, pour les résoudre. L'utilisateur dispose de plusieurs moyens pour gérer ces conflits. Voici les différents cas de conflits possibles :
Des verrous en accès exclusif pris sur le serveur primaire, incluant à
la fois les commandes LOCK
exclusives et quelques
actions de type DDL, entrent en conflit avec les
accès de table des requêtes en lecture seule.
La suppression d'un tablespace sur le serveur primaire entre en conflit avec les requêtes sur le serveur secondaire qui utilisent ce tablespace pour les fichiers temporaires.
La suppression d'une base de données sur le serveur primaire entre en conflit avec les sessions connectées sur cette base de données sur le serveur en attente.
La copie d'un enregistrement nettoyé par un VACUUM entre en conflit avec les transactions sur le serveur en attente qui peuvent toujours « voir » au moins une des lignes à supprimer.
La copie d'un enregistrement nettoyé par un VACUUM entre en conflit avec les requêtes accédant à la page cible sur le serveur en attente, qu'elles voient ou non les données à supprimer.
Sur le serveur primaire, ces cas résultent en une attente supplémentaire ; l'utilisateur peut choisir d'annuler une des actions en conflit. Néanmoins, sur le serveur en attente, il n'y a pas de choix possibles : l'action enregistrée dans les journaux de transactions est déjà survenue sur le serveur primaire et le serveur secondaire doit absolument réussir à l'appliquer. De plus, permettre que l'enregistrement de l'action attende indéfiniment pourrait avoir des effets fortement non désirables car le serveur en attente sera de plus en plus en retard par rapport au primaire. Du coup, un mécanisme est fourni pour forcer l'annulation des requêtes sur le serveur en attente qui entreraient en conflit avec des enregistrements des journaux de transactions en attente.
Voici un exemple de problème type : un administrateur exécute un
DROP TABLE
sur une table du serveur primaire qui est
actuellement utilisé dans des requêtes du serveur en attente. Il est clair
que la requête ne peut pas continuer à s'exécuter si l'enregistrement
dans les journaux de transactions, correspondant au DROP
TABLE
est appliqué sur le serveur en attente. Si cette situation
survient sur le serveur primaire, l'instruction DROP TABLE
attendra jusqu'à ce que l'autre requête se termine. Par contre, quand le
DROP TABLE
est exécuté sur le serveur primaire, ce dernier
ne sait pas les requêtes en cours d'exécution sur le serveur en attente,
donc il n'attendra pas la fin de l'exécution des requêtes sur le serveur
en attente. L'enregistrement de cette modification dans les journaux de
transactions arrivera au serveur en attente alors que la requête sur le
serveur en attente est toujours en cours d'exécution, causant un conflit.
Le serveur en attente doit soit retarder l'application des enregistrements
des journaux de transactions (et tous ceux qui sont après aussi) soit
annuler la requête en conflit, pour appliquer l'instruction DROP
TABLE
.
Quand une requête en conflit est courte, il est généralement préférable d'attendre un peu pour l'application du journal de transactions. Mais un délai plus long n'est généralement pas souhaitable. Donc, le mécanisme d'annulation dans l'application des enregistrements de journaux de transactions dispose de deux paramètres, max_standby_archive_delay et max_standby_streaming_delay, qui définissent le délai maximum autorisé pour appliquer les enregistrements. Les requêtes en conflit seront annulées si l'application des enregistrements prend plus de temps que celui défini. Il existe deux paramètres pour que des délais différents puissent être observés suivant le cas : lecture des enregistrements à partir d'un journal archivé (par exemple lors de la restauration initiale à partir d'une sauvegarde ou lors d'un « rattrapage » si le serveur en attente accumulait du retard par rapport au primaire) et lecture des enregistrements à partir de la réplication en flux.
Pour un serveur en attente dont le but principal est la haute-disponibilité, il est préférable de configurer des valeurs assez basses pour les paramètres de délai, de façon à ce que le serveur en attente ne soit pas trop en retard par rapport au serveur primaire à cause des délais suivis à cause des requêtes exécutées sur le serveur en attente. Par contre, si le serveur en attente doit exécuter des requêtes longues, alors une valeur haute, voire infinie, du délai pourrait être préférable. Néanmoins, gardez en tête qu'une requête mettant du temps à s'exécuter pourrait empêcher les autres requêtes de voir les modifications récentes sur le serveur primaire si elle retarde l'application des enregistrements de journaux de transactions.
Une fois que le délai spécifié par
max_standby_archive_delay
ou
max_standby_streaming_delay
a été dépassé, toutes les
requêtes en conflit seront annulées. Ceci résulte habituellement en une
erreur d'annulation, bien que certains cas, comme un DROP
DATABASE
, peuvent occasionner l'arrêt complet de la connexion.
De plus, si le conflit intervient sur un verrou détenu par une transaction
en attente, la session en conflit sera terminée (ce comportement pourrait
changer dans le futur).
Les requêtes annulées peuvent être ré-exécutées immédiatement (après avoir commencé une nouvelle transaction, bien sûr). Comme l'annulation des requêtes dépend de la nature des enregistrements dans le journal de transactions, une requête annulée pourrait très bien réussir si elle est de nouveau exécutée.
Gardez en tête que les paramètres de délai sont comparés au temps passé depuis que la donnée du journal de transactions a été reçue par le serveur en attente. Du coup, la période de grâce accordée aux requêtes n'est jamais supérieure au paramètre de délai, et peut être considérablement inférieure si le serveur en attente est déjà en retard suite à l'attente de la fin de l'exécution de requêtes précédentes ou suite à son impossibilité de conserver le rythme d'une grosse mise à jour.
La raison la plus fréquente des conflits entre les requêtes en lecture seule et le rejeu des journaux de transactions est le « nettoyage avancé ». Habituellement, PostgreSQL permet le nettoyage des anciennes versions de lignes quand aucune transaction ne peut les voir pour s'assurer du respect des règles de MVCC. Néanmoins, cette règle peut seulement s'appliquer sur les transactions exécutées sur le serveur primaire. Donc il est possible que le nettoyage effectué sur le primaire supprime des versions de lignes toujours visibles sur une transaction exécutée sur le serveur en attente.
Le nettoyage des versions de ligne n'est pas la seule cause de conflits
avec les requêtes exécutées sur les secondaires. Tous les parcours
d'index seuls (ceci incluant ceux qui s'exécutent sur les secondaires)
doivent utiliser un snapshot MVCC qui
« accepte » la carte de visibilité. Les conflits sont de ce fait
requis à chaque fois que VACUUM
indique une page comme toutes-visibles
dans la carte de visibilité contenant une ou plusieurs lignes
non visibles pour toutes les requêtes du secondaire.
Donc même exécuter VACUUM
sur une table sans lignes mises
à jour ou supprimées nécessitant du nettoyage peut amener à des conflits.
Les utilisateurs doivent s'attendre à ce que les tables fréquemment mises
à jour sur le serveur primaire seront aussi fréquemment la cause de
requêtes annulées sur le serveur en attente. Dans un tel cas, le
paramétrage d'une valeur finie pour
max_standby_archive_delay
ou
max_standby_streaming_delay
peut être considéré comme
similaire à la configuration de statement_timeout
.
Si le nombre d'annulations de requêtes sur le serveur en attente est
jugé inadmissible, quelques solutions existent. La première option est de définir la variable
hot_standby_feedback
qui permet d'empêcher les conflits liés au nettoyage
opéré par la commande VACUUM
en lui interdisant de nettoyer les lignes récemment supprimées. Si
vous le faites, vous devez noter que cela retardera le nettoyage des
versions de lignes mortes sur le serveur primaire, ce qui pourrait résulter
en une fragmentation non désirée de la table. Néanmoins, cette situation
ne sera pas meilleure si les requêtes du serveur en attente s'exécutaient
directement sur le serveur primaire. Vous avez toujours le bénéfice de
l'exécution sur un serveur distant. Si des serveurs secondaires se
connectent et se déconnectent fréquemment, vous pourriez vouloir faire des
ajustements pour gérer la période durant laquelle hot_standby_feedback
n'est pas renvoyé. Par exemple, vous pouvez considérer l'augmentation de
max_standby_archive_delay
pour que les requêtes ne
soient pas annulées rapidement par des conflits avec le journal de transactions
d'archive durant les périodes de déconnexion. Vous pouvez également
considérer l'augmentation de max_standby_streaming_delay
pour éviter des annulations rapides par les nouvelles données de flux de
transaction après la reconnexion.
Le nombre de requêtes annulées et le motif de cette annulation peut être visualisé avec
la vue système pg_stat_database_conflicts
sur le serveur
secondaire. La vue système pg_stat_database
contient aussi
des informations synthétiques sur ce sujet.
Les utilisateurs peuvent contrôler si un message doit être écrit dans les
traces du serveur lorsque le rejeu des journaux de transactions est en
conflit depuis plus longtemps que deadlock_timeout
.
Ce comportement est contrôlé par le paramètre
log_recovery_conflict_waits.
Si hot_standby
est positionné à on
dans postgresql.conf
(valeur par défaut) et qu'un
fichier standby.signal
est présent, le serveur
fonctionnera en mode Hot Standby.
Toutefois, il pourrait s'écouler du temps avant que les connections en
Hot Standby soient autorisées, parce que le serveur n'acceptera pas de connexions tant
que la récupération n'aura pas atteint un point garantissant un état cohérent permettant
aux requêtes de s'exécuter. Pendant cette période, les clients qui tentent de se connecter
seront rejetés avec un message d'erreur.
Pour confirmer que le serveur a démarré, vous pouvez soit tenter de vous connecter en
boucle, ou rechercher ces messages dans les journaux du serveur:
LOG: entering standby mode ... puis, plus loin ... LOG: consistent recovery state reached LOG: database system is ready to accept read-only connections
L'information sur la cohérence est enregistrée une fois par checkpoint sur le primaire.
Il n'est pas possible d'activer le mode Hot Standby si on lit des WAL générés durant
une période pendant laquelle wal_level
n'était pas positionné
à replica
ou logical
sur le primaire. L'arrivée à un état cohérent
peut aussi être retardée si ces deux conditions se présentent:
Une transaction en écriture a plus de 64 sous-transactions
Des transactions en écriture ont une durée très importante
Si vous effectuez du log shipping par fichier (warm standby), vous pourriez
devoir attendre jusqu'à l'arrivée du prochain fichier de WAL, ce qui pourrait
être aussi long que le paramètre archive_timeout
du primaire.
Certains paramètres déterminent la taille de la mémoire partagée pour le suivi des identifiants de transaction, des verrous, et des transactions préparées. Ces structures mémoires partagées ne peuvent pas être plus petites sur le secondaire que sur le primaire pour s'assurer que le secondaire ne tombera pas à court de mémoire partagée pendant la récupération. Par exemple, si le primaire avait utilisé des transactions préparées mais que le secondaire n'avait pas alloué de mémoire partagée pour suivre ces transactions préparées, alors la récupération ne pourrait reprendre avant que la configuration du secondaire ne soit adaptée. Les paramètres concernés sont:
max_connections
max_prepared_transactions
max_locks_per_transaction
max_wal_senders
max_worker_processes
La façon la plus simple pour éviter que cela ne devienne un problème est d'avoir tous ces paramètres définis sur les serveurs secondaires à des valeurs égales ou supérieures que celles du primaire. C'est pourquoi, si vous voulez augmenter ces valeurs, vous devez le faire d'abord sur tous les serveurs secondaires avant de le faire sur le serveur primaire. De la même façon, si vous voulez diminuer ces valeurs, vous devez d'abord le faire sur le serveur primaire, puis sur tous les serveurs secondaires. Gardez également à l'esprit que lorsqu'un secondaire est promu, il devient alors la nouvelle référence des valeurs de ces paramètres pour les secondaires qui s'y raccrochent. De ce fait, pour éviter que cela ne devienne un problème lors d'une bascule (switchover ou failover), il est recommandé de conserver ces paramètres identiques sur tous les serveurs secondaires.
Les journaux de transactions tracent le changement de ces paramètres sur le serveur primaire. Si un serveur hot standby rejoue un journal de transactions qui indique que la valeur actuelle sur le primaire est plus élevée que la sienne, un message d'avertissement sera écrit dans les traces du serveur et le rejeu mis en pause. Par exemple :
WARNING: hot standby is not possible because of insufficient parameter settings DETAIL: max_connections = 80 is a lower setting than on the primary server, where its value was 100. LOG: recovery has paused DETAIL: If recovery is unpaused, the server will shut down. HINT: You can then restart the server after making the necessary configuration changes.
A ce stade, les paramètres du secondaire doivent être ajustés et l'instance redémarrée avant que le rejeu ne puisse reprendre. Si le secondaire n'est pas en mode hot standby alors, lorsqu'il rencontrera un changement de paramètre incompatible, il s'éteindra immédiatement sans pause, puisqu'il serait inutile de rester actif.
Il est important que l'administrateur sélectionne le paramétrage approprié pour max_standby_archive_delay et max_standby_streaming_delay. Le meilleur choix varie les priorités. Par exemple, si le serveur a comme tâche principale d'être un serveur de haute-disponibilité, alors il est préférable d'avoir une configuration assez basse, voire à zéro, de ces paramètres. Si le serveur en attente est utilisé comme serveur supplémentaire pour des requêtes du type décisionnel, il sera acceptable de mettre les paramètres de délai à des valeurs allant jusqu'à plusieurs heures, voire même -1 (cette valeur signifiant qu'il est possible d'attendre que les requêtes se terminent d'elles-même).
Les "hint bits" (bits d'indices) écrits sur le primaire ne sont pas journalisés en WAL, il est donc probable que les hint bits soient réécrits sur le secondaire. Ainsi, le serveur secondaire fera toujours des écritures disques même si tous les utilisateurs sont en lecture seule ; aucun changement ne se produira sur les données elles mêmes. Les utilisateurs écriront toujours les fichiers temporaires pour les gros tris et re-génèreront les fichiers d'information relcache, il n'y a donc pas de morceau de la base qui soit réellement en lecture seule en mode hot standby. Notez aussi que les écritures dans des bases distantes en utilisant le module dblink, et d'autres opérations en dehors de la base s'appuyant sur des fonctions PL seront toujours possibles, même si la transaction est en lecture seule localement.
Les types suivants de commandes administratives ne sont pas acceptées durant le mode de récupération:
Langage de Définition de Données (LDD ou DDL) : comme CREATE INDEX
Droits et propriété : GRANT
, REVOKE
,
REASSIGN
Commandes de maintenance : ANALYZE
, VACUUM
,
CLUSTER
, REINDEX
Notez encore une fois que certaines de ces commandes sont en fait autorisées durant les transactions en "lecture seule" sur le primaire.
Par conséquent, vous ne pouvez pas créer d'index supplémentaires qui existeraient uniquement sur le secondaire, ni des statistiques qui n'existeraient que sur le secondaire. Si ces commandes administratives sont nécessaires, elles doivent être exécutées sur le primaire, et ces modifications se propageront à terme au secondaire.
pg_cancel_backend()
et
pg_terminate_backend()
fonctionneront sur les
processus utilisateurs, mais pas sur les processus de démarrage, qui
effectuent la récupération. pg_stat_activity
ne
montre pas les transactions de récupération comme actives. Ainsi,
pg_prepared_xacts
est toujours vide durant la
récupération. Si vous voulez traiter des transactions préparées douteuses,
interrogez pg_prepared_xacts
sur le primaire, et
exécutez les commandes pour résoudre le problème à cet endroit ou
résolvez-les après la fin de la restauration.
pg_locks
affichera les verrous posés par les processus,
comme en temps normal. pg_locks
affiche aussi une transaction
virtuelle gérée par le processus de démarrage qui possède tous les
AccessExclusiveLocks
posés par les transactions rejouées par la récupération.
Notez que le processus de démarrage n'acquiert pas de verrou pour effectuer les modifications à
la base, et que par conséquent les verrous autre que AccessExclusiveLocks
ne sont pas visibles dans pg_locks
pour le processus de démarrage;
ils sont simplement censés exister.
Le plugin Nagios check_pgsql fonctionnera, parce que les informations simples qu'il vérifie existent. Le script de supervision check_postgres fonctionnera aussi, même si certaines valeurs retournées pourraient être différentes ou sujettes à confusion. Par exemple, la date de dernier vacuum ne sera pas mise à jour, puisqu’aucun vacuum ne se déclenche sur le secondaire. Les vacuums s'exécutant sur le primaire envoient toujours leurs modifications au secondaire.
Les options de contrôle des fichiers de WAL ne fonctionneront pas durant la récupération,
comme pg_backup_start
, pg_switch_wal
, etc...
Les modules à chargement dynamique fonctionnent, comme pg_stat_statements
.
Les verrous consultatifs fonctionnent normalement durant la récupération, y compris en ce qui concerne la détection des verrous mortels (deadlocks). Notez que les verrous consultatifs ne sont jamais tracés dans les WAL, il est donc impossible pour un verrou consultatif sur le primaire ou le secondaire d'être en conflit avec la ré-application des WAL. Pas plus qu'il n'est possible d'acquérir un verrou consultatif sur le primaire et que celui-ci initie un verrou consultatif similaire sur le secondaire. Les verrous consultatifs n'ont de sens que sur le serveur sur lequel ils sont acquis.
Les systèmes de réplications à base de triggers tels que Slony, Londiste et Bucardo ne fonctionneront pas sur le secondaire du tout, même s'ils fonctionneront sans problème sur le serveur primaire tant que les modifications ne sont pas envoyées sur le serveur secondaire pour y être appliquées. Le rejeu de WAL n'est pas à base de triggers, vous ne pouvez donc pas utiliser le secondaire comme relais vers un système qui aurait besoin d'écritures supplémentaires ou utilise des triggers.
Il n'est pas possible d'assigner de nouveaux OID, bien que des générateurs d'UUID puissent tout de même fonctionner, tant qu'ils n'ont pas besoin d'écrire un nouveau statut dans la base.
À l'heure actuelle, la création de table temporaire n'est pas autorisée durant les transactions en lecture seule, certains scripts existants pourraient donc ne pas fonctionner correctement. Cette restriction pourrait être levée dans une version ultérieure. Il s'agit à la fois d'un problème de respect des standards et d'un problème technique.
DROP TABLESPACE
ne peut réussir que si le tablespace est vide.
Certains utilisateurs pourraient utiliser de façon active le tablespace via leur
paramètre temp_tablespaces
. S'il y a des fichiers temporaires
dans le tablespace, toutes les requêtes actives sont annulées pour s'assurer que les
fichiers temporaires sont supprimés, afin de supprimer le tablespace et de continuer
l'application des WAL.
Exécuter DROP DATABASE
ou ALTER DATABASE ...
SET TABLESPACE
sur
le serveur primaire générera un enregistrement dans les journaux de
transactions qui causera la déconnexion de tous les utilisateurs
actuellement connectés à cette base de données. Cette action survient
immédiatement, quelque soit la valeur du paramètre
max_standby_streaming_delay
. Notez que
ALTER DATABASE ... RENAME
ne déconnecte pas les
utilisateurs qui, dans la plupart des cas, ne s'en apercevront pas. Cela
peut néanmoins semer de la confusion pour un programme qui dépendrait du nom de la base.
En fonctionnement normal (pas en restauration), si vous exécutez
DROP USER
ou DROP ROLE
pour un rôle ayant l'attribut LOGIN alors que cet utilisateur est toujours
connecté alors rien ne se produit pour cet utilisateur connecté -- il reste connecté. L'utilisateur
ne peut toutefois pas se reconnecter. Ce comportement est le même en récupération, un
DROP USER
sur le primaire ne déconnecte donc pas cet utilisateur sur le secondaire.
Le système de statistiques cumulatives est actif pendant la restauration.
Tous les parcours, lectures, blocs, utilisations d'index, etc. seront
enregistrés normalement sur le standby. Néanmoins, le rejeu des journaux de
transactions n'incrémentera pas les compteurs spécifiques des relations et
des bases. Le rejeu n'incrémentera pas les colonnes de
pg_stat_all_tables
(comme n_tup_ins
), pas plus que les lectures et écritures réalisées par le
processus de démarrage ne seront tracées dans les vues pg_statio_
, ou que les
colonnes associées de pg_stat_database
ne seront incrémentées.
Autovacuum n'est pas actif durant la récupération, il démarrera normalement à la fin de la récupération.
Les processus d'écriture en arrière plan (checkpointer et background
writer) sont actifs durant la restauration. Le processus checkpointer
process effectuera les restartpoints (similaires aux checkpoints sur le
primaire) et le processus background writer réalisera les activités
normales de nettoyage de blocs. Ceci peut inclure la mise à jour des
information de hint bit des données du serveur secondaire. La commande
CHECKPOINT
est acceptée pendant la récupération, bien
qu'elle déclenche un restartpoint et non un checkpoint.
De nombreux paramètres ont été mentionnés ci-dessus dans Section 26.4.2 et Section 26.4.3.
Sur le primaire, le paramètre wal_level peut être utilisé. max_standby_archive_delay et max_standby_streaming_delay n'ont aucun effet sur le primaire.
Sur le serveur en attente, les paramètres hot_standby, max_standby_archive_delay et max_standby_streaming_delay peuvent être utilisés.
Il y a plusieurs limitations au Hot Standby. Elles peuvent et seront probablement résolues dans des versions ultérieures:
Une connaissance complète des transactions en cours d'exécution est nécessaire avant de pouvoir déclencher des instantanés. Des transactions utilisant un grand nombre de sous-transactions (à l'heure actuelle plus de 64) retarderont le démarrage des connexions en lecture seule jusqu'à complétion de la plus longue transaction en écriture. Si cette situation se produit, des messages explicatifs seront envoyés dans la trace du serveur.
Des points de démarrage valides pour les requêtes du secondaire sont générés à chaque checkpoint sur le primaire. Si le secondaire est éteint alors que le primaire est déjà éteint, il est tout à fait possible ne pas pouvoir repasser en Hot Standby tant que le primaire n'aura pas été redémarré, afin qu'il génère de nouveaux points de démarrage dans les journaux WAL. Cette situation n'est pas un problème dans la plupart des situations où cela pourrait se produire. Généralement, si le primaire est éteint et plus disponible, c'est probablement en raison d'un problème sérieux qui va de toutes façons forcer la conversion du secondaire en primaire. Et dans des situations où le primaire est éteint intentionnellement, la procédure standard est également de promouvoir le secondaire.
À la fin de la récupération, les AccessExclusiveLocks
possédés
par des transactions préparées nécessiteront deux fois le nombre d'entrées normal dans la
table de verrous. Si vous pensez soit exécuter un grand nombre de transactions préparées
prenant des AccessExclusiveLocks
, ou une grosse transaction prenant
beaucoup de AccessExclusiveLocks
, il est conseillé d'augmenter la valeur
de max_locks_per_transaction
, peut-être jusqu'à une valeur double
de celle du serveur primaire. Vous n'avez pas besoin de prendre ceci en compte
si votre paramètre max_prepared_transactions
est 0.
Il n'est pas encore possible de passer une transaction en mode d'isolation sérialisable tout en supportant le hot standby (voir Section 13.2.3 et Section 13.4.1 pour plus de détails). Une tentative de modification du niveau d'isolation d'une transaction à sérialisable en hot standby générera une erreur.