Vous n'êtes pas identifié(e).
Pages : 1
Bonjour,
je souhaite faire un formulaire de saisie de requêtes vers une base PostGreSQL avec un bouton valider et un bouton annuler.
Le bouton valider permet de lancer la requête écrite dans le champ et de l'afficher sur la page, et la requête annuler servirait à stopper la requête (exemple de requête trop longue pour l'utilisateur).
Mon problème est que lorsque je lance la requête (derrière il y a un pg_send_query), tant que je n'ai pas le résultat à l'écran (indiquant que la requête est terminée), je ne peux rien faire. Le clic sur le bouton annuler ne sert donc plus à rien vu qu'il est pris en compte une fois la requête terminée.
Question : existe-t-il une fonction PHP permettant de tuer une requête comme on le ferait avec un CTRL-C sous psql? ou une méthode pour gérer ce problème?
Bonjour,
j'ai une interface PHP que j'utilise pour faire des select sur des tables d'une base, mais les commandes "\d" ou "\dt" ne fonctionnent pas ; j'utilise la fonction pg_query pour gérer les requêtes.
Exemple : sur "\dt" la commande last_error() me renvoie le message
" ERREUR: erreur de syntaxe sur ou près de « \ » LINE 1: \dt "
TEMP n'est pas une table temporaire, je l'ai nomméé ici comme cela pour plus de simplicité ; je pense que ce sont les tests sur les 16 colonnes qui ralentissent ; mais à ce point-là je pensais pas...
Voici donc le plan d'exécution de cette requête :
explain analyze select * from TEMP
where (ch1 is null and ch2 is null and ch3 is null and ch4 is null and ch5 is not null and ch6 is not null and ch7 is null and ch8 is null and ch9 is null and ch10 is null
and ch11 is null and ch12 is null and ch13 is null and ch14 is null and ch15 is null and ch16 is null)
and (numero,dat) in (select numero,dat from TEMP group by numero,dat having (count(*)>1));
------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.00..1925561.92 rows=1 width=123) (actual time=34754.943..966952296.369 rows=7277 loops=1)
Join Filter: ((TEMP.numero = TEMP.numero) AND (TEMP.dat = TEMP.dat))
-> Seq Scan on TEMP (cost=0.00..482731.76 rows=1 width=123) (actual time=60.574..40028.057 rows=20979 loops=1)
Filter: ((ch1 IS NULL) AND (ch2 IS NULL) AND (ch3 IS NULL) AND (ch4 IS NULL) AND (ch5 IS NOT NULL) AND (ch6 IS NOT NULL) AND (ch7 IS NULL) AND (ch8 IS NULL) AND (ch9 IS NULL) AND (ch10 IS NULL) AND (ch11 IS NULL) AND (ch12 IS NULL) AND (ch13 IS NULL) AND (ch14 IS NULL) AND (ch15 IS NULL) AND (ch16 IS NULL))
-> GroupAggregate (cost=0.00..1398772.46 rows=1762308 width=14) (actual time=12.024..46079.740 rows=8326 loops=20979)
Filter: (count(*) > 1)
-> Index Scan using idx_temp on TEMP (cost=0.00..1244570.54 rows=17623076 width=14) (actual time=3.980..36479.630 rows=17623075 loops=20979)
Total runtime: 966955605.121 ms
(8 lignes)
Temps : 966955826,462 ms
Une précision :
Je sais que la sous-requête "select numero,dat from TEMP group by numero,dat having (count(*)>1)" renvoie 8149 lignes, donc si je la remplace par la sous-requête
"select numero,dat from TEMP group by numero,dat having (count(*)>1 limit 9000)", là j'ai une réponse au bout de 50,247 secondes...
Bonjour,
j'ai une table qu'on va appeler TEMP avec les champs suivants :
numero | dat | datrecu | ch1 | ... | champ16
Il y a un index sur (numero,dat) mais pas de clé primaire.
Cette table est utilisée pour servir d'intermédiaire avant de charger les données dans une table équivalente qu'on appellera T et sur laquelle j'ai une PK sur (numero,dat).
Pour résumer je dois insérer des données d'un fichier dans T mais je passe par TEMP car j'ai des doublons (numero,dat).
Parmi ces doublons, je sais que pour l'une des deux lignes j'ai les champs ch5 et ch6 NOT NULL et les autres champs NULL. Je veux supprimer dans TEMP ces lignes-là pour ne plus avoir de doublons et insérer les données dans T.
Je fais donc la requête suivante en testant avec "select *" plutôt qu'avec delete (le but étant de faire un delete des lignes obtenues) :
select * from TEMP
where (ch1 is null and ch2 is null and ch3 is null and ch4 is null and ch5 is not null and ch6 is not null and ch7 is null and ch8 is null and ch9 is null and ch10 is null
and ch11 is null and ch12 is null and ch13 is null and ch14 is null and ch15 is null and ch16 is null)
and (numero,dat) in (select numero,dat from TEMP group by numero,dat having (count(*)>1));
Au bout de 72h, je n'ai toujours rien....
J'ai donc lancé la requête suivante :
select * from (
select * from TEMP where (numero,dat) in (select numero,dat from TEMP group by numero,dat having (count(*)>1)
intersect
(select numero,dat from TEMP where (ch1 is null and ch2 is null and ch3 is null and ch4 is null and ch5 is not null and ch6 is not null
and ch7 is null and ch8 is null and ch9 is null and ch10 is null and ch11 is null and ch12 is null and ch13 is null and ch14 is null and ch15 is null and ch16 is null)))
) as toto
where (ch1 is null and ch2 is null and ch3 is null and ch4 is null and ch5 is not null and ch6 is not null
and ch7 is null and ch8 is null and ch9 is null and ch10 is null and ch11 is null and ch12 is null and ch13 is null and ch14 is null and ch15 is null and ch16 is null);
Celle-ci met 85s et j'obtiens bien ce que je veux.
Question : pourquoi la première requête pédale?
OK merci, c'est un peu plus clair maintenant.
En revanche, lorsque je lance le pg_restore pour une des grosses tables, voici le message d'erreur qui apparait :
pg_restore: [programme d'archivage (db)] erreur renvoyée par PQputCopyData : la connexion au serveur a été coupée de façon inattendue
Le serveur s'est peut-être arrêté anormalement avant ou durant le traitement de la requête.
Est-il possible que j'aie un timeout configuré quelquepart?
Merci!
Bonjour,
je recharge actuellement les tables d'une base sur un nouveau serveur, et j'ai notamment 3 énormes tables (entre 30 et 220 Go).
Pour cela, j'utilise pg_restore, et me demande si je ne peux pas l'optimiser via les paramètres lié au bgwriter.
La requête ci-dessous donne les résultats suivants :
select * from pg_stat_bgwriter;
checkpoints_timed | checkpoints_req | buffers_checkpoint | buffers_clean | maxwritten_clean | buffers_backend | buffers_backend_fsync | buffers_alloc | stats_reset
-------------------+-----------------+--------------------+---------------+------------------+-----------------+-----------------------+---------------+------------------------------
163 | 14 | 1464278 | 708767 | 3381 | 16915605 | 0 | 2443216 | 2012-04-06 23:56:32.97968+00
(quelques minutes après)
checkpoints_timed | checkpoints_req | buffers_checkpoint | buffers_clean | maxwritten_clean | buffers_backend | buffers_backend_fsync | buffers_alloc | stats_reset
-------------------+-----------------+--------------------+---------------+------------------+-----------------+-----------------------+---------------+------------------------------
163 | 14 | 1539900 | 747803 | 3381 | 17133678 | 0 | 2491555 | 2012-04-06 23:56:32.97968+00
les paramètres bgwriter_delay, bgwriter_lru_maxpages et bgwriter_lru_multiplier sont configurés par défaut.
Si j'ai bien compris, on voit que buffers_backend est bien plus élevé que buffers_checkpoint, donc que le nombre de pages placées dans le cache par postgres (via pg_restore) est bien plus élevé que le nombre de pages placées par bgwriter.
Ai-je bien analysé ces paramètres? Si oui, je suppose que bgwriter n'a pas le temps de "vider" le cache par rapport à la quantité de données qui y est stockée (par l'opération de restauration de la table qui est en cours).
Du coup est-ce qu'au final cela ne ralentit pas l'écriture des données de cette table sur disque? Et comment l'optimiser? en diminuant bgwriter_delay qui est à 200ms actuellement? en augmentant le bgwriter_lru_maxpages?
Si on pouvait m'expliquer comment analyser les valeurs des champs de la table pg_stat_bgwriter, cela me permettrait d'y voir plus clair.
Merci d'avance en tout cas.
Bonjour,
la migration me procure quelques problèmes :
- je vois que la table pg_autovacuum a disparu...comment gérer les autovacuum par table? cela m'était bien utile, car je le désactivais pour certaines de mes tables (les plus importantes) pour lesquelles je souhaitais gérer le nettoyage ;
- lorsque je lance psql, je n'arrive plus à gérer l'historique des commandes par "CTRL-R" (cela ne fonctionne plus).
Merci pour votre aide
1 - parce que le vacuum full est me semble-t-il plus efficace pour gagner de la place
2 - faire un vacuum full bloque de toute façon la base ;
3 - si je la mets en maintenance la nuit, j'éviterai que des utilisateurs n'y accèdent à ce moment-là (enfin c'est pas garanti de toute façon surtout s'ils ont des scripts qui tournent)
Bonjour,
étant donné que le temps mis pour lancer la commande "vacuum full" est prohibitif sur des tables volumineuses, je me posais une question :
au lieu de faire un vacuum full, est-ce équivalent de faire un pg_dump des données de la table, puis un truncate de la table en question, puis un pg_restore de la même table depuis le fichier créé?
Puisque la table est vide, je suppose que les index sont recréés en faisant le pg_restore?
Merci pour vos avis
J'ai testé le cas où je dois (ou veux) remonter ma base sur une autre machine.
J'ai donc effectué une sauvegarde des schemas/roles/tablespaces par pgdump_all et j'ai une sauvegarde régulière du contenu de mes tables par pg_dump -Fc (2 fois par mois) qui est assez longue, mais c'est une base volumineuse.
Par ailleurs je sauvegarde les fichiers pg_hba.conf et postgresql.conf et le fichier .pgpass.
J'ai donc installé une version de PostgreSQL sur la nouvelle machine, puis recopié les fichiers pg_hba.conf et postgresql.conf, puis lancé le serveur postgreSQL.
J'ai ensuite recréé les tablespaces (là il faut soit avoir le même répertoire cible que sur la 1ere machine, soit les faire correspondre à d'autres répertoires) : c'est un peu fastidieux s'il y a beaucoup de tablespaces, mais dans mon cas j'en ai 2.
J'ai ensuite recréé la base, puis rejouer les scripts obtenus par pgdump_all et permettant de créer les objets.
Enfin j'ai restauré les tables par pg_restore.
Dit comme ça, cela parait très fastidieux, mais ça me permet d'avoir tout ce qu'il faut pour reconstruire une base ailleurs si jamais il y a un crash du disque où la base est stockée.
J'ai quand même une question :
je sauvegarde les schémas par la commande pg_dumpall -v -U postgres -p 5433 -i -s > sauvegarde_schemas.sql
puis les roles par la commande pg_dumpall -v -U postgres -p 5433 -i -r > sauvegarde_roles.sql
Mais lorsque je rejoue le fichier sauvegarde_schemas.sql, il me crée les roles, et je n'ai pas besoin de relancer le fichier sauvegarde_roles.sql? C'est normal?
Ma base fait 400 Go, elle grossit régulièrement mais pas trop en volume, disons dans les 30 Mo par jour.
Vous me conseillez d'utiliser pg_start_backup() mais la question est "combien de temps cela prend-il?" et quel volume.
Si je dois compter le volume équivalent, je ne l'ai pas...c'est pour cela que les sauvegardes des tables par pg_dump et par ailleurs de la structure par pgdump_all me convenaient bien.
Nous avons par ailleurs un logiciel qui tourne sur le serveur et qui fait une sauvegarde du système de fichiers, mais je ne suis pas sûr que si j'ai un crash à l'instant T et que la sauvegarde date de T-3h je puisse remonter la base même en recopiant tout les systèmes de fichiers concernés.
Bonjour,
je suis en train de me poser (enfin) les bonnes questions concernant la sauvegarde de ma base.
Actuellement, je sauvegarde les fichiers de config (postgreql.conf, etc...) et par ailleurs j'utilise pg_dump pour sauvegarder mes tables. Tous les scripts que j'ai pour recréer la base depuis le début peuvent me servir en cas de problème, mais sont-ils toujours à jour...
Je compte donc envisager le problème sous l'angle suivant :
- pouvoir restaurer une table si jamais elle disparait (un drop malheureux) => pour cela il faut que je sauvegarde les tables uniquement ;
- pouvoir restaurer la base si j'ai un crash : pour cela il faut que je sauvegarde les schémas et les rôles, mais sans les données.
J'ai vu que je pouvais utiliser pg_dumpall, mais si je fais 1 sauvegarde pour les tablespaces, une pour les schémas, et une pour les rôles, est-ce que ça parait cohérent?
Ce que j'ai du mal à comprendre, c'est si je dois repartir de 0 pour recréer la base, est-ce que je dois faire comme ci-dessous :
- je recrée éventuellement une instance avec initdb ;
- je récupère les anciens fichiers de configuration comme pg_hba.conf et postgresql.conf ;
- je relance le script qui me recrée les tablespaces ;
- je relance la création de la base par createdb mabase -D montablespace ;
- je relance le script qui crée les schémas ;
- je relance le script qui crée les rôles ;
- je recrée les tables que j'ai sauvegardées par pg_dump ;
Merci d'avance pour votre aide
Si je configure statement_timeout dans postgresql.conf, cela va affecter toutes les sessions ; d'ailleurs il est déconseillé de le faire dans la doc Postgresql en ligne.
Est-ce que je peux créer un trigger sur ouverture de session afin de configurer cette variable pour un seul utilisateur ?
Effectivement, je confirme qu'il y avait bien un produit cartésien (requête sur 4 fois la même table) suivi d'un ORDER BY ; je vais donc faire un système de fichiers dédié ; ceci dit, je ne peux pas empêcher certains utilisateurs de faire ce genre de requête...
Que va-t-il se passer lorsque ce système de fichiers dédié sera saturé?
Merci
Bonjour,
je gère une base volumineuse (300 Go) pour laquelle j'ai eu une requête assez importante avec tri par ORDER BY, requête qui m'a fait planter le SGBD après avoir saturé l'espace disque où est situé le répertoire pgsql_tmp.
Effectivement plusieurs dizaines de Go ont été écrits sous ce répertoire jusqu'à saturation. Lorsque j'ai relancé la base, tout a été effacé et c'est reparti. Mais la requête a été relancée plus tard et même souci.
Question : comment gérer au mieux pour que cela ne se reproduise plus?
Pour information, la variable work_mem est à 50 Mo, mais je ne compte pas l'augmenter.
Sur quoi peut-on jouer pour éviter ces désagréments?
Merci d'avance
Y.
Pages : 1