Vous n'êtes pas identifié(e).
Bonjour,
Je souhaiterais tracer l'exécution des différents triggers liés aux contraintes (FK surtout). Vous voyez un moyen de faire ça ?
Parce que je me retrouve dans un cas incompréhensible. Une contrainte FK est manifestement déclenchée sans raison sur un ordre delete (pg13), et j'aimerai comprendre ce qui se passe.
En résumé :
Table T1 (id1 INT PIMARY KEY);
Table T2 (id2 PRIMARY KEY, t1_id1 INT REFERENCES T1(id));
Table T3 (id3 PRIMARY KEY, t1_id1 INT REFERENCES T1(id));
Si je fais des DELETE sur T3, manifestement ça déclenche le check de la FK sur T2 !?
C'est absurde, je n'arrive pas à le reproduire en créant des tables T1,T2,T3 sur une sandbox, mais je suis à peu près sûr de mon coup parce que l'ordre DELETE sur T3 mouline toujours 96h plus tard, alors que si je crée un index sur T2(t1_id1) le DELETE s'exécute en quelques milisecondes, et se je droppe l'index, re-belote, le delete dure plus que ma patience.
J'aimerais donc pourvoir identifier tous les triggers appelés sur mon ordre DELETE, avoir une stack d'appel ce serait l'idéal. Vous voyez un moyen de faire ça ?
Alors que la récupération directe des instructions DELETE à partir d'une publication n'est pas possible, il existe des approches alternatives pour assurer le suivi et l'audit des modifications de données pour les opérations DELETE dans votre base de données. Voici deux solutions potentielles :
Utilisation de Change Data Capture (CDC) :
Oui mais justement, on cherche à se débarrasser de CDC qui pose trop de problèmes :-p
Oui les stats sont à jour.
Il n'y a pas que les stats à vérifier, il y a aussi l'état de la visibility-map.
Pour cette requête et potentiellement d'autre il semble que random_page_cost = 1.2 soit trop agressif et que ça force le planner à utiliser l'indexe, avec des accès random, à tort ...
Elle a beaucoup de colonnes ta table gaicr ?
Parce que normalement, le index-only scan est plus performant que le Seq Scan...
Pour cette requête et potentiellement d'autre il semble que random_page_cost = 1.2 soit trop agressif et que ça force le planner à utiliser l'indexe, avec des accès random, à tort ...
Elle a beaucoup de colonnes ta table gaicr ?
Parce que normalement, le index-only scan est plus performant que le Seq Scan...
Merci Hervé, on a été collègues alors
Je pense que 1.2 ou 1.3 ça ne change pas grand chose, ce qui m'étonne est que le planner ne prenne pas en compte le fait que l'index n'est pas très performant... si c'est bien ça ...
Que l'index soit performant ou pas, si les données figurent dans l'index, il est plus rapide de scanner l'index plutôt que la table...
Le truc bête, après un vacuum analyse des tables, le comportement ne change pas ?
Alors je ne vais pas vraiment (pas du tout) vous aider.
Mais quand j'étais chez Bull, en 2018 j'avais benché les serveurs x86 Bull avec SSD Nvme, et le ratio random/sequential était à 1,3 et non pas 1,2.
(et à vrai dire, j'étais surpris, je pensais que le ratio serait très proche de 1).
ça donne quoi le postgres.conf ?
Il n' a pas 36 solutions.
Soit :
1) pg_dump + pg_restore avec reconstruction des réplicats.
2) pg_upgrade cf https://docs.postgresql.fr/14/pgupgrade.html
3) dupliquer votre infrastructure avec des serveurs pg16, et mettre en place une réplication logique du master pg15 vers le master pg16.
Bonjour,
Existerait-il un moyen de récupérer les ordres DELETE qui proviennent d'une publication ?
Je voudrais tracer les suppression sur des tables d'une base de données ; mais comme la base est déjà surchargée on voudrait supprimer les triggers qui servent à ça.
L'idée est donc de mettre les tables à tracer dans une publication pour delete, mais :
- on ne peut pas faire de réplication logique vers des vues (même avec un trigger INSTEAD OF DELETE).
- Il faut absolument que la clef soit présente dans la table destination, sinon il est impossible de récuérer cette clef dans le trigger sur la table destination (j'ai tenté de surcharger le type BIGINT en redéfinissant l'opérateur "=" pour qu'il soit toujours vrai, le trigger sur DELETE se déclenche bien, mais impossible de récupérer la valeur de la clef).
Est-ce qu'il y aurait un moyen de tracker les ordres delete qui sont adressés à une souscription ?
Je pense que le problème est ailleurs.
Hello,
je rencontre cette erreur le caractère dont la séquence d'octets dans l'encodage « UTF8 » n'a pas d'équivalent dans l'encodage « WIN1252 »
C'est une erreur de la DB ou bien de l'application ? Vous avez accès au code source de l'application ?
Le QString travaille en UNICODE sur tous les O/S. Après si l'erreur est produite par l'application, il est possible que dans le code source de l'appli il soit fait appel à QString.toLocal8Bit() auquel cas, il n'y a pas grand chose à faire : Soit recompiler/exécuter l'appli sous Linux, soit remplacer les appels QString.toLocal8Bit() par des appels QString.toUtf8()
Si l'appli exporte les QString en Utf8, il faut bien sûr migrer la DB en UTF8.
Non, AMHA il ne faut pas créer un projet spécifique, il faut créer une arborescence "SGBD" spécifique dans le projet existant.
Cela permet de "tagger" les scripts de fonctions / DDL du SGBD de la même façon que le reste du projet (web services etc.) afin de gérer les compatibilités et adhérences ( Appli V1 / Base V1 ; Appli V2 / Base V2 etc.)
En général, on scripte la création des fonctions. On fait des fichiers un fichier .sql pour chaque fonction qui en comporte la définition, un script shell qui va exécuter tous ces .sql ; et tout ça est mis dans le GIT.
C'est peut-être un problème IPv4/IPv6 ...
Genre dans le pg_hba.conf il y a une autorisation de connexion pour "localhost" 127.0.0.1 (ipV4) ; mais pas pour "::1" (localhost en ipV6)
Essayez pour voir :
C:\Program Files\PostgreSQL\16\bin>psql.exe -h 127.0.0.1 -p 5433 -U postgresql
C'est peut-être un problème IPv4/IPv6 ...
Genre dans le pg_hba.conf il y a une autorisation de connexion pour "localhost" 127.0.0.1 (ipV4) ; mais pas pour "::1" (localhost en ipV6)
J'ai beaucoup à apprendre... merci pour ces précisions ! Peut-être que je veux aller trop vite...
Ça va, un CREATE DATABASE c'est un bon point de départ ;-)
Les répertoires data, ça veut dire le $PGDATA ?
Commencer par désactiver le JIT. Nous avons eu aussi du SEGV, c'était lié au jit.
Bonjour,
Auriez-vous par contre une commande qui permet de faire une sauvegarde de la base de donnée ? (pas trop envie de tout reperdre la prochaine fois que ça tombera)
Cdt
Si la base a une taille "raisonnable" (chez nous on compte < 200 Go), le plus simple est de faire un pg_dump la nuit.
Bonjour,
Il y a quelque chose qui me laisse perplexe, c'est la non utilisation de l'index BRIN sur un max() :
aegir=# select version();
version
--------------------------------------------------------------------------------------------------------------------------------------
PostgreSQL 14.9 (Ubuntu 14.9-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit
(1 row)
aegir=# create table example (id bigint);
CREATE TABLE
aegir=# create index brin_example on example using brin(id);
CREATE INDEX
aegir=# insert into example ( select generate_series(1,1000000));
INSERT 0 1000000
aegir=# select pg_size_pretty(pg_relation_size('example'));
pg_size_pretty
----------------
35 MB
(1 row)
aegir=# select pg_size_pretty(pg_relation_size('brin_example'));
pg_size_pretty
----------------
24 kB
(1 row)
aegir=# explain (analyze, verbose) select max(id) from example;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=10633.55..10633.56 rows=1 width=8) (actual time=80.798..90.351 rows=1 loops=1)
Output: max(id)
-> Gather (cost=10633.33..10633.54 rows=2 width=8) (actual time=80.732..90.344 rows=3 loops=1)
Output: (PARTIAL max(id))
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=9633.33..9633.34 rows=1 width=8) (actual time=55.675..55.676 rows=1 loops=3)
Output: PARTIAL max(id)
Worker 0: actual time=43.249..43.250 rows=1 loops=1
Worker 1: actual time=43.237..43.238 rows=1 loops=1
-> Parallel Seq Scan on public.example (cost=0.00..8591.67 rows=416667 width=8) (actual time=0.009..26.193 rows=333333 loops=3)
Output: id
Worker 0: actual time=0.011..20.722 rows=251488 loops=1
Worker 1: actual time=0.011..20.815 rows=251764 loops=1
Planning Time: 0.192 ms
Execution Time: 90.382 ms
(16 rows)
Pourquoi diable le BRIN n'est pas utilisé ? Je pensais qu'il suffisait de faire le max de toutes les bornes supérieures pour avoir le max() non ?
Évidemment, avec un index btree, l'index est bien utilisé :
aegir=# create index bt_example on example(id);
CREATE INDEX
aegir=# explain (analyze, verbose) select max(id) from example;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Result (cost=0.45..0.46 rows=1 width=8) (actual time=0.026..0.027 rows=1 loops=1)
Output: $0
InitPlan 1 (returns $0)
-> Limit (cost=0.42..0.45 rows=1 width=8) (actual time=0.024..0.025 rows=1 loops=1)
Output: example.id
-> Index Only Scan Backward using bt_example on public.example (cost=0.42..28480.42 rows=1000000 width=8) (actual time=0.023..0.024 rows=1 loops=1)
Output: example.id
Index Cond: (example.id IS NOT NULL)
Heap Fetches: 0
Planning Time: 0.165 ms
Execution Time: 0.039 ms
(11 rows)
Il y a quelque chose qui m'échappe au sujet des BRIN ?
Bonjour
Merci Mortimer et Guillaume pour ce post très intéressant, à partir de quel PCT_DEAD_LINE nous devons faire un vacuum full ?
Bonne journée
Normalement, on ne fait jamais de vacuum full.
S'il y en a besoin c'est que l'autovacuum et/ou les batches de vacuum sont mal tunés.
Bonjour,
Est-ce qu'il est possible de voir les les paramètres de session d'une requête dans pg_stat_activity
(genre voir si la requête tourne avec un SET ENABLE_SEQSCAN TO OFF;)
C'est quoi le rapport avec PostgreSQL ????
L'ajout ou non d'une clé étrangère entre les tables ne change pas ce comportement.
Je déconseille fortement l'utilisation de clés étrangères sur les tables partitionnées PostgreSQL.
D'abord parce qu'un simple ATTACH peut prendre des heures, voire des jours selon la volumétrie et rendre la table inexploitable pendant ce temps (exclusive shared lock).
Ensuite, il y a manifestement des bugs sur les FK de tables partitionnées lors des ATTACH/DETACH(*) qui AMHA ne seront pas résolus de sitôt(**).
Au boulot, en solution de contournement en attendant mieux, on fait une vérification d'intégrité avant de faire le ATTACH ; et on remplace la FK par un trigger "maison" qui fait le check d'intégrité lors des insert/update.
(*) Ref: https://www.postgresql.org/message-id/C … .gmail.com
(**) Ref : https://www.postgresql.org/message-id/C … .gmail.com