IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes PostgreSQL Discussion :

Disque plein !


Sujet :

Requêtes PostgreSQL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut Disque plein !
    Bonjour,

    J'ai écrit un bout de logiciel pour insérer des lignes dans une table (j'utilise la commande "copy from stdin"). La table est définie comme ci dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    CREATE TABLE dataflow
    (
        num_id_cycle 	int4,
        ipproto 		int2,
        ipLocal 		inet NOT NULL,
        direction 		char,
        ipExtern  		inet NOT NULL,
        portLocal 		int4,
        portExtern	 	int4,
        tcpFlags 		smallint,
        incTraffic 		int8,
        outTraffic 		int8,
        incPkts 		int8,
        outPkts 	  	int8,
        firstTimestamp 	TIMESTAMP WITHOUT TIME ZONE,
        lastTimestamp 	TIMESTAMP WITHOUT TIME ZONE,
        ipoutsideCountryId 	int2,
     
        PRIMARY KEY (num_id_cycle,ipLocal,ipExtern,ipproto,portLocal,portExtern),
        constraint fk_num_cycle FOREIGN KEY (num_id_cycle) REFERENCES collect_cycle (num_id_cycle)
    );
    Mon programme insère plusieurs milliers de ligne chaque 1/4 d'heure; et toutes les 24 heures, il fait le ménage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    DELETE FROM dataflow WHERE num_id_cycle < xy; 
    -- where xy is the num_id_cycle of 24hours old data;
     
    VACUUM ANALYZE dataflow
    Ainsi, il y a toujours moins de 24heures de données dans la base de données.
    Cependant, le disque se remplit, et régulièrement, au bout de 2 ou 3 mois, le serveur postgresql se plante car le disque est plein !

    Pourquoi est-ce que le taille sur le disque augmente (alors que le nombre d'entrée dans la table n'augmente pas) ?

    Merci d'avance pour votre aide et vos conseils. Amicalement
    Thierry

  2. #2
    Membre confirmé Avatar de juvamine
    Profil pro
    Chef de projet MOA
    Inscrit en
    Mai 2004
    Messages
    414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet MOA
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Mai 2004
    Messages : 414
    Points : 502
    Points
    502
    Par défaut
    n'y a t il pas un journal de transactions (comme dans sqlserver) qui gonfle régulièrement ?
    Juvamine

  3. #3
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Le journal de transactions est recyclé automatiquement sauf si archive_mode est à on.
    Il est possible que ce soit l'index ou les index qui grossissent.
    Tu peux faire un REINDEX TABLE dataflow après le VACUUM pour éviter ça.

    Sinon suivre l'évolution des tailles avec les fonctions pg_database_size(), pg_relation_size() et pg_total_relation_size()

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Salut,
    J'ai suivi vos conseils, merci... mais j'ai un peu de mal à interpréter le résultat !
    Il efface 49619262 raws... ce qui fait augmenter le pg_database_size, pg_relation_size, et pg_total_relation_size !!! Il y a un bug, ou quelqu'un peut m'expliquer ?! Merci.
    Amicalement
    T.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    db=> DELETE FROM dataflow WHERE num_id_cycle < (SELECT MIN(num_id_cycle) FROM collect_cycle WHERE date_trunc('hour',date) = date_trunc('hour','now'::timestamp - interval '1 days'));
    select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
    DELETE 49619262
    db=> select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
     pg_database_size | pg_relation_size | pg_total_relation_size 
    ------------------+------------------+------------------------
          22989305616 |      14742257664 |            22485639168
    (1 row)
     
    db=> VACUUM ANALYZE dataflow;
    VACUUM
    db=> select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
     pg_database_size | pg_relation_size | pg_total_relation_size 
    ------------------+------------------+------------------------
          23433369360 |      15027437568 |            22922969088
    (1 row)

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Il faut faire le REINDEX

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Effectivement... (voir ci dessous)
    Mais c'est pas terrible. La logique aurait voulu que ça fasse partie du VACUUM !
    Et pour moi, c'est un vrai problème: pour faire un REINDEX, la table doit rester verrouillée en lecture/écriture pendant presque 1/2 heure(!!), or je dois insérer des données tous les 1/4 h...

    db=> select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
     pg_database_size | pg_relation_size | pg_total_relation_size 
    ------------------+------------------+------------------------
          24113665808 |      15027437568 |            23482236928
    (1 row)
    
    db=> REINDEX TABLE dataflow;
    select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
    
    REINDEX
    znets=> select pg_database_size(16385), pg_relation_size(16394), pg_total_relation_size(16394);
     pg_database_size | pg_relation_size | pg_total_relation_size 
    ------------------+------------------+------------------------
          20088559376 |      15027437568 |            19457130496
    (1 row)

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Comme la clef primaire porte sur 6 champs, l'index doit être en plus assez coûteux.
    Sur un problème de ce genre, personnellement j'évaluerais deux pistes:
    1) partitionnement avec suppression des partitions obsolètes. Dans ce cas plus besoin ni de delete ni de vacuum ni de reindex. La difficulté est de trouver la bonne clef de partitionnement mais ton num_id_cycle a l'air d'un bon candidat.
    2) si impossible de partitionner, voir s'il est possible de se passer de l'index.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Merci pour ta réponse.

    1) Non, un partitionnement des données n'est plus envisageable à ce stade du projet (et c'est très contraignant...)
    2) Comment ? Je supprime la clé primaire de la table ?

    ... lors de la conception, j'ai pas imaginé une seconde que le VACUUM ne faisait pas complètement le ménage et qu'il allait falloir que je lance des REINDEX sur les index généré d'après la clé publique des tables !!
    Si je vire la clé primaire et que je crée quelques index, chacun sur 1 seul champ... le REINDEX sera plus rapide ?

    Merci.

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Le ménage complet se fait VACUUM FULL + REINDEX mais c'est une opération très coûteuse dès qu'il y a un volume important. VACUUM seul repère simplement les trous utilisables plus tard mais ne les élimine pas sauf s'ils sont à la fin de la table.

    Si la clef primaire n'est pas indispensable, alors autant la supprimer.
    Ensuite s'il y a d'autres index nécessaires, voir s'il peuvent être créés avec le type hash au lieu de btree (dans ce cas chaque index doit être mono-colonne). D'après la doc c'est plutôt l'index btree qui est sujet à la dilatation en taille.

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Le concept du VACUUM est très bien et très clair...
    Mais le REINDEX c'est du grand n'importe quoi ! Ca sert à quoi de gérer un index de manière transparente, s'il n'est pas mis à jour lors des DELETE ??? Encore une chance qu'il faille pas faire un REINDEX qui bloque la table 1/4h après chaque INSERT...
    Enfin bref, je vais essayer de bricoler un truc du coup... Merci pour ton aide

  11. #11
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    J'ai déjà aussi rencontré ce genre de problème
    Le hic sous Postgresql c'est que quand on fait un "create index" ou "reindex" ça locke la table
    Pour le partitionnement n'en parlons même pas c'est une usine à gaz avec des contraintes/triggers partout
    N'y a-t-il aucun créneau horaire pendant lequel la table n'est pas utilisée pour pouvoir faire cette opération ?
    Si non, tu peux éventuellement essayer d'augmenter le paramètre maintenance_work_mem pour accélérer le reindex ou le create index si tu le droppes à chaque fois
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  12. #12
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    A noter que pour CREATE INDEX, il y a une option CONCURRENTLY qui fait que la table n'est pas verrouillée pendant l'opération.

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    D'après la documentation, il est possible de réindexer sans verrouiller les tables : http://www.postgresql.org/docs/9.0/s...X-CONCURRENTLY

    Par contre ce n'est pas une option de la commande REINDEX et il faut supprimer et recréer l'index pour bénéficier de l'option.

    edit : Cramé de 10mn . Ca m'apprendra à laisser une réponse non validée pendant un quart d'heure .

  14. #14
    Membre expérimenté Avatar de scheu
    Inscrit en
    Juin 2007
    Messages
    1 506
    Détails du profil
    Informations forums :
    Inscription : Juin 2007
    Messages : 1 506
    Points : 1 734
    Points
    1 734
    Par défaut
    Je ne connaissais pas l'option CONCURRENTLY, merci à vous deux pour l'info
    Ça oblige à faire un drop/create des index et PK mais bon c'est mieux que rien ...
    La théorie, c'est quand on sait tout mais que rien ne fonctionne.
    La pratique, c'est quand tout fonctionne mais que personne ne sait pourquoi.
    Ici, nous avons réuni théorie et pratique : Rien ne fonctionne ... et personne ne sait pourquoi !

    Réplication de base avec Postgresql : http://scheu.developpez.com/tutoriel.../log-shipping/

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2011
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Septembre 2011
    Messages : 9
    Points : 5
    Points
    5
    Par défaut
    Salut,
    Oui, finalement, j'ai réglé le problème en faisant des drops index et des create index concurrently. C'est plus rapide qu'un reindex, et ça évite de locker la table.
    Merci pour votre aide et vos conseils. Amicalement
    Thierry

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Squelette d'un disque plein
    Par Minouchka dans le forum Traitement d'images
    Réponses: 6
    Dernier message: 08/05/2009, 22h45
  2. Espace Disque plein
    Par hamer66 dans le forum AS/400
    Réponses: 3
    Dernier message: 07/07/2007, 11h39
  3. [Oracle 9i] Disque plein :'(
    Par jeoff dans le forum Oracle
    Réponses: 2
    Dernier message: 14/11/2006, 14h00
  4. Serveur disque plein
    Par julien.63 dans le forum Administration système
    Réponses: 6
    Dernier message: 29/10/2006, 17h34
  5. [Oracle10g Linux] Disque plein
    Par leng dans le forum Oracle
    Réponses: 1
    Dernier message: 17/11/2005, 10h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo