Mécanisme de tas uniquement de tuples dans PostgreSQL

Postgresql diffère des autres SGBD en ce sens que lors de l'opération UPDATE, les modifications apportées à la ligne existante ne se produisent pas et qu'une copie de la ligne est différente de l'original avec les valeurs des colonnes affectées par la mise à jour - elles sont anciennes dans l'original et modifiées dans la copie. Cette approche, d'une part, vous permet d'éviter les verrous lors de l'exécution des demandes de lecture et d'écriture, et d'autre part, elle crée le besoin d'effacer constamment les anciennes versions de lignes que personne ne lira jamais. En relation avec cette fonctionnalité architecturale, la question se pose souvent de ce qui se passera si vous avez besoin de stocker dans la base de données quelque chose comme l'heure du dernier accès aux données qui autrement ne change pas. Répondra-t-il aux performances? Conduira-t-il à une restructuration constante des indices?


En bref, oui, Copy On Write n'ira nulle part, mais dans de nombreux cas, les index ne peuvent pas être reconstruits, grâce à HOT.


Les tuples de segment de mémoire uniquement, également appelés HOT, sont une optimisation utilisée par Postgres pour réduire la quantité d'E / S requises pour les mises à jour. En raison de MVCC, une mise à jour dans Postgres consiste à rechercher une ligne pour la mise à jour et à insérer de nouvelles versions de la ligne dans la base de données. Le principal inconvénient de cette procédure est la nécessité de rajouter une ligne à chaque index.
Cela nécessite beaucoup plus d'E / S car la ligne doit être réinsérée dans chaque index de la table. Le besoin de réinsertion se pose car la position physique de la nouvelle version d'une ligne sur disque est différente de la position physique de l'ancienne version.


Pour réduire la quantité d'E / S requises pour la MISE À JOUR, l'équipe Postgres a ajouté HOT à Postgres. L'idée derrière HOT est relativement simple. Lors de la mise à jour de la ligne, si possible, Postgres mettra une nouvelle copie de la ligne immédiatement après l'ancienne copie de la ligne. De plus, dans l'ancienne copie de la chaîne, une étiquette spéciale est apposée afin que Postgres sache que la nouvelle copie de la chaîne se trouve immédiatement après l'ancienne. Par conséquent, la mise à jour de tous les index n'est pas nécessaire.


Lors du scan par index pour lequel passe une nouvelle copie de la chaîne, le filtre Postgres trouvera l'ancienne copie de la chaîne. Puisqu'il y a une étiquette spéciale sur l'ancienne copie de la ligne, Postgres comprendra que la nouvelle copie de la ligne se trouve immédiatement après l'ancienne et trouvera la nouvelle version et l'utilisera. Il s'avère que Postgres dans de tels cas peut se comporter comme si tous les index pointent vers une nouvelle copie de la chaîne, et ils n'ont pas besoin d'être reconstruits.


Désormais, HOT n'est impliqué que lorsque seules les colonnes non indexables sont impliquées dans la mise à jour. Si au moins une colonne participant à la mise à jour est incluse dans l'index, HOT ne peut pas être appliqué. Dans ce cas, l'utilisation de HOT pose plusieurs problèmes. Par exemple, lorsque l'index de la colonne à mettre à jour est indexé par une analyse et que l'ancienne copie de la ligne tombe dans le prédicat de l'analyse, mais pas la nouvelle. Dans cette situation, Postgres essaiera d'utiliser l'index pour trouver rapidement toutes les lignes qui conviennent au prédicat de requête, et dans le cas des colonnes qui ont été mises à jour à l'aide de HOT, il produira une nouvelle copie de la ligne qui ne correspond pas au prédicat de requête. En raison de cette limitation (que HOT ne fonctionne pas lorsque des colonnes indexables sont incluses dans la mise à jour), Postgres peut garantir que lorsqu'il essaie de trouver des lignes qui conviennent au prédicat par lequel l'index est transmis, alors si le prédicat correspond à l'ancienne version de la ligne, puis à la nouvelle version de la ligne lui convient aussi et vice versa.


Actuellement en cours de développement est une extension HOT appelée WARM, qui fonctionne également lors de la mise à jour des colonnes sur lesquelles les index sont créés. L'idée derrière WARM est de mettre une nouvelle ligne immédiatement après l'ancienne et de mettre à jour la ligne pour les index qui ont changé de colonne. Cela complique grandement la situation décrite, car maintenant Postgres a besoin d'un moyen de déterminer en quelque sorte si la ligne passe le filtre pour l'index ou non.


PS Dans l'article original, le mécanisme HOT est décrit, mais nous avons ici à l'esprit le mécanisme dans lequel seuls les tuples sont impliqués, et le terme lui-même a une signification distincte.


Le tuple Heap only n'est qu'une nouvelle version de la ligne. Aussi étrange que cela puisse paraître, un segment de mémoire est une table, et un segment de mémoire signifie uniquement que cette ligne ne peut être trouvée que par la chaîne qui provient de l'ancienne version de la ligne appelée racine.

Source: https://habr.com/ru/post/fr475642/


All Articles