{"id":81089,"date":"2020-05-11T01:42:24","date_gmt":"2020-05-10T23:42:24","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov"},"modified":"2020-05-11T01:42:24","modified_gmt":"2020-05-10T23:42:24","slug":"tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","title":{"rendered":"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Je vous invite \u00e0 consulter le compte rendu de la pr\u00e9sentation d'Andrei Salnikov au d\u00e9but de l'ann\u00e9e 2016 intitul\u00e9e \"Erreurs typiques dans les applications qui m\u00e8nent \u00e0 un bloat dans PostgreSQL\"<\/strong><\/p>\n<p><\/p>\n<p>Dans cette pr\u00e9sentation, je vais examiner les principales erreurs dans les applications qui surviennent lors de la conception et de la r\u00e9daction du code de l'application. Je vais me concentrer uniquement sur les erreurs qui entra\u00eenent un bloat dans PostgreSQL. En g\u00e9n\u00e9ral, c'est le d\u00e9but de la fin pour les performances de votre syst\u00e8me dans son ensemble, bien qu'aucun signe pr\u00e9monitoire n'\u00e9tait visible au d\u00e9part.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a9e199bfe2e01c76966b32868790f8f0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Je suis ravi de vous accueillir ! Cette pr\u00e9sentation n'est pas aussi technique que celle de mon coll\u00e8gue. Elle s'adresse principalement aux d\u00e9veloppeurs de syst\u00e8mes backend, car nous avons un nombre assez \u00e9lev\u00e9 de clients. Et tous commettent les m\u00eames erreurs. Je vais vous en parler. J'expliquerai les cons\u00e9quences fatales et n\u00e9fastes de ces erreurs. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c6c84dbafc595ae3068cd8bf804ccee7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pourquoi ces erreurs se produisent-elles ? Elles se produisent pour deux raisons : par opportunisme, en pensant que cela pourrait fonctionner, et par m\u00e9connaissance de certains m\u00e9canismes qui se produisent au niveau entre la base de donn\u00e9es et l'application, ainsi qu'au sein de la base elle-m\u00eame. <\/p>\n<p><\/p>\n<p>Je vais vous donner trois exemples avec des images horribles montrant comment tout d\u00e9g\u00e9n\u00e8re. Je d\u00e9taillerai bri\u00e8vement le m\u00e9canisme en jeu. Et comment r\u00e9agir lorsqu'ils se produisent, ainsi que les m\u00e9thodes pr\u00e9ventives \u00e0 utiliser pour \u00e9viter les erreurs. Je parlerai des outils auxiliaires et fournirai des liens utiles. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b0230d992f5b44f0e542df2e4b4d526f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>J'ai utilis\u00e9 une base de donn\u00e9es de test, o\u00f9 j'avais deux tableaux. Un tableau avec les factures des clients, l'autre avec les op\u00e9rations sur ces comptes. Et \u00e0 intervalles r\u00e9guliers, nous mettons \u00e0 jour les soldes de ces comptes.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1d2a21278b095b07546e1bb870819dbf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Les donn\u00e9es initiales du tableau : il est relativement petit, 2 Mo. Le temps de r\u00e9ponse de la base et sp\u00e9cifiquement du tableau est \u00e9galement tr\u00e8s bon. Et la charge est assez importante \u2013 2000 op\u00e9rations par seconde sur le tableau.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/dea5a4b1ac7952f8cfed0e2e1cfc10dd.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c0 travers cette pr\u00e9sentation, je vais vous montrer des graphiques pour illustrer clairement ce qui se passe. Il y aura toujours 2 diapositives avec des graphiques. La premi\u00e8re diapositive montre ce qui se passe en g\u00e9n\u00e9ral sur le serveur. <\/p>\n<p><\/p>\n<p>Dans cette situation, nous voyons effectivement que notre tableau est de petite taille. L'index est \u00e9galement petit, \u00e0 2 Mo. C'est le premier graphique \u00e0 gauche. <\/p>\n<p><\/p>\n<p>Le temps de r\u00e9ponse moyen sur le serveur est \u00e9galement stable et faible. C'est le graphique en haut \u00e0 droite. <\/p>\n<p><\/p>\n<p>Le graphique en bas \u00e0 gauche montre les transactions les plus longues. Nous constatons que les transactions sont rapidement ex\u00e9cut\u00e9es. Et l'auto-vacuum n'est pas encore op\u00e9rationnel ici, car c'\u00e9tait un test initial. Par la suite, il fonctionnera et sera b\u00e9n\u00e9fique pour nous.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e9b46acd9a878ff70ca4a7850adff09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Le deuxi\u00e8me diapositive sera toujours consacr\u00e9 \u00e0 la table test. Dans cette situation, nous mettons constamment \u00e0 jour les soldes des comptes des clients. Et nous constatons que le temps de r\u00e9ponse moyen pour les op\u00e9rations de mise \u00e0 jour est assez bon, inf\u00e9rieur \u00e0 une milliseconde. Nous voyons \u00e9galement que les ressources CPU (c'est le graphique en haut \u00e0 droite) sont utilis\u00e9es de mani\u00e8re uniforme et restent relativement faibles. <\/p>\n<p><\/p>\n<p>Le graphique en bas \u00e0 droite montre combien de m\u00e9moire op\u00e9rationnelle et de disque nous analysons \u00e0 la recherche de notre ligne n\u00e9cessaire avant de la mettre \u00e0 jour. Et le nombre d'op\u00e9rations sur la table est de 2 000 par seconde, comme je l'ai mentionn\u00e9 au d\u00e9but. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/84760d52716209b8dcfffb462c67a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et maintenant, nous faisons face \u00e0 une trag\u00e9die. Pour une raison quelconque, une transaction oubli\u00e9e se produit. Les raisons sont g\u00e9n\u00e9ralement banales : <\/p>\n<p><\/p>\n<ul>\n<li>L'une des causes les plus fr\u00e9quentes est que nous avons commenc\u00e9 \u00e0 appeler un service externe depuis le code de l'application. Et ce service ne r\u00e9pond pas. C'est-\u00e0-dire que nous avons ouvert une transaction, effectu\u00e9 une modification dans la base de donn\u00e9es et sommes partis lire nos e-mails ou consulter un autre service dans notre infrastructure, et pour une raison quelconque, il ne r\u00e9pond pas. Nous avons donc une session suspendue dans un \u00e9tat \u2013 on ne sait pas quand cela sera r\u00e9solu.<\/li>\n<li>La deuxi\u00e8me situation survient lorsque, pour une raison quelconque, une exception se produit dans notre code. Et nous n'avons pas trait\u00e9 la fermeture de la transaction dans l'exception. Nous avons donc une session suspendue avec une transaction ouverte. <\/li>\n<li>Et enfin, le dernier \u2013 c'est \u00e9galement un cas assez fr\u00e9quent. C'est du code de mauvaise qualit\u00e9. Certains frameworks ouvrent une transaction. Elle reste en suspens, et vous pouvez ne pas savoir dans l'application qu'elle est toujours active. <\/li>\n<\/ul>\n<p><\/p>\n<p>Quelles sont les cons\u00e9quences de telles situations ? <\/p>\n<p><\/p>\n<p>Elles entra\u00eenent un gonflement soudain des tables et des index. C'est exactement cet effet de bloat. Pour la base de donn\u00e9es, cela se traduira par une augmentation significative du temps de r\u00e9ponse, une augmentation de la charge sur le serveur de base de donn\u00e9es. En cons\u00e9quence, notre application souffrira. Parce que si dans votre code, vous consacriez 10 millisecondes \u00e0 une requ\u00eate dans la base, 10 millisecondes \u00e0 votre logique, votre fonction s'ex\u00e9cutait en 20 millisecondes. Or maintenant, votre situation sera tout \u00e0 fait pr\u00e9occupante. <\/p>\n<p><\/p>\n<p>Voyons ce qui se passe. Le graphique en bas \u00e0 gauche montre que nous avons une transaction longue. Et si nous regardons le graphique en haut \u00e0 gauche, nous constatons que la taille de la table de deux m\u00e9gaoctets a soudainement grimp\u00e9 \u00e0 300 m\u00e9gaoctets. Pendant ce temps, la quantit\u00e9 de donn\u00e9es dans la table n'a pas chang\u00e9, c'est-\u00e0-dire qu'il y a pas mal de d\u00e9chets.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/b1947f6487e440a770a1251a955e62d2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La situation g\u00e9n\u00e9rale concernant le temps de r\u00e9ponse moyen du serveur a \u00e9galement chang\u00e9 de plusieurs ordres de grandeur. Tous les requ\u00eates au serveur ont commenc\u00e9 \u00e0 ralentir consid\u00e9rablement. De plus, des processus internes de Postgres, sous forme d'autovacuum, se sont lanc\u00e9s, essayant de faire quelque chose et consommant des ressources.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/8e91f035d1dd04e72e842d714cc611a5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Que se passe-t-il alors avec notre table ? La m\u00eame chose. Le temps de r\u00e9ponse moyen pour la table a \u00e9galement cru de plusieurs ordres de grandeur. En ce qui concerne les ressources consomm\u00e9es, nous voyons que la charge sur le processeur a fortement augment\u00e9. C'est le graphique en haut \u00e0 droite. Et cela a augment\u00e9 parce que le processeur doit parcourir une multitude de lignes inutiles \u00e0 la recherche d'une seule n\u00e9cessaire. C'est le graphique en bas \u00e0 droite. En cons\u00e9quence, le nombre d'appels par seconde a commenc\u00e9 \u00e0 chuter fortement, car la base n'arrive pas \u00e0 traiter le m\u00eame nombre de requ\u00eates. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/424685ce852bc5f3ef77151f8d3d7289.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nous devons revenir \u00e0 la normale. Nous allons sur Internet et d\u00e9couvrons que les transactions longues posent probl\u00e8me. Nous trouvons et tuons cette transaction. Et tout redevient normal. Tout fonctionne comme il se doit. <\/p>\n<p><\/p>\n<p>Nous sommes calm\u00e9s, mais apr\u00e8s un certain temps, nous commen\u00e7ons \u00e0 remarquer que l'application ne fonctionne pas aussi bien qu'avant l'incident. Les requ\u00eates sont toujours trait\u00e9es plus lentement, et ce de mani\u00e8re significative. Dans mon exemple, elles sont lentement trait\u00e9es une fois et demie \u00e0 deux fois plus. La charge sur le serveur est \u00e9galement sup\u00e9rieure \u00e0 celle d'avant l'accident. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3037719a31f8d18fc42745716c4da5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et la question est : \u00ab Que se passe-t-il avec la base \u00e0 ce moment-l\u00e0 ? \u00bb. Voici ce qui se passait avec la base. Sur le graphique des transactions, vous voyez qu'il s'est arr\u00eat\u00e9 et qu'il n'y a pas vraiment de longues transactions. Mais les tailles des tables ont fatidiquement augment\u00e9 pendant l'accident. Et elles ne se sont pas r\u00e9duites depuis. Le temps moyen pour la base s'est stabilis\u00e9. Les r\u00e9ponses semblent circuler de mani\u00e8re ad\u00e9quate \u00e0 une vitesse acceptable pour nous. L'autovacuum est devenu plus actif et a commenc\u00e9 \u00e0 faire quelque chose avec la table, car il doit traiter un plus grand nombre de donn\u00e9es. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/f6205242c4024dc3ed4cade5844dbf76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Concernant le tableau test\u00e9 avec les comptes, o\u00f9 nous modifions les soldes : le temps de r\u00e9ponse des requ\u00eates semble \u00eatre revenu \u00e0 la normale. Mais en r\u00e9alit\u00e9, il est une fois et demie plus \u00e9lev\u00e9.<\/p>\n<p><\/p>\n<p>Et concernant la charge sur le processeur, nous constatons qu'elle n'est pas revenue \u00e0 la valeur souhait\u00e9e avant l'accident. Les raisons se trouvent dans le graphique en bas \u00e0 droite. On peut voir qu'il y a un certain surco\u00fbt en m\u00e9moire. Autrement dit, pour trouver la bonne ligne, nous consommons les ressources du serveur de la base de donn\u00e9es en parcourant des donn\u00e9es inutiles. Le nombre de transactions par seconde s'est stabilis\u00e9. <\/p>\n<p><\/p>\n<p>Dans l'ensemble, c'est bien, mais la situation est pire qu'avant. Il y a une d\u00e9gradation \u00e9vidente de la base de donn\u00e9es en raison de notre application qui interagit avec cette base de donn\u00e9es. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/0dfc9cd453fd84bc639ffd99cf189fd2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et pour comprendre ce qui se passe, si vous n'\u00e9tiez pas pr\u00e9sents lors de la pr\u00e9c\u00e9dente pr\u00e9sentation, voici un peu de th\u00e9orie. Une th\u00e9orie sur le processus interne. Quel est le but d'un autovacuum et que fait-il ?<\/p>\n<p><\/p>\n<p>En bref, pour comprendre. \u00c0 un moment donn\u00e9, nous avons une table. Dans cette table, nous avons des lignes. Ces lignes peuvent \u00eatre actives, vivantes, n\u00e9cessaires \u00e0 l'instant. Dans l'image, elles sont marqu\u00e9es en vert. Et il y a des lignes mortes, qui ont d\u00e9j\u00e0 \u00e9t\u00e9 trait\u00e9es, mises \u00e0 jour, pour lesquelles de nouvelles entr\u00e9es ont \u00e9t\u00e9 cr\u00e9\u00e9es. Elles sont marqu\u00e9es comme \u00e9tant d\u00e9j\u00e0 non int\u00e9ressantes pour la base de donn\u00e9es. Mais elles restent dans la table \u00e0 cause des sp\u00e9cificit\u00e9s de Postgres.<\/p>\n<p><\/p>\n<p>\u00c0 quoi sert l'autovacuum ? L'autovacuum, \u00e0 un moment donn\u00e9, s'adresse \u00e0 la base de donn\u00e9es et lui demande : \u00ab Donnez-moi, s'il vous pla\u00eet, l'id de la transaction la plus ancienne qui est actuellement ouverte dans la base de donn\u00e9es. \u00bb La base de donn\u00e9es retourne cet id. Et l'autovacuum s'appuie sur celui-ci pour parcourir les lignes de la table. Et s'il constate que certaines lignes ont \u00e9t\u00e9 modifi\u00e9es par des transactions beaucoup plus anciennes, alors il a le droit de les marquer comme des lignes que nous pourrons r\u00e9utiliser \u00e0 l'avenir, en y \u00e9crivant de nouvelles donn\u00e9es. C'est un processus d'arri\u00e8re-plan.<\/p>\n<p><\/p>\n<p>Pendant ce temps, nous continuons \u00e0 travailler avec la base de donn\u00e9es, nous continuons \u00e0 apporter des modifications \u00e0 la table. Et sur ces lignes que nous pouvons r\u00e9utiliser, nous \u00e9crivons de nouvelles donn\u00e9es. Ainsi, nous avons un cycle : il y a toujours des vieilles lignes mortes qui apparaissent, et \u00e0 leur place, nous \u00e9crivons de nouvelles lignes dont nous avons besoin. Et c'est l'\u00e9tat normal pour le fonctionnement de PostgreSQL.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/98dd4451a7ca5f418775f72822c2840c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Que s'est-il pass\u00e9 lors de l'accident ? Comment ce processus s'est-il d\u00e9roul\u00e9 ?<\/p>\n<p><\/p>\n<p>Nous avions un tableau dans un \u00e9tat particulier, avec certaines lignes actives et d'autres mortes. Un autovacuum est arriv\u00e9. Il a demand\u00e9 \u00e0 la base de donn\u00e9es quelle \u00e9tait notre plus ancienne transaction et quel \u00e9tait son id. Il a obtenu cet id, qui peut remonter \u00e0 plusieurs heures ou \u00e0 dix minutes. Cela d\u00e9pend de la charge sur votre base de donn\u00e9es. Puis il est all\u00e9 chercher les lignes qu'il pouvait marquer comme r\u00e9utilisables. Mais il n'a trouv\u00e9 aucune ligne dans notre tableau. <\/p>\n<p><\/p>\n<p>Mais pendant ce temps, nous continuons \u00e0 travailler avec le tableau. Nous faisons des modifications, nous mettons \u00e0 jour des donn\u00e9es. Et que peut faire la base de donn\u00e9es pendant ce temps ? Elle n'a d'autre choix que d'ajouter de nouvelles lignes \u00e0 la fin du tableau existant. Ainsi, la taille de notre tableau commence \u00e0 augmenter. <\/p>\n<p><\/p>\n<p>En r\u00e9alit\u00e9, nous avons besoin de lignes vertes pour le travail. Mais pendant un tel probl\u00e8me, nous constatons que le pourcentage de lignes vertes est extr\u00eamement faible par rapport \u00e0 l'ensemble du tableau. <\/p>\n<p><\/p>\n<p>Et quand nous ex\u00e9cutons une requ\u00eate, la base de donn\u00e9es doit examiner toutes les lignes : rouges et vertes, pour trouver la ligne n\u00e9cessaire. L'effet de gonflement du tableau avec des donn\u00e9es inutiles est appel\u00e9 \u00ab bloat \u00bb, qui consomme aussi notre espace disque. Vous vous rappelez, c'\u00e9tait 2 Mo, \u00e7a a augment\u00e9 \u00e0 300 Mo ? Maintenant, remplacez les m\u00e9gaoctets par des gigaoctets et vous perdrez assez rapidement toutes vos r\u00e9serves de ressources disque.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/fe7cb6b5c99610744ebcfe5ad7235d1e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quelles peuvent \u00eatre les cons\u00e9quences pour nous ? <\/p>\n<p><\/p>\n<ul>\n<li>Dans mon exemple, le tableau et l'index ont grossi de 150 fois. Certains de nos clients ont connu des cas plus fatals, o\u00f9 l'espace disque a commenc\u00e9 \u00e0 manquer. <\/li>\n<li>La taille des tableaux ne diminuera jamais d'elle-m\u00eame. L'autovacuum peut, dans certains cas, couper la queue d'un tableau, s'il n'y a que des lignes mortes. Mais comme il y a une rotation constante, une ligne verte peut rester \u00e0 la fin sans mise \u00e0 jour, tandis que toutes les autres seront \u00e9crites quelque part au d\u00e9but du tableau. Mais c'est un \u00e9v\u00e9nement tellement improbable que vous ne devriez pas esp\u00e9rer que votre tableau diminue en taille. <\/li>\n<li>La base de donn\u00e9es doit parcourir toute une pile de lignes inutiles. Et nous gaspillons des ressources disque, des ressources processeur et de l'\u00e9nergie. <\/li>\n<li>Et cela affecte directement notre application, car si au d\u00e9part nous d\u00e9pensions 10 millisecondes pour la requ\u00eate et 10 millisecondes pour notre code, pendant la panne, nous en venions \u00e0 d\u00e9penser une seconde pour la requ\u00eate et 10 millisecondes pour le code, c'est-\u00e0-dire que la performance de l'application a chut\u00e9 d'un ordre de grandeur. Et quand la panne a \u00e9t\u00e9 r\u00e9solue, nous avons commenc\u00e9 \u00e0 d\u00e9penser 20 millisecondes pour la requ\u00eate et 10 millisecondes pour le code. Cela signifie que nous avons tout de m\u00eame subi une baisse de performance de 1,5 fois. Et tout cela \u00e0 cause d'une seule transaction qui \u00e9tait suspendue, probablement \u00e0 cause de notre erreur. <\/li>\n<li>La question est donc : \u00ab Comment tout ramener en arri\u00e8re ? \u00bb pour que tout aille bien et que les requ\u00eates soient \u00e0 nouveau aussi rapides qu'avant la panne. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/1bf46e8cd9b28ca2862f978f2ca85819.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pour cela, il y a un certain cycle de travail qui doit \u00eatre effectu\u00e9. <\/p>\n<p><\/p>\n<p>D'abord, nous devons identifier les tables probl\u00e9matiques qui se sont \u00e9tendues. Nous comprenons que certaines tables enregistrent plus activement, tandis que d'autres le font moins. Et pour cela, nous utilisons l'extension <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>. En installant cette extension, vous pouvez \u00e9crire des requ\u00eates qui vous aideront \u00e0 trouver les tables qui se sont consid\u00e9rablement \u00e9tendues. <\/p>\n<p><\/p>\n<p>Une fois que vous avez trouv\u00e9 ces tables, elles doivent \u00eatre compact\u00e9es. Pour cela, il existe d\u00e9j\u00e0 des outils. Dans notre entreprise, nous utilisons trois outils. Le premier est le VACUUM FULL int\u00e9gr\u00e9. Il est s\u00e9v\u00e8re, brutal et impitoyable, mais parfois tr\u00e8s utile. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Pg_repack<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex> sont des utilitaires tiers pour compresser les tables. Et ils sont plus doux avec la base de donn\u00e9es. <\/p>\n<p><\/p>\n<p>Ils sont utilis\u00e9s en fonction de ce qui vous convient le mieux. Mais j'en reparlerai \u00e0 la fin. L'important, c'est qu'il y a trois outils. Vous avez le choix. <\/p>\n<p><\/p>\n<p>Une fois que tout est corrig\u00e9 et que nous avons v\u00e9rifi\u00e9 que tout va bien, nous devons savoir comment \u00e9viter cette situation \u00e0 l'avenir :<\/p>\n<p><\/p>\n<ul>\n<li>C'est assez facile \u00e0 pr\u00e9venir. Il faut surveiller la dur\u00e9e des sessions sur le serveur ma\u00eetre. <strong>Les sessions particuli\u00e8rement dangereuses sont celles en \u00e9tat idle in transaction.<\/strong>Ce sont celles qui ont ouvert une transaction, ont fait quelque chose, puis se sont \u00e9loign\u00e9es ou se sont perdues dans le code. <\/li>\n<li>Et pour vous, en tant que d\u00e9veloppeurs, il est important de tester le code au moment o\u00f9 ces situations se produisent. Ce n'est pas difficile \u00e0 faire. Cela sera un contr\u00f4le utile. Vous \u00e9viterez un grand nombre de \u00ab probl\u00e8mes de d\u00e9butant \u00bb li\u00e9s aux transactions prolong\u00e9es. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/d55465d96c4018db733954867d23aaba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sur ces graphiques, je voulais vous montrer comment la table et le comportement de la base de donn\u00e9es ont chang\u00e9 apr\u00e8s avoir effectu\u00e9 un VACUUM FULL sur la table dans ce cas. Ce n\u2019est pas en production.<\/p>\n<p><\/p>\n<p>La taille de la table est revenue imm\u00e9diatement \u00e0 un \u00e9tat de fonctionnement normal de quelques m\u00e9gaoctets. Cela n'a pas trop influenc\u00e9 le temps de r\u00e9ponse moyen du serveur. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cbb07ad24dba899395223d1ca25e438e.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Mais concernant notre table exp\u00e9rimentale, o\u00f9 nous avons mis \u00e0 jour les soldes, nous constatons que le temps de r\u00e9ponse moyen pour la mise \u00e0 jour des donn\u00e9es dans la table a \u00e9t\u00e9 r\u00e9duit \u00e0 un niveau acceptable. Les ressources processeur utilis\u00e9es pour ex\u00e9cuter cette requ\u00eate ont \u00e9galement diminu\u00e9 \u00e0 un niveau acceptable. Et le graphique en bas \u00e0 droite montre que nous trouvons maintenant exactement la ligne dont nous avons besoin imm\u00e9diatement, sans avoir \u00e0 parcourir un tas de lignes mortes qui existaient avant la compression de la table. Et le temps moyen des requ\u00eates est rest\u00e9 \u00e0 peu pr\u00e8s le m\u00eame. Mais ici, j'ai probablement des limites li\u00e9es \u00e0 mon mat\u00e9riel.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c1d90c5442e02fce209dc40e048a8ca2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'est la premi\u00e8re histoire. Elle est la plus courante. Cela arrive \u00e0 tout le monde, ind\u00e9pendamment de l'exp\u00e9rience du client et des comp\u00e9tences des programmeurs. T\u00f4t ou tard, cela se produit. <\/p>\n<p><\/p>\n<p>Deuxi\u00e8me histoire, dans laquelle nous r\u00e9partissons la charge et optimisons les ressources serveur.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/cda421c554d1329107ddc935045cc1b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Nous avons d\u00e9j\u00e0 grandi et sommes devenus des acteurs s\u00e9rieux. Nous comprenons que nous avons une r\u00e9plique et qu'il serait bien de r\u00e9partir la charge : \u00e9crire sur le Ma\u00eetre et lire depuis la r\u00e9plique. Cette situation se pr\u00e9sente g\u00e9n\u00e9ralement lorsque nous voulons pr\u00e9parer certains rapports ou ETL. Et le business s'en r\u00e9jouit beaucoup. Il d\u00e9sire vraiment divers rapports avec une analyse complexe. <\/li>\n<li>Les rapports prennent des heures car il n'est pas possible de calculer une analyse complexe en quelques millisecondes. En tant que fiers d\u00e9veloppeurs, nous \u00e9crivons du code. Dans l'application, nous effectuons des insertions pour que l'enregistrement se fasse sur le Ma\u00eetre, tandis que les rapports s'ex\u00e9cutent sur la r\u00e9plique. <\/li>\n<li>Nous r\u00e9partissons la charge. <\/li>\n<li>Tout fonctionne parfaitement. Bravo \u00e0 nous. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/e94c8c492197a5015ac8aae79389a4c2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et \u00e0 quoi ressemble cette situation ? Concr\u00e8tement, sur ces graphiques, j'ai \u00e9galement ajout\u00e9 la dur\u00e9e des transactions depuis la r\u00e9plique. Tous les autres graphiques concernent uniquement le serveur Ma\u00eetre. <\/p>\n<p><\/p>\n<p>Le tableau des rapports a consid\u00e9rablement augment\u00e9 jusqu'\u00e0 pr\u00e9sent. Nous constatons que le temps de r\u00e9ponse moyen du serveur est stable. Nous avons \u00e9galement une transaction longue sur la r\u00e9plique, qui dure 2 heures. Le fonctionnement de l'autovacuum, qui g\u00e8re les lignes mortes, est \u00e9galement calme. Tout se passe bien. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2da8acf098d12d6f146ab9b9dcb54b81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Concernant le tableau test\u00e9, nous continuons \u00e0 mettre \u00e0 jour les soldes sur les comptes. Nous avons \u00e9galement un temps de r\u00e9ponse stable pour la requ\u00eate et une consommation de ressources stable. Tout se passe bien. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/3621ef723017bac6fb635caf0a5f4de6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tout va bien jusqu'\u00e0 ce que ces rapports commencent \u00e0 \u00e9chouer en raison de conflits de r\u00e9plication. Et ils \u00e9chouent avec une fr\u00e9quence constante. <\/p>\n<p><\/p>\n<p>Nous faisons des recherches en ligne pour comprendre pourquoi cela se produit. Et nous trouvons une solution. <\/p>\n<p><\/p>\n<p>La premi\u00e8re solution consiste \u00e0 augmenter le d\u00e9lai de r\u00e9plication. Nous savons que notre rapport prend 3 heures. Nous d\u00e9finissons le d\u00e9lai de r\u00e9plication \u00e0 3 heures. Nous lan\u00e7ons tout, mais nous avons toujours des probl\u00e8mes avec des rapports qui \u00e9chouent parfois. <\/p>\n<p><\/p>\n<p>Nous voulons que tout soit parfait. Nous continuons nos recherches et d\u00e9couvrons un param\u00e8tre g\u00e9nial en ligne \u2013 hot_standby_feedback. Nous l'activons. Hot_standby_feedback nous permet de retenir le fonctionnement de l'autovacuum sur le ma\u00eetre. Ainsi, nous \u00e9liminons compl\u00e8tement les conflits de r\u00e9plication. Et tout fonctionne bien avec les rapports.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/ee3c315168bdd3f392d2e8a1c5861004.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Que se passe-t-il pendant ce temps avec le serveur ma\u00eetre ? Eh bien, il subit une crise totale. Actuellement, nous observons les graphiques depuis que j'ai activ\u00e9 ces deux param\u00e8tres. Nous constatons que la session sur la r\u00e9plique influence d'une mani\u00e8re ou d'une autre la situation sur le serveur ma\u00eetre. Elle a r\u00e9ellement un impact, car elle a suspendu l'autovacuum, qui d\u00e9barrasse les lignes mortes. La taille de la table a de nouveau grimp\u00e9 en fl\u00e8che. Le temps moyen d'ex\u00e9cution des requ\u00eates dans toute la base de donn\u00e9es a \u00e9galement augment\u00e9. Les autovacuums sont un peu plus sollicit\u00e9s. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/980611dcce8b189dc50f422ffd3d2d72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Concernant notre tableau, nous voyons \u00e9galement que la mise \u00e0 jour des donn\u00e9es a augment\u00e9. La consommation des ressources processeur a \u00e9galement consid\u00e9rablement augment\u00e9. Nous parcourons de nouveau un grand nombre de lignes mortes et inutiles. Et le temps de r\u00e9ponse pour ce tableau, le nombre de transactions a chut\u00e9. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a648fd313a5dccf45f0056dc13c54263.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>\u00c0 quoi cela ressemblerait-il si nous ignorons ce dont je parlais auparavant ?<\/p>\n<p><\/p>\n<ul>\n<li>Nous commen\u00e7ons \u00e0 rechercher des probl\u00e8mes. Si nous avons rencontr\u00e9 des probl\u00e8mes dans la premi\u00e8re partie, nous savons que cela peut \u00eatre d\u00fb \u00e0 une transaction longue et nous plongeons dans le Master. Le probl\u00e8me se situe sur le Master. \u00c7a bug. Il chauffe, sa charge moyenne fr\u00f4le les cent. <\/li>\n<li>Les requ\u00eates ralentissent l\u00e0-bas, mais nous ne voyons aucune transaction longue. Et nous ne comprenons pas pourquoi. Nous ne savons pas o\u00f9 chercher. <\/li>\n<li>Nous v\u00e9rifions le mat\u00e9riel du serveur. Peut-\u00eatre que notre RAID a \u00e9chou\u00e9. Peut-\u00eatre qu'une barrette de RAM a br\u00fbl\u00e9. Tout peut arriver. Mais non, les serveurs sont neufs, tout fonctionne parfaitement. <\/li>\n<li>Tout le monde court : administrateurs, d\u00e9veloppeurs et directeur. Rien n'y fait. <\/li>\n<li>Et \u00e0 un moment donn\u00e9, tout commence soudainement \u00e0 se corriger tout seul. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/7d4f6417bc5cb3cec33679d843c6661d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sur la r\u00e9plique, \u00e0 ce moment, une requ\u00eate a \u00e9t\u00e9 trait\u00e9e et est partie. Nous avons re\u00e7u un rapport. L'entreprise est toujours satisfaite. Comme nous le voyons, notre tableau a encore grandi et ne compte pas diminuer. Sur le graphique des sessions, j'ai laiss\u00e9 un extrait de cette longue transaction depuis la r\u00e9plique, afin que vous puissiez \u00e9valuer combien de temps il faut avant que la situation ne se stabilise. <\/p>\n<p><\/p>\n<p>La session est partie. Et seulement apr\u00e8s un certain temps, le serveur revient plus ou moins \u00e0 la normale. Le temps de r\u00e9ponse moyen des requ\u00eates sur le serveur Master redevient normal. Parce que, enfin, l'autovacuum a pu commencer \u00e0 nettoyer, \u00e0 marquer ces lignes mortes. Et il a commenc\u00e9 \u00e0 faire son travail. Et aussi rapidement qu'il le fait, c'est aussi rapidement que nous reviendrons \u00e0 la normale.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/547d195e08de1566da818150a47218eb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sur le tableau test\u00e9, o\u00f9 nous mettons \u00e0 jour les soldes des comptes, nous voyons exactement la m\u00eame image. Le temps moyen de mise \u00e0 jour des soldes se normalise \u00e9galement progressivement. Les ressources utilis\u00e9es par le processeur diminuent aussi. Et le nombre de transactions par seconde revient \u00e0 la normale. Mais \u00e0 nouveau, ce n'est pas la m\u00eame normalit\u00e9 qu'avant l'accident. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/29372a5e9124690931485a7aea65befc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dans tous les cas, nous subissons une baisse de performance, tout comme dans le premier cas, d'un niveau et demi \u00e0 deux fois, voire plus parfois. <\/p>\n<p><\/p>\n<p>Nous avons l'impression d'avoir fait tout correctement. Nous avons r\u00e9parti la charge. Le mat\u00e9riel ne reste pas inactif. Nous avons judicieusement r\u00e9parti les requ\u00eates, mais cela n'a toujours pas bien fonctionn\u00e9. <\/p>\n<p><\/p>\n<ul>\n<li>Ne pas activer hot_standby_feedback ? Oui, il n'est pas recommand\u00e9 de l'activer sans raison valable. Car ce param\u00e8tre affecte directement le serveur principal et suspend le fonctionnement de l'autovacuum. En l'activant sur une r\u00e9plique et en l'oubliant, vous risquez de compromettre le ma\u00eetre et de rencontrer de s\u00e9rieux probl\u00e8mes avec l'application. <\/li>\n<li>Augmenter max_standby_streaming_delay ? Oui, pour les rapports \u2013 c'est tout \u00e0 fait pertinent. Si vous avez un rapport de trois heures et que vous ne souhaitez pas qu'il \u00e9choue \u00e0 cause de conflits de r\u00e9plication, augmentez simplement le d\u00e9lai. Un rapport long ne n\u00e9cessite jamais des donn\u00e9es arriv\u00e9es dans la base \u00e0 cet instant. S'il est sur trois heures, cela signifie que vous l'ex\u00e9cutez sur une p\u00e9riode de donn\u00e9es ant\u00e9rieure. Et que ce soit trois heures de retard ou six heures de retard \u2013 cela n'aura pas d'importance, mais vous recevrez des rapports stables sans vous soucier des interruptions. <\/li>\n<li>Il est naturellement important de surveiller les sessions longues sur les r\u00e9pliques, surtout si vous avez d\u00e9cid\u00e9 d'activer hot_standby_feedback sur la r\u00e9plique. Car tout peut se produire. Vous avez donn\u00e9 cette r\u00e9plique \u00e0 un d\u00e9veloppeur pour qu'il teste des requ\u00eates. Il a \u00e9crit une requ\u00eate complexe. L'a lanc\u00e9e et est parti prendre un th\u00e9, tandis que nous avons obtenu un ma\u00eetre engorg\u00e9. Ou nous avons laiss\u00e9 entrer une application inappropri\u00e9e. Les situations sont vari\u00e9es. Les sessions sur les r\u00e9pliques doivent \u00eatre surveill\u00e9es aussi soigneusement que sur le ma\u00eetre. <\/li>\n<li>Et si vous avez des requ\u00eates rapides et longues sur les r\u00e9pliques, il est pr\u00e9f\u00e9rable de les r\u00e9partir pour une meilleure gestion de la charge. Cela fait r\u00e9f\u00e9rence \u00e0 streaming_delay. Pour les rapides, avoir une r\u00e9plique avec un petit retard de r\u00e9plication. Pour les longues requ\u00eates de rapport, avoir une r\u00e9plique qui peut avoir un retard de 6 heures, voire d'un jour. C'est une situation tout \u00e0 fait normale. <\/li>\n<\/ul>\n<p><\/p>\n<p>Nous \u00e9liminons les cons\u00e9quences de la m\u00eame mani\u00e8re :<\/p>\n<p><\/p>\n<ul>\n<li>Nous identifions les tables surdimensionn\u00e9es.<\/li>\n<li>Et nous les compressons avec l'outil le plus appropri\u00e9 pour nous. <\/li>\n<\/ul>\n<p><\/p>\n<p>Cette histoire s'est termin\u00e9e ici. Passons \u00e0 la troisi\u00e8me histoire. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/c8784e0be27883640cb8f6919a1c25e0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'est aussi un cas assez courant pour nous, o\u00f9 nous effectuons une migration. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/a04b9cd88a0e7e8a3b960ef930eb2657.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<ul>\n<li>Tout produit logiciel \u00e9volue. Ses exigences changent. Nous voulons progresser. Et il arrive que nous devions mettre \u00e0 jour les donn\u00e9es dans la table, en faisant passer une mise \u00e0 jour dans le cadre de notre migration vers de nouvelles fonctionnalit\u00e9s que nous int\u00e9grons dans notre d\u00e9veloppement. <\/li>\n<li>Le format de donn\u00e9es ancien ne convient pas. Supposons que nous nous tournions maintenant vers le deuxi\u00e8me tableau, o\u00f9 j'ai les op\u00e9rations pour ces comptes. Et, disons qu'elles \u00e9taient en roubles, mais nous avons d\u00e9cid\u00e9 d'augmenter la pr\u00e9cision et de travailler en kopecks. Pour cela, nous devons effectuer une mise \u00e0 jour : multiplier le champ avec le montant de l'op\u00e9ration par cent. <\/li>\n<li>Dans le monde moderne, nous utilisons des moyens automatis\u00e9s de contr\u00f4le de version de base de donn\u00e9es. Supposons, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.liquibase.org\/\">Liquibase<\/a><\/noindex>. Nous y d\u00e9crivons notre migration. Nous la testons sur notre base de test. Tout va bien. La mise \u00e0 jour a lieu. Cela bloque le travail pendant un certain temps, mais nous obtenons des donn\u00e9es mises \u00e0 jour. Nous pouvons lancer de nouvelles fonctionnalit\u00e9s \u00e0 partir de cela. Nous avons tout test\u00e9, v\u00e9rifi\u00e9. Tout a \u00e9t\u00e9 confirm\u00e9. <\/li>\n<li>Nous avons effectu\u00e9 des travaux planifi\u00e9s, r\u00e9alis\u00e9 la migration. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/9e046583f7b1723fc1eaf61a03900918.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voici la migration avec mise \u00e0 jour pr\u00e9sent\u00e9e devant vous. Comme il s'agit d'op\u00e9rations sur des comptes, le tableau faisait 15 Go. Et comme nous mettrons \u00e0 jour chaque ligne, nous avons doubl\u00e9 la taille du tableau avec notre mise \u00e0 jour, car nous avons r\u00e9\u00e9crit chaque ligne. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/06120c98ea43d0568045e71935c23592.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pendant la migration, nous ne pouvions rien faire avec ce tableau, car toutes les requ\u00eates \u00e0 celui-ci \u00e9taient en attente et attendaient que cette mise \u00e0 jour soit termin\u00e9e. Mais ici, je veux attirer votre attention sur les chiffres sur l'axe vertical. C'est-\u00e0-dire que nous avons un temps de requ\u00eate moyen avant la migration d'environ 5 millisecondes et une charge processeur, le nombre d'op\u00e9rations de lecture m\u00e9moire disque, inf\u00e9rieure \u00e0 7,5. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/69a3ba4d1d0cec7d39284e09e9d3055b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nous avons effectu\u00e9 la migration et rencontr\u00e9 \u00e0 nouveau des probl\u00e8mes. <\/p>\n<p><\/p>\n<p>La migration a r\u00e9ussi, mais :<\/p>\n<p><\/p>\n<ul>\n<li>Le fonctionnement ancien a pris plus de temps. <\/li>\n<li>La taille de la table a \u00e0 nouveau augment\u00e9. <\/li>\n<li>La charge sur le serveur est \u00e0 nouveau plus importante qu'auparavant. <\/li>\n<li>Et, bien s\u00fbr, nous avons encore des ajustements \u00e0 faire sur la fonctionnalit\u00e9 qui fonctionnait bien, nous l'avons l\u00e9g\u00e8rement am\u00e9lior\u00e9e. <\/li>\n<\/ul>\n<p><\/p>\n<p>Et cela est \u00e0 nouveau excessif, ce qui nuit \u00e0 notre exp\u00e9rience. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/becd7cce3a1c8821c81c96257f41202b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ici, je montre que le tableau, comme dans les deux cas pr\u00e9c\u00e9dents, ne compte pas revenir \u00e0 des tailles ant\u00e9rieures. La charge moyenne sur le serveur semble raisonnable. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4d703a60d43a3460bc3782d49865b690.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Et si nous nous r\u00e9f\u00e9rons au tableau des factures, nous verrons que le temps moyen de requ\u00eate a doubl\u00e9 pour ce tableau. La charge sur le processeur et le nombre de lignes parcourues en m\u00e9moire a d\u00e9pass\u00e9 7,5, alors qu'il \u00e9tait en dessous. Et cela a doubl\u00e9 pour les processeurs et augment\u00e9 de 1,5 fois pour les op\u00e9rations par blocs, c'est-\u00e0-dire que nous avons constat\u00e9 une d\u00e9gradation des performances du serveur. En cons\u00e9quence, une d\u00e9gradation des performances de notre application. Cependant, le nombre d'appels est rest\u00e9 \u00e0 peu pr\u00e8s au m\u00eame niveau. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/80772afa0643b29f5314a2482c9dfe0d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il est essentiel de comprendre comment effectuer correctement ces migrations. Et il est n\u00e9cessaire de les faire. Nous effectuons assez r\u00e9guli\u00e8rement ces migrations.<\/p>\n<p><\/p>\n<ul>\n<li>De telles grandes migrations ne sont jamais effectu\u00e9es automatiquement. Elles doivent toujours \u00eatre contr\u00f4l\u00e9es. <\/li>\n<li>Un contr\u00f4le est n\u00e9cessaire de la part d'une personne exp\u00e9riment\u00e9e. Si vous avez un DBA dans l'\u00e9quipe, que ce soit lui qui s'en occupe. C'est son travail. Sinon, la personne la plus exp\u00e9riment\u00e9e devrait s'en charger, celle qui sait comment travailler avec des bases de donn\u00e9es. <\/li>\n<li>Le nouveau sch\u00e9ma de base de donn\u00e9es, m\u00eame si nous mettons \u00e0 jour une seule colonne, doit toujours \u00eatre pr\u00e9par\u00e9 par \u00e9tapes, c'est-\u00e0-dire en amont du d\u00e9ploiement de la nouvelle version de l'application :<\/li>\n<li>De nouveaux champs sont ajout\u00e9s pour stocker les donn\u00e9es mises \u00e0 jour. <\/li>\n<li>Nous transf\u00e9rons les donn\u00e9es de l'ancien champ vers le nouveau champ par petites portions. Pourquoi faisons-nous cela ? Tout d'abord, nous contr\u00f4lons toujours le processus. Nous savons que nous avons d\u00e9j\u00e0 transf\u00e9r\u00e9 un certain nombre de lots et qu'il nous en reste encore \u00e0 faire. <\/li>\n<li>Un autre effet positif est qu'entre chaque lot, nous fermons la transaction, en ouvrons une nouvelle et cela permet au syst\u00e8me d'effectuer l'autovacuumer sur la table, en marquant les lignes mortes pour \u00eatre r\u00e9utilis\u00e9es. <\/li>\n<li>Pour les lignes qui appara\u00eetront pendant le fonctionnement de l'application (notre ancienne application est toujours en cours d'ex\u00e9cution), nous ajoutons un d\u00e9clencheur qui enregistre de nouvelles valeurs dans les nouveaux champs. Dans notre cas, cela correspond \u00e0 multiplier par cent la valeur ancienne. <\/li>\n<li>Si nous sommes vraiment obstin\u00e9s et voulons le m\u00eame champ, alors une fois toutes les migrations termin\u00e9es et avant le d\u00e9ploiement de la nouvelle version de l'application, nous simplement renommant les champs. Les anciens prenant un nom fictif, tandis que les nouveaux champs sont renomm\u00e9s en anciens. <\/li>\n<li>Ce n'est qu'apr\u00e8s cela que nous lan\u00e7ons la nouvelle version de l'application. <\/li>\n<\/ul>\n<p><\/p>\n<p>Et ainsi, nous n'aurons pas de bloat et ne subirons pas de d\u00e9gradation des performances. <\/p>\n<p><\/p>\n<p>Cette troisi\u00e8me histoire est maintenant termin\u00e9e. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/2afab2906b5ccd30e4c8772248818057.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql\">https:\/\/github.com\/dataegret\/pg-utils\/blob\/master\/sql\/table_bloat_approx.sql<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Et maintenant, un peu plus en d\u00e9tail sur les outils que j'ai mentionn\u00e9s dans la toute premi\u00e8re histoire. <\/p>\n<p><\/p>\n<p>Avant de chercher le bloat, il est imp\u00e9ratif d'installer l'extension. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/pgstattuple.html\">pgstattuple<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Pour vous \u00e9viter d'inventer des requ\u00eates, nous avons d\u00e9j\u00e0 \u00e9crit ces requ\u00eates dans notre travail. Vous pouvez les utiliser. Deux requ\u00eates sont pr\u00e9sent\u00e9es ici. <\/p>\n<p><\/p>\n<ul>\n<li>La premi\u00e8re fonctionne assez longtemps, mais elle vous montrera les valeurs exactes du bloat dans la table. <\/li>\n<li>La deuxi\u00e8me fonctionne plus rapidement et est tr\u00e8s efficace lorsqu'il s'agit d'\u00e9valuer rapidement \u2013 s'il y a du bloat ou non dans la table. Et vous devez \u00e9galement comprendre que le bloat dans la table Postgres est toujours pr\u00e9sent. C'est une particularit\u00e9 de son mod\u00e8le MVCC. <\/li>\n<li>Et 20 % de bloat est normal pour les tables dans la plupart des cas. Donc, vous ne devriez pas vous inqui\u00e9ter et compresser cette table. <\/li>\n<\/ul>\n<p><\/p>\n<p>Nous avons compris comment identifier les tables qui ont gonfl\u00e9 avec des donn\u00e9es inutiles. <\/p>\n<p><\/p>\n<p>Maintenant, parlons de la fa\u00e7on de corriger le bloat :<\/p>\n<p><\/p>\n<ul>\n<li>Si nous avons une petite table et de bons disques, c'est-\u00e0-dire qu'il est tout \u00e0 fait possible d'utiliser VACUUM FULL sur une table allant jusqu'\u00e0 un gigaoctet. Cela prendra un verrou exclusif sur la table pendant quelques secondes et tout ira bien, mais cela fera le travail rapidement et efficacement. Que fait VACUUM FULL ? Il prend un verrou exclusif sur la table et r\u00e9\u00e9crit les lignes vivantes des anciennes tables dans une nouvelle table. \u00c0 la fin, il remplace leurs places. Il supprime les anciens fichiers et place les nouveaux \u00e0 la place des anciens. Mais pendant son ex\u00e9cution, il prend un verrou exclusif sur la table. Cela signifie que vous ne pourrez rien faire avec cette table : ni y \u00e9crire, ni y lire, ni la modifier. Et VACUUM FULL n\u00e9cessite de l'espace suppl\u00e9mentaire sur le disque pour enregistrer les donn\u00e9es.<\/li>\n<li>L'outil suivant est <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">pg_repack<\/a><\/noindex>. Par son principe, il est tr\u00e8s similaire \u00e0 VACUUM FULL, car il r\u00e9\u00e9crit \u00e9galement les donn\u00e9es \u00e0 partir des anciens fichiers dans de nouveaux et les remplace dans la table. Mais il ne prend pas de verrou exclusif sur la table au d\u00e9but de son fonctionnement, mais seulement au moment o\u00f9 il a d\u00e9j\u00e0 des donn\u00e9es pr\u00eates \u00e0 remplacer les fichiers. Les exigences en mati\u00e8re de ressources disque sont similaires \u00e0 celles de VACUUM FULL. Vous aurez besoin d'espace suppl\u00e9mentaire sur le disque, ce qui peut parfois \u00eatre critique si vous avez des tables de plusieurs t\u00e9raoctets. Et il est assez gourmand en ressources processeur, car il effectue un travail actif d'entr\u00e9e-sortie. <\/li>\n<li>La troisi\u00e8me utilit\u00e9 est <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">pgcompacttable<\/a><\/noindex>Elle g\u00e8re les ressources de mani\u00e8re plus prudente, car elle fonctionne selon des principes l\u00e9g\u00e8rement diff\u00e9rents. L'essence de pgcompacttable est qu'elle d\u00e9place toutes les lignes actives en d\u00e9but de table lors des mises \u00e0 jour. Ensuite, elle ex\u00e9cute un vide en raison de la connaissance que nous avons des lignes vivantes au d\u00e9but et des mortes \u00e0 la fin. Le vide va donc couper cette partie, c'est-\u00e0-dire qu'il n\u00e9cessite peu d'espace disque suppl\u00e9mentaire. De plus, il peut \u00eatre compress\u00e9 en ressources. <\/li>\n<\/ul>\n<p><\/p>\n<p>Tout est dans les outils. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Erreurs typiques dans les applications qui entra\u00eenent un bloat dans PostgreSQL. Andre\u00ef Salnikov\" src=\"\/wp-content\/uploads\/2020\/05\/4187915e54e54a0b85a342fe0280f78f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Si le sujet du bloat vous para\u00eet int\u00e9ressant \u00e0 explorer plus en profondeur, voici quelques liens utiles :<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres\">https:\/\/www.slideshare.net\/alexius2Mb\/where-is-the-space-postgres<\/a><\/noindex> \u2013 c'est une pr\u00e9sentation de mon coll\u00e8gue. Elle aborde de mani\u00e8re g\u00e9n\u00e9rale o\u00f9 l'espace dispara\u00eet dans Postgres durant son fonctionnement. Il y a une grande section technique d\u00e9taill\u00e9e pour les administrateurs de bases de donn\u00e9es sur le bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pg-utils\">https:\/\/github.com\/dataegret\/pg-utils<\/a><\/noindex> \u2013 c'est un lien vers notre d\u00e9p\u00f4t o\u00f9 nous stockons de nombreux scripts utiles pour v\u00e9rifier l'\u00e9tat de la base de donn\u00e9es. Vous y trouverez des scripts pour rechercher le bloat. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/reorg\/pg_repack\">Troisi\u00e8me<\/a><\/noindex> et <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dataegret\/pgcompacttable\">quatri\u00e8me<\/a><\/noindex> liens vers des outils qui vous aideront \u00e0 compresser les tables. <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html\">http:\/\/blog.dataegret.com\/2Mb018\/03\/postgresql-bloatbusters.html<\/a><\/noindex> \u2013 c'est un article de mon coll\u00e8gue. Il examine de mani\u00e8re plut\u00f4t s\u00e9rieuse et technique le bloat, \u00e0 un niveau proche des administrateurs. <\/li>\n<\/ul>\n<p><\/p>\n<p>J'ai essay\u00e9 ici de montrer un aper\u00e7u inqui\u00e9tant pour les d\u00e9veloppeurs, car ils sont nos clients directs des bases de donn\u00e9es et doivent comprendre les cons\u00e9quences de leurs actions. J'esp\u00e8re avoir r\u00e9ussi. Merci de votre attention !<\/p>\n<p><\/p>\n<p>Questions<\/p>\n<p><\/p>\n<p><em>Merci pour la pr\u00e9sentation ! Vous avez parl\u00e9 de la mani\u00e8re de d\u00e9tecter les probl\u00e8mes. Comment peut-on les pr\u00e9venir ? C'est-\u00e0-dire, j'ai eu une situation o\u00f9 des requ\u00eates bloquaient non seulement parce qu'elles faisaient appel \u00e0 des services externes. Il s'agissait de simples joins d\u00e9mesur\u00e9s. Quelques petites requ\u00eates inoffensives sont rest\u00e9es bloqu\u00e9es pendant une journ\u00e9e avant de causer des anomalies. Cela ressemble beaucoup \u00e0 ce que vous d\u00e9crivez. Comment le surveiller ? Faut-il surveiller constamment quelle requ\u00eate est suspendue ? Comment peut-on pr\u00e9venir cela ?<\/em><\/p>\n<p><\/p>\n<p>Dans ce cas, c'est une t\u00e2che pour les administrateurs de votre entreprise, pas forc\u00e9ment pour le DBA.<\/p>\n<p><\/p>\n<p><em>Je suis administrateur.<\/em><\/p>\n<p><\/p>\n<p>Dans PostgreSQL, il existe une vue appel\u00e9e pg_stat_activity qui montre les requ\u00eates en cours. Vous pouvez voir combien de temps elles ont \u00e9t\u00e9 suspendues.<\/p>\n<p><\/p>\n<p><em>Dois-je me connecter toutes les 5 minutes pour v\u00e9rifier ?<\/em><\/p>\n<p><\/p>\n<p>Configure cron and keep checking. If you have a long-running query, send an email and that's it. That is, you don't need to watch it manually; this can be automated. You will receive an email, and you react to it. Or you can shoot it off automatically.<\/p>\n<p><\/p>\n<p><em>Are there obvious reasons why this is happening?<\/em><\/p>\n<p><\/p>\n<p>I've listed some. Others are more complex examples. And the conversation there can be lengthy.<\/p>\n<p><\/p>\n<p><em>Thank you for the presentation! I wanted to clarify about the pg_repack utility. If it doesn't do exclusive locking, then\u2026<\/em><\/p>\n<p><\/p>\n<p>It does perform exclusive locking. <\/p>\n<p><\/p>\n<p>\u2026 <em>Then I could potentially lose data. My application should not be writing at that time, right?<\/em><\/p>\n<p><\/p>\n<p>No, it works fine with the table; that is, pg_repack first moves all active rows. Naturally, some writing occurs in the table. It just appends that tail. <\/p>\n<p><\/p>\n<p><em>That is, it ultimately does it at the end?<\/em><\/p>\n<p><\/p>\n<p>In the end, it takes an exclusive lock to swap those files. <\/p>\n<p><\/p>\n<p><em>Will this be faster than VACUUM FULL?<\/em><\/p>\n<p><\/p>\n<p>VACUUM FULL, as soon as it starts, immediately takes an exclusive lock. And it doesn't release it until everything is done. pg_repack takes an exclusive lock only at the moment of file replacement. At that moment, you can't write to it, but no data will be lost; everything will be fine. <\/p>\n<p><\/p>\n<p><em>Hello! You talked about the autovacuum operation. There was a graph with red, yellow, and green cells for records. That is, the yellow ones are marked as deleted. Consequently, can something new be written to them?<\/em><\/p>\n<p><\/p>\n<p>Yes. Postgres does not delete rows. It has this specificity. If we update a row, we mark the old one as deleted. An ID of the transaction that changed the row appears, and we write a new row. And we have sessions that can potentially read them. At some point, they become completely old. The essence of autovacuum is that it goes through these rows and marks them as unnecessary. And data can be rewritten there. <\/p>\n<p><\/p>\n<p><em>I understand. But the question is a bit different. I didn't finish my thought. Suppose we have a table. It has variable size fields. If I try to insert something new, it may simply not fit in the old cell.<\/em> <\/p>\n<p><\/p>\n<p>Non, toute la ligne est mise \u00e0 jour de toute fa\u00e7on. PostgreSQL dispose de deux mod\u00e8les de stockage des donn\u00e9es. Il choisit en fonction du type de donn\u00e9es. Il y a des donn\u00e9es qui sont stock\u00e9es directement dans la table, et il y a aussi des donn\u00e9es malloc. Ce sont de grands volumes de donn\u00e9es : texte, json. Ils sont stock\u00e9s dans des tables s\u00e9par\u00e9es. Et pour ces tables, c'est la m\u00eame histoire avec le bloat, c\u2019est-\u00e0-dire que c'est tout \u00e0 fait pareil. Sauf qu'elles sont s\u00e9par\u00e9es. <\/p>\n<p><\/p>\n<p><em>Merci pour la pr\u00e9sentation ! Dans quelle mesure est-il acceptable d'utiliser des requ\u00eates de type statement timeout pour limiter la dur\u00e9e des requ\u00eates ?<\/em><\/p>\n<p><\/p>\n<p>C'est tout \u00e0 fait acceptable. Nous l'utilisons partout. Et comme nous n'avons pas de services propres, nous offrons une assistance \u00e0 distance, donc nous avons des clients assez vari\u00e9s. Et cela satisfait tout le monde. C'est-\u00e0-dire que nous avons des t\u00e2ches dans cron qui v\u00e9rifient. On discute simplement avec le client de la dur\u00e9e des sessions, avant laquelle nous ne les terminons pas. Cela peut \u00eatre une minute, cela peut \u00eatre 10 minutes. Cela d\u00e9pend de la charge sur la base et de son objectif. Mais pour tous, nous utilisons pg_stat_activity.<\/p>\n<p><\/p>\n<p><em>Merci pour la pr\u00e9sentation ! J'essaie d'adapter votre pr\u00e9sentation \u00e0 mes applications. Et il semble que nous commen\u00e7ons une transaction partout, et nous la terminons clairement partout. S'il y a une exception, alors un rollback se produit quand m\u00eame. Et je me suis demand\u00e9. En effet, une transaction peut d\u00e9marrer de mani\u00e8re implicite. C'est une indication pour la fille, je suppose. Si je fais simplement une mise \u00e0 jour d'un enregistrement, la transaction commencera dans PostgreSQL et ne se terminera que lorsque la connexion sera interrompue ?<\/em><\/p>\n<p><\/p>\n<p>Si vous parlez maintenant du niveau de l'application, cela d\u00e9pend du driver que vous utilisez, de l'ORM qui est utilis\u00e9. Il y a beaucoup de param\u00e8tres. Si vous avez activ\u00e9 l'auto commit, alors la transaction d\u00e9marre et se ferme imm\u00e9diatement.<\/p>\n<p><\/p>\n<p><em>C'est-\u00e0-dire qu'elle se ferme imm\u00e9diatement apr\u00e8s la mise \u00e0 jour ?<\/em><\/p>\n<p><\/p>\n<p>Cela d\u00e9pend des param\u00e8tres. J'ai mentionn\u00e9 un param\u00e8tre. C'est auto commit. C'est assez courant. S'il est activ\u00e9, alors la transaction est ouverte et ferm\u00e9e. Si vous n'avez pas explicitement dit \u00ab start transaction \u00bb et \u00ab end transaction \u00bb, mais avez simplement lanc\u00e9 une requ\u00eate dans la session. <\/p>\n<p><\/p>\n<p><em>Bonjour ! Merci pour la pr\u00e9sentation ! Imaginons que nous ayons une base de donn\u00e9es qui grossit et que l'espace sur le serveur soit limit\u00e9. Y a-t-il des outils pour corriger cette situation ?<\/em> <\/p>\n<p><\/p>\n<p>L'espace sur le serveur doit id\u00e9alement \u00eatre surveill\u00e9. <\/p>\n<p><\/p>\n<p><em>Par exemple, un DBA est parti prendre un caf\u00e9, \u00e9tait en vacances, etc.<\/em><\/p>\n<p><\/p>\n<p>Lorsque le syst\u00e8me de fichiers est cr\u00e9\u00e9, un certain espace r\u00e9serv\u00e9 est au minimum \u00e9tabli, o\u00f9 les donn\u00e9es ne sont pas \u00e9crites. <\/p>\n<p><\/p>\n<p><em>Et si c'est compl\u00e8tement \u00e0 z\u00e9ro ?<\/em><\/p>\n<p><\/p>\n<p>Il est ainsi appel\u00e9 espace r\u00e9serv\u00e9, c'est-\u00e0-dire que vous pouvez le lib\u00e9rer, et selon la taille qu'il a \u00e9t\u00e9 cr\u00e9\u00e9, vous avez de l'espace libre. Par d\u00e9faut, je ne sais pas combien il y a. Dans un autre cas, vous devez fournir des disques pour avoir de la place pour effectuer une op\u00e9ration de r\u00e9cup\u00e9ration. Vous pouvez supprimer une table dont vous \u00eates s\u00fbr qu'elle ne vous est pas n\u00e9cessaire. <\/p>\n<p><\/p>\n<p><em>Il n'y a pas d'autres outils ?<\/em><\/p>\n<p><\/p>\n<p>C'est toujours un travail manuel. Et sur place, on d\u00e9termine ce qu'il est pr\u00e9f\u00e9rable de faire, car certaines donn\u00e9es sont critiques, d'autres ne le sont pas. Et cela d\u00e9pend de chaque base et de chaque application qui travaille avec elle, cela varie selon les affaires. Tout se d\u00e9cide sur place. <\/p>\n<p><\/p>\n<p><em>Merci pour la pr\u00e9sentation ! J'ai deux questions. Tout d'abord, vous avez montr\u00e9 des diapositives o\u00f9 il \u00e9tait indiqu\u00e9 que dans le cas de transactions bloqu\u00e9es, \u00e0 la fois le volume de l'espace tabulaire et la taille de l'index augmentent. Ensuite, dans la pr\u00e9sentation, il y avait de nombreux outils qui compactent les tables. Que se passe-t-il avec l'index ?<\/em><\/p>\n<p><\/p>\n<p>Ils le compressent aussi. <\/p>\n<p><\/p>\n<p><em>Mais le vacuum ne touche pas \u00e0 l'index ?<\/em><\/p>\n<p><\/p>\n<p>Certains travaillent avec l'index. Par exemple, pg_rapack, pgcompacttable. Le vacuum recr\u00e9e les index, il les touche. Le but de VACUUM FULL est de tout r\u00e9\u00e9crire, c'est-\u00e0-dire qu'il travaille avec tous. <\/p>\n<p><\/p>\n<p><em>Et ma deuxi\u00e8me question. Je n'ai pas compris pourquoi les rapports sur les r\u00e9pliques d\u00e9pendent tant de la r\u00e9plication elle-m\u00eame. Je pensais que les rapports \u00e9taient de la lecture, et la r\u00e9plication \u00e9tait de l'\u00e9criture.<\/em> <\/p>\n<p><\/p>\n<p>O\u00f9 se situe le conflit de r\u00e9plication ? Nous avons un Ma\u00eetre o\u00f9 les processus se d\u00e9roulent. Nous avons un autovacuum. Que fait en fait l'autovacuum ? Il supprime certaines anciennes lignes. Si, en m\u00eame temps, sur la r\u00e9plique, une requ\u00eate lit ces anciennes lignes, mais qu'au Ma\u00eetre, l'autovacuum a marqu\u00e9 ces lignes comme pouvant \u00eatre r\u00e9\u00e9crites, nous les avons r\u00e9\u00e9crites. Et nous avons re\u00e7u un paquet de donn\u00e9es lorsque nous devons r\u00e9\u00e9crire ces lignes n\u00e9cessaires \u00e0 la requ\u00eate sur la r\u00e9plique, le processus de r\u00e9plication attendra le timeout que vous avez configur\u00e9. Ensuite, PostgreSQL d\u00e9cidera ce qui est le plus important pour lui. Et la r\u00e9plication est plus importante pour lui que la requ\u00eate, donc il rejettera la requ\u00eate pour pouvoir appliquer ces modifications sur la r\u00e9plique. <\/p>\n<p><\/p>\n<p><em>Andr\u00e9, j'ai une question. Ces magnifiques graphiques que vous avez montr\u00e9s pendant la pr\u00e9sentation, sont-ils le r\u00e9sultat du travail d'un de vos outils ? Comment ont-ils \u00e9t\u00e9 r\u00e9alis\u00e9s ?<\/em><\/p>\n<p><\/p>\n<p>C'est un service <noindex><a rel=\"nofollow\" href=\"https:\/\/okmeter.io\/\">Okmeter<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><em>C'est un produit commercial ?<\/em><\/p>\n<p><\/p>\n<p>Oui. C'est un produit commercial.<\/p>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/501040\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0442 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u0432\u043e\u0437\u044c\u043c\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 Postgresql. \u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u044d\u0442\u043e \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u043d\u0446\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":81090,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-81089","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-10T23:42:24+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Erreurs typiques dans les applications qui entra\u00eenent du bloat dans postgresql. Andr\u00e9 Salkin | ProHoster","description":"Je vous propose de consulter le compte rendu de la pr\u00e9sentation d'Andr\u00e9 Salkin de d\u00e9but 2016 intitul\u00e9 \"Erreurs typiques dans les applications qui entra\u00eenent du bloat dans postgresql\". Dans cette pr\u00e9sentation, je vais examiner les principaux points.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql. \u0410\u043d\u0434\u0440\u0435\u0439 \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432 | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 2016 \u0433\u043e\u0434\u0430 \u0410\u043d\u0434\u0440\u0435\u044f \u0421\u0430\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u0430 &quot;\u0422\u0438\u043f\u043e\u0432\u044b\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0434\u0443\u0442 \u043a bloat \u0432 postgresql&quot; \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/tipovye-oshibki-v-prilozheniyah-kotorye-vedut-k-bloat-v-postgresql-andrej-salnikov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-10T23:42:24+00:00","article:modified_time":"2020-05-10T23:42:24+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"81089","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:05:22","updated":"2022-09-27 16:01:50","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/81089","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=81089"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/81089\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/81090"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=81089"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=81089"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=81089"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}