web-dev-qa-db-fra.com

Stratégies PostgreSQL pour traiter le remplissage du disque

J'utilise PostgreSQL (8.4) pour stocker des données produites par une application faisant des insertions fréquentes (dans la structure de table décrite ci-dessous).

La base de données continue de croître avec le temps et, étant donné que les données les plus récentes sont plus pertinentes que les données plus anciennes (dans cette application particulière), la suppression des lignes plus anciennes est une solution raisonnable (soit basée sur le bas id ou plus âgé input_datetime, qui est plus ou moins identique).

Pour prévenir les problèmes liés à cette base de données (la seule base de données exécutée sur ce serveur) de l'affectation du reste du système, j'ai placé le répertoire de données PostgreSQL sur sa propre partition (EXT3, sur un système Linux). Néanmoins, lorsque cette partition devient pleine, cela provoque un certain nombre de problèmes.

Je pense que la suppression régulière des données plus anciennes (E.G. DELETE FROM data_group WHERE id <= ... via un travail de cron) pour y faire face.

Premièrement, ma compréhension de VACUUM (comme effectuée par aspiration automatique, qui est activée) est que, bien que cela ne redonne pas nécessairement l'espace disque au système d'exploitation (comme VACUUM FULL), cela permet toujours à certains Les nouvelles données à insérer dans l'espace disque déjà utilisé (c'est-à-dire que le DELETEs n'affecte pas nécessairement la taille du fichier, mais ils sont toujours libres d'espace dans les propres structures de données de PostgreSQL). Est-ce correct? (J'ai remarqué VACUUM FULL a causé quelques problèmes avec l'application elle-même, probablement en raison des serrures qu'il utilise.)

Si tel est le cas, il apparaît également que SELECT pg_database_size('my_database') reflète la taille utilisée sur le disque, ce qui ne reflète pas nécessairement ce qui est disponible pour d'autres inserts. Y a-t-il une autre façon d'estimer la quantité d'espace disponible pour de nouveaux inserts?

De plus, quand il est trop tard et que la partition est remplie à 100%, l'exécution de cette déclaration DELETE provoque cette erreur et bloque le service PostgreSQL:

Panic: Impossible d'écrire au fichier "pg_xlog/xlogtemp.7810": pas d'espace restant sur le périphérique

L'arrêt du démon postgreSQL est bien sûr un problème majeur (et il n'y a pas d'autre disque pour déplacer le cluster sur cette machine).

Existe-t-il des stratégies générales pour empêcher ce type de problème de se produire (sachant que l'espace disque est contraint dans une partition donnée, mais qu'il peut être acceptable de supprimer des données plus anciennes)? J'aimerais automatiser autant que possible cela que possible, sans root ou postgres (ou postgreSQL admin) intervention.


CREATE TABLE data_group (
    id SERIAL PRIMARY KEY,
    name TEXT,
    input_datetime TIMESTAMPTZ
);

CREATE TABLE data_item (
    id SERIAL PRIMARY KEY,
    group_id INTEGER NOT NULL REFERENCES data_group(id) ON DELETE CASCADE ON UPDATE CASCADE,
    position INTEGER NOT NULL,
    data BYTEA
);
6
Bruno

D'une part, vous pouvez regarder ne des Mes réponses précédentes pour voir comment vous pouvez garder une taille de table plus ou moins stable. Vous trouverez une solution avec des déclencheurs - bien sûr, cela peut également être résolu avec un travail de cron. Dans ce dernier cas, je vérifierais d'abord si le numéro de la ligne a dépassé une certaine limite et la suppression des lignes les plus anciennes ou déposez une partition.

D'autre part, comme vous l'avez déjà remarqué, il faut prendre soin de l'espace disque où pg_xlog est. Quand il est plein, il n'est pas si facile à récupérer ... mais vérifiez vos paramètres de base de données, vous pouvez avoir une estimation équitable quelle quantité d'espace dont vous avez besoin:

Il y aura toujours au moins un fichier de segment wal et ne sera normalement pas plus que (2 + checkpoint_completion_target) * checkpoint_segments + 1 ou alors checkpoint_segments + wal_keep_segments + 1 des dossiers. Chaque fichier de segment est normalement de 16 Mo (bien que cette taille puisse être modifiée lors de la construction du serveur). Vous pouvez utiliser ceci pour estimer les exigences spatiales pour WALL. Ordinairement, lorsque les anciens fichiers de segment de journal ne sont plus nécessaires, ils sont recyclés (renommé pour devenir les prochains segments de la séquence numérotée). Si, en raison d'un sommet à court terme de taux de sortie du journal, il y a plus que 3 * checkpoint_segments + 1 Fichiers de segment, les fichiers de segments inutiles seront supprimés au lieu de recycler jusqu'à ce que le système soit revenu sous cette limite.

Si vous n'avez pas de réplication mis en place, le maximum est 3 * checkpoint_segments + 1 (fois 16 Mo). Une configuration typique de la réplication nécessitera quelque chose de moins de 10 Go pour pg_xlog, Je pense.

4
dezso