Un de mes serveurs PostgreSQL héberge plusieurs (1-3) bases de données qui reçoivent un flux constant de données. Les données ne sont pas particulièrement structurées, elles correspondent à l'heure actuelle et à une variété de données observées pour cet instant particulier. Le débit de données est assez élevé; cela équivaut à environ un gigaoctet par jour pour une base de données, environ un dixième de cela pour une autre. Je ne m'attends pas à ce que ce taux augmente. La performance de lecture est une priorité beaucoup plus faible et est actuellement acceptable.
Dans les journaux, j'ai ce message:
LOG: checkpoints are occurring too frequently (15 seconds apart)
HINT: Consider increasing the configuration parameter "checkpoint_segments".
Cette valeur est actuellement définie sur 16, avec l'aimable autorisation de pgtune
.
Quels sont les paramètres à prendre en compte pour améliorer les performances d'écriture? Je préférerais garder autant de sécurité que possible. Compte tenu du volume de données entrant, je pouvais accepter de perdre certaines données récentes en cas d'échec tant que la majeure partie des données étaient intactes.
Edit: j'utilise PostgreSQL 9.0 pour l'instant, mais je prévois de passer à 9.1. Je ne publie pas les détails du matériel car bien que je reconnaisse leur importance, je devrai finalement faire cette optimisation sur plusieurs machines avec du matériel très divers. Si le matériel est essentiel à la réponse, veuillez me donner les informations générales afin que je puisse appliquer la réponse aux machines avec différentes configurations matérielles.
1 gigaoctet par jour n'est pas une charge d'écriture aussi élevée. Répartis tout au long de la journée, cela représente environ 50 kilo-octets par seconde. Une clé USB lente pourrait gérer cela. Je suppose que c'est plus éclatant cependant. Comme le suggère a_horse_with_no_name, augmentez les segments de point de contrôle. 100 ou plus n'est pas hors de l'ordinaire.
Augmentez ensuite votre checkpoint_timeout
à 1 heure, et essayez d'augmenter votre checkpoint_completion_target
à quelque chose de plus proche de 1.0 (100%). La cible d'achèvement indique à PostgreSQL comment agressivement écrire en arrière-plan afin qu'il soit terminé à x% avant d'exécuter un point de contrôle, ce qui force toutes les données à être écrites à la fois à partir du WAL et ralentira le système à une analyse pendant qu'il se produit.
La raison pour laquelle vous ne le définissez généralement pas à 100% est qu'il est assez courant d'écrire plusieurs fois dans le même bloc, et en retardant les écritures WAL dans le magasin principal, vous empêchez le même bloc d'être écrit deux fois sans raison.
S'il est peu probable que vous écriviez dans le même bloc plus d'une fois avant que votre délai d'expiration ne se produise, c'est-à-dire que tout ce que vous faites est d'insérer, puis de le définir assez haut est logique de le porter à 0,9 ou plus. Le pire qui puisse arriver, c'est que vous écrirez un peu plus souvent que vous n'auriez pu le faire autrement, mais l'impact des points de contrôle sera considérablement réduit.
Dans un système très "lourd en écriture", vous êtes susceptible d'être limité par le taux d'écriture de WAL pendant une activité de pointe.
Si vous pouvez vraiment "accepter de perdre des données récentes en cas d'échec", vous pouvez désactiver validation synchrone qui:
peut être une alternative utile lorsque les performances sont plus importantes que la certitude exacte de la durabilité d'une transaction
Si vous êtes en mesure de changer votre matériel, vous pouvez envisager l'une de ces options pour optimiser les écritures:
--Éditer
Sur la base de votre commentaire sur @ l'excellente réponse de Scott : "Le volume d'écriture est en fait presque complètement uniforme", et le débit de données implicite de "50 Ko par seconde", je doute que vous deviez faire quoi que ce soit qui risque les données perte. Il serait peut-être utile de savoir quels sont certains de vos autres paramètres de configuration.
Vous pouvez également vérifier la fréquence/taille de vos validations: j'ai rencontré récemment un problème dans lequel j'essayais de mettre à jour> 1 million d'enregistrements en une seule transaction. J'ai reçu des messages de journal similaires à ceux décrits par OP, mais la transaction n'a pas pu se terminer même après plusieurs heures. Lorsque j'ai fractionné l'écriture en plusieurs transactions plus petites (environ 10 000 enregistrements), le temps total requis est tombé à environ 15 minutes.
Ce que je pense est arrivé, c'est que Postgres a passé tellement de temps à écrire les journaux que checkpoint_timeout s'est écoulé avant qu'il ne puisse faire des progrès substantiels en sauvegardant les enregistrements. Je ne sais pas si cette explication tient. Je reçois toujours les avertissements, mais toutes les écritures sont finalement traitées. Cependant, j'avais besoin (et trouvé) une solution de contournement programmatique plutôt qu'une solution nécessitant une reconfiguration de la base de données.
Voir aussi http://www.postgresql.org/docs/9.3/static/wal-configuration.html