PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 10.23 » Annexes » Modules supplémentaires fournis » amcheck

F.2. amcheck

Le module amcheck fournit des fonctions vous permettant de vérifier la cohérence logique de la structure des index. Si la structure semble valide, aucune erreur n'est levée.

Les fonctions vérifient diverses propriétés invariables dans la structure de la représentation de certains index. La justesse des fonctions permettant l'accès aux données durant les parcours d'index et d'autres opération importantes reposent sur le fait que ces propriétés invariables soient toujours vraies. Par exemple, certaines fonctions vérifient, entre autres choses, que toutes les pages d'index B-Tree ont leurs éléments dans un ordre « logique » (par exemple, pour des index B-Tree sur un type text, les lignes de l'index devraient être triées dans l'ordre alphabétique défini par la collation). Si, quelque soit la raison, cette propriété invariable spécifique n'est plus vérifiée, il faut s'attendre à ce que des recherches binaires sur la page affectée renseignent de manière erronée les parcours d'index, avec pour conséquence des résultats erronnés aux requêtes SQL.

La vérification est réalisée en utilisant les même précédures que celles utilisées par les parcours d'index eux-même, qui peuvent très bien être du code utilisateur pour une classe d'opérateur. Par exemple, la vérification d'index B-Tree s'appuie sur les comparaisons faites avec une ou plusieurs routines pour la fonction de support 1. See Section 37.14.3 pour plus de détail sur les fonctions de support des classes d'opérateur.

Les fonctions du module amcheck ne peuvent être exécutées que par des super utilisateurs.

F.2.1. Fonctions

bt_index_check(index regclass) returns void

bt_index_check que sa cible, un index B-Tree, respecte une vériété de propriétés invariables. Exemple d'utilisation :

test=# SELECT bt_index_check(c.oid), c.relname, c.relpages
FROM pg_index i
JOIN pg_opclass op ON i.indclass[0] = op.oid
JOIN pg_am am ON op.opcmethod = am.oid
JOIN pg_class c ON i.indexrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE am.amname = 'btree' AND n.nspname = 'pg_catalog'
-- Ignore les tables temporaires, qui peuvent appartenir à d'autres sessions
AND c.relpersistence != 't'
-- La fonction peut renvoyer une erreur si cela est omis :
AND i.indisready AND i.indisvalid
ORDER BY c.relpages DESC LIMIT 10;
 bt_index_check |             relname             | relpages
----------------+---------------------------------+----------
                | pg_depend_reference_index       |       43
                | pg_depend_depender_index        |       40
                | pg_proc_proname_args_nsp_index  |       31
                | pg_description_o_c_o_index      |       21
                | pg_attribute_relid_attnam_index |       14
                | pg_proc_oid_index               |       10
                | pg_attribute_relid_attnum_index |        9
                | pg_amproc_fam_proc_index        |        5
                | pg_amop_opr_fam_index           |        5
                | pg_amop_fam_strat_index         |        5
(10 rows)
      

Cet exemple montre une session qui effectue une vérification des dix plus gros index sur le catalogue dans la base de données « test ». Puisqu'aucune erreur n'est retournée, tous les index testés semblent être cohérent au niveau logique. Bien évidemment, cette requête pourrait être facilement modifiée pour appeler bt_index_check sur chacun des index présents dans la base de données pour lesquels la vérification est supportée.

bt_index_check acquiert un AccessShareLock sur l'index cible ainsi que sur la relation à laquelle il appartient. Ce niveau de verrouillage est le même que celui acquis sur les relations lors d'une simple requête SELECT statements. bt_index_check ne vérifie pas les propriétés invariantes qui englobent les relations enfant/parent, et ne vérifie pas non plus que l'index est cohérent par rapport au contenu de la relation associée. Quand un test léger, de routine, pour détecter des problèmes de corruption est nécessaire sur un environnement de production, utiliser bt_index_check offre généfalement le meilleur compromis entre la minutie de la vérification et l'impact limité sur les performances de l'application ainsi que sa disponibilité.

bt_index_parent_check(index regclass) returns void

bt_index_parent_check teste que sa cible, un index B-Tree, respecte un certain nombre de propriétés invariantes. Les vérifications effectuées par bt_index_parent_check sont un sur-ensemble des vérifications effectuées par bt_index_check. On peut voir bt_index_parent_check comme une version plus minitieuse de bt_index_check : contrairement à bt_index_check, bt_index_parent_check vérifie également les propriétés invariantes qui englobent les relations parent/enfant. Cependant, cette fonction ne vérifie pas que l'index cible est cohérent avec la relation associée. bt_index_parent_check respecte la convention habituelle qui consiste à retourner une erreur si une incohérence ou tout autre problème est détecté.

Un verrou de type ShareLock est requis sur l'index ciblé par bt_index_parent_check (un verrou de type ShareLock est également acquis sur la relation associée). Ces verrous empêchent des modifications concurrentes par des commandes INSERT, UPDATE, et DELETE Les verrous empêchent également la relation associée d'être traitée de manière concurrente par VACUUM, ainsi que toute autre commande qui n'est pas un ordre DML. Il est à noter que cette fonction conserve les verrous uniquement durant son exécution et non pas durant l'intégralité de la transaction.

La vérification supplémentaire de bt_index_parent_check est plus apte à détecter différents cas pathologiques. Ces cas peuvent impliquer une classe d'opérateur B-Tree implémentée de manière incorrecte utilisée pout l'index vérifié, ou, hypothétiquement, des bugs non encore découverts dans le code de la méthode d'accès assocée à cet index B-Tree. Il est à noter que bt_index_parent_check ne peut pas être utilisé lorsque le mode Hot Standby est activé (c'est-à-dire, sur un serveur secondaire disponible en lecture seule), contrairement à bt_index_check.

F.2.2. Utiliser amcheck efficacement

amcheck peut être efficace pour détecter différents types de modes d'échec que les sommes de contrôle de page n'arriveront jamais à détecter. Cela inclut :

  • Les incohérences structurelles causée par des implémentations incorrectes de classe d"opérateur.

    Cela inclue également des problèmes causés par le changement des règles de comparaison des collations du système d'exploitation. Les comparaisons des données d'un type ayant une collation comme text doivent être immuables (tout comme toutes les autres comparaisons utilisées pour les parcours d'index B-Tree doivent être immuables), ce qui implique que les règles de collation du système d'exploitation ne dois jamais changer. Bien que cela soit rare, des mises à jour des règles des collations du système d'exploitation peuvent causer ces problèmes. Plus généralement, une incohérence dans l'ordre de collation entre un serveur primaire et son réplicat est impliqué, peut-être parce que la version major du système d'exploitation utilisée était incohérente. De telles incohérences ne surviendront généralement que sur des serveur secondaires, et ne pourront par conséquent être détectées que sur des serveurs secondaires.

    Si un tel problème survient, il se peut que cela n'affecte par individuellement chaque index qui utilise le tri d'une collation affectée, tout simplement car les valeurs indexée pourraient avoir le même ordre de tri absolu indépendamment des incohérences comportementales. Voir Section 23.1 et Section 23.2 pour plus de détails sur comment PostgreSQL utilise les locales et collations du système d'exploitation.

  • Une corruption causée par un hypothétique bug non encore découvert dans l'implémentation associée à la méthode d'accès ou au code effectuant le tri.

    La vérification automatique de l'intégrité structurelle des index joue un rôle sur les principaux tests des fonctionnalités nouvelles ou proposées dans PostgreSQL qui pourraient possiblement autoriser l'introduction d'incohérence logiques. Une stratégie de test évidente est d'appeler les fonctions d'amcheck de manière continue en même temps que les tests de régression standard sont lancés. Voir Section 32.1 pour plus de détail sur commencer lancer les tests.

  • Les défauts du système de fichiers ou du sous système de stockage quand les vérifications des sommes de contrôles ne sont pas activées.

    Il est à noter que amcheck examine les pages telles que représentées dans des tampons en mémoire partagée au moment de la vérification s'il y a seulement un accès en mémoire partagée lors de l'accès au bloc. Par conséquent, amcheck n'examine pas forcément les données lues depuis le système de fichiers au moment de la vérification. De plus, quand les sommes de contrôles sont activées, amcheck peut lever une erreur de somme de contrôle incorrecte quand un block corrompu est lu vers un tampon.

  • Les corruptions causée par une mémoire RAM défaillante, et plus largement le sous système mémoire.

    PostgreSQL ne protège pas contre les erreurs mémoire corrigibles et il est supposé que vous utilisez de la mémoire RAM utilisant le standard de l'instrie Error Correcting Codes (ECC) ou une meilleure protection. Cependant, la mémoire ECC est typiquement immunisée uniquement contre les erreurs d'un seul bit, et il ne faut pas partir du principe que ce type de mémoire fournit une protection absolue contre les défaillances résultant en une corruption mémoire.

De manière générale, amcheck ne peut que prouver la présence d'une corruption; il ne peut pas en prouver l'absence.

F.2.3. Réparer une corruption

Aucune erreur concernant une corruption remontée par amcheck ne devrait être un faux positif. Dans la pratique, amcheck est plus à même de trouver des bugs logiciels que des problèmes matériels. amcheck remonte des erreurs dans le cas où des conditions, par définition, ne devraient jamais arriver, et par conséquent une analyse minutieuse des erreurs remontées par amcheck est souvent nécessaire.

Il n'y a pas de méthode générale pour réparer les problèmes que amcheck détecte. Une explication de la cause principale menant à ce que la propriété invariable soit violée devrait être étudiée. pageinspect pourrait jouer un rôle utile dans le diagnostique de la corruption qu'amcheck détecte. Un REINDEX pourrait ne pas être efficace pour réparer la corruption.