PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL :six éléments pas si faciles

PostgreSQL est livré avec un excellent ensemble de fonctionnalités, inégalé dans l'espace RDBMS open source. Il est généralement facile à apprendre et à utiliser, en particulier pour les développeurs d'applications. Cependant, certaines parties ne sont tout simplement pas faciles. Ils nécessitent du travail pour être configurés et bien exécutés, et sont également généralement essentiels à la mission.

Gestion des connexions

PostgreSQL lance un nouveau processus, appelé processus backend , pour gérer chaque connexion. Cela contraste avec les architectures modernes de gestion des connexions basées sur des boucles d'événements/pools de threads que l'on trouve dans d'autres logiciels de serveur comparables. Générer un processus complet prend plus de temps et de ressources, et se manifeste par des latences de requêtes accrues dans les applications où les connexions sont ouvertes et fermées à un rythme élevé.

Dans la plupart des déploiements, le regroupement des connexions est requis à un certain niveau. Au niveau d'une application, cela peut utiliser les fonctionnalités de votre langage de programmation/bibliothèque. Par exemple, sql/DB.SetMaxIdleConns peut être utilisé pour augmenter la réutilisation des connexions à partir d'une seule application Go.

Cependant, vous devrez souvent utiliser une solution tierce de regroupement de connexions ou d'équilibrage de charge. Les pooleurs de connexions maintiennent un pool de connexions inactives au serveur Postgres en amont, qui sont attribuées et transmises par proxy aux connexions client entrantes. Ils analysent généralement le SQL envoyé par les clients pour reconnaître les limites des transactions et les DML de modification des données afin d'implémenter des fonctionnalités telles que le regroupement des connexions au niveau des transactions et les répliques en lecture.

PgBouncer est un pooler de connexion binaire simple, léger et populaire et est souvent exécuté avec PostgreSQL dans le même système.

PgPool est plus polyvalent que PgBouncer. Il peut également faire de l'équilibrage de charge et de la réplication par exemple.

La mise en commun des connexions apporte cependant son propre ensemble de maux de tête. Premièrement, il s'agit d'une pièce mobile supplémentaire qui doit être conservée dans votre déploiement. La configuration de l'authentification est également pénible si vous avez des clients qui utilisent des informations d'identification ou des mécanismes d'authentification différents. Certaines fonctionnalités au niveau de la connexion telles que LISTEN/NOTIFY, les instructions préparées, les tables temporaires, etc. peuvent nécessiter une configuration supplémentaire ou des modifications côté client pour fonctionner.

Mises à niveau sans temps d'arrêt

La mise à niveau de PostgreSQL entre les versions mineures (13.x -> 13.y) implique l'installation du nouveau package et le redémarrage du processus serveur. Bien que le redémarrage du processus du serveur perturbe nécessairement tous les clients connectés, cela reste une demande raisonnable, étant donné que le temps d'arrêt est lié à la durée d'un redémarrage du service.

Cependant, la mise à niveau entre les versions majeures (12.x -> 13.y) est une affaire beaucoup plus importante. En règle générale, plus il y a de données, plus le processus est pénible.

La méthode la plus simple, qui ne fonctionne que pour de faibles quantités de données (disons des dizaines de Go), consiste à vider les données de l'ancienne version et à les restaurer sur un serveur de nouvelle version. Une autre option consiste à utiliser pg_upgrade, qui nécessite une danse orchestrée impliquant des binaires des deux versions de Postgres.

Dans les deux cas, les bases de données seraient indisponibles pendant un temps considérable.

Idéalement, il devrait être possible de répliquer sur un nouveau serveur de version et de promouvoir le nouveau serveur de version en tant que serveur principal. Cependant, il n'est pas possible d'effectuer une réplication en continu vers un serveur de secours avec une version majeure différente. La réplication logique, bien qu'elle semble bien adaptée à la tâche, présente certains pièges qui doivent être contournés pour assurer une réplication complète.

La plupart des solutions HA pour Postgres reposent sur la réplication en continu et, par conséquent, vous ne pouvez pas mettre à niveau les nœuds d'un cluster un par un.

L'état actuel de l'art serait d'utiliser la réplication logique, tout en contournant les limites de la réplication logique, et en impliquant éventuellement des fonctionnalités restrictives que les applications peuvent utiliser (comme les DDL) pendant la phase de mise à niveau.

Haute disponibilité

PostgreSQL est livré avec toutes les fonctionnalités de bas niveau requises pour construire une solution HA :réplication avec rétroaction, réplication en cascade, réplication synchrone, standbys, hot standbys, promotion de standby et ainsi de suite. Cependant, il ne fournit pas réellement une solution HA prête à l'emploi. Il n'y a pas de cadres ou d'outils pour surveiller la santé et basculer automatiquement vers un serveur de secours. Il n'y a pas de notion de cluster HA multi-nœuds.

Vous devrez configurer et exécuter une solution tierce pour créer des déploiements Postgres à haute disponibilité. Les favoris actuels sont pg_auto_failover et Patroni. Alors que Patroni s'appuie sur un magasin de configuration hautement disponible existant comme ZooKeeper ou etcd, pg_auto_failover peut s'en passer.

Évaluer, déployer et tester l'un d'entre eux en production demande du temps et des efforts. Les playbooks de surveillance, d'alerte et d'opérations doivent être configurés et maintenus.

Gestion des ballonnements

L'architecture MVCC de PostgreSQL signifie qu'aucune donnée n'est jamais écrasée - la modification d'une ligne entraîne uniquement l'écriture d'une nouvelle version de la ligne sur le disque. Supprimer une ligne signifie uniquement enregistrer que la ligne est invisible pour les transactions futures. Lorsqu'une version de ligne est inaccessible à partir de toute transaction en cours ou future, elle n'est plus d'aucune utilité et est appelée "bloat". Le processus de collecte de déchets de ce gonflement est appelé "vacuum".

Le gonflement est invisible pour les applications et devient uniquement le casse-tête du DBA. tablelevel pour s'assurer que les tailles de table ne deviennent pas trop grandes.

Les index sont également affectés par le ballonnement, et l'autovacuum n'aide pas ici. La suppression de lignes et la mise à jour de colonnes indexées entraînent des entrées mortes dans les index. Les charges de travail lourdes mises à jour avec des mises à jour des colonnes indexées peuvent conduire à des index en croissance constante et inefficaces. Il n'y a pas d'équivalent de vide pour les index. La seule solution est de reconstruire tout l'index en utilisant REINDEX ou d'utiliser VACUUM FULL sur la table.

Hormis une seule valeur par table (pg_stat_all_tables.n_dead_tup), Postgres n'offre rien pour estimer le gonflement d'une table, et rien du tout pour les index. Le moyen le plus pratique reste d'exécuter une requête effrayante à partir de check_postgres.

pgmetrics intègre la requête de check_postgres et peut produire une sortie au format JSON et CSV qui inclut des informations de taille et de gonflement pour toutes les tables et tous les index ; qui peuvent alimenter des outils de surveillance ou d'automatisation.

pg_repack est une alternative populaire à VACUUM FULL - il peut faire le même travail mais sans verrous. Si vous êtes obligé de faire VACUUM FULL régulièrement, c'est un outil indispensable.

zheap est le nouveau moteur de stockage pour Postgres qui est en développement depuis des années, qui promet de réduire l'encombrement grâce à des mises à jour sur place.

Gestion des plans de requête

Core PostgreSQL ne propose que deux outils rudimentaires dans cet espace :

  • pg_stat_statements extension pour l'analyse des requêtes - cela donne le total et les moyennes des temps de planification et d'exécution des requêtes, de l'utilisation du disque et de la mémoire
  • auto_explain extension, qui peut imprimer des plans d'exécution de requête dans la destination du journal Postgres

Alors que les statistiques fournies par pg_stat_statements sont juste suffisantes pour s'en sortir, en utilisant auto_explain forcer les plans dans des fichiers journaux, puis les extraire n'est pas vraiment plus qu'un piratage, en particulier par rapport aux concurrents commerciaux de Postgres, qui offrent des fonctionnalités d'historique de plan, de référencement et de gestion.

L'état actuel de l'art avec Postgres consiste à extraire les plans de recherche des fichiers journaux et à les stocker ailleurs. Mais peut-être que le problème le plus handicapant est de ne pas pouvoir associer le plan de requête aux analyses correspondantes de pg_stat_statements. La façon dont pgDash fait cela est d'analyser à la fois les textes de la requête SQL de pg_stat_statements et de la sortie auto_explain, d'ajuster la modification effectuée par pg_stat_statements et d'essayer de faire correspondre les deux. Il nécessite un analyseur SQL complet en dialecte PostgreSQL.

La définition de base, la définition de politiques pour la sélection de plans, etc. ne sont tout simplement pas possibles dans le noyau PostgreSQL actuellement.

Il existe quelques extensions qui sont essentiellement des versions améliorées de pg_stat_statements, mais les étapes supplémentaires impliquées dans l'utilisation d'une extension tierce en font un défi pour la plupart des gens, surtout s'ils utilisent un fournisseur Postgres géré.

Réglage

PostgreSQL a une pléthore d'options de réglage, à commencer par le paramètre under-configured-by-defaultshared_buffers. Certains sont faciles à comprendre et à définir, comme le nombre de travailleurs parallèles pour diverses opérations (max_worker_processes, max_parallel_* etc.). D'autres sont un peu obscurs (wal_compression, random_page_cost, etc.) mais généralement bénéfiques. Cependant, les plus frustrants sont ceux qui ont besoin d'informations quantifiables sur la charge de travail.

Par exemple, si work_mem est trop faible, les requêtes peuvent utiliser des fichiers de disque temporaires ; s'il est trop élevé et qu'il y a suffisamment de requêtes simultanées, les processus backend Postgres peuvent être tués par OOM. Alors, comment savoir sur quel numéro le définir ?

En pratique, en particulier avec les charges de travail OLTP et les charges de travail d'application Web, il est impossible de prédire quelle serait la demande maximale de mémoire pour les requêtes. Votre meilleur pari est de lui définir une valeur raisonnable, puis de surveiller les requêtes pour voir si l'une d'entre elles aurait pu bénéficier d'une valeur plus élevée de work_mem.

Et comment faites-vous cela? Vous aurez besoin de l'extension auto_explain pour enregistrer les plans d'exécution de chaque requête, extraire ceux des fichiers journaux de Postgres, examiner chaque plan de requête pour voir s'il utilise des fusions externes sur disque ou une analyse de tas bitmap avec des blocs de tas avec perte.

Pas impossible, juste difficile.