Vous n'êtes pas identifié(e).
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
Merci pour vos réponses:
@herve:select n_live_tup,n_dead_tup from pg_stat_user_tables where relname like 'table_part_%'; relname |n_live_tup|n_dead_tup| ------------+----------+----------+ table_part_1| 0| 0| table_part_2| 0| 0| table_part_3| 0| 0|
Si je comprends bien cela signifie que toutes les partitions sont a priori équivalentes c'est bien cela ? (j'ai rentré la même quantité de données dans chacune: 10k lignes), ce qui explique les plans d'execution.
Oui, mais à ce que je comprends, il n'y a jamais eu de VACUUM ANALYZE effectué (j'ai pas vérifié, mais je pense que cela devrait figurer dans les stats des partitions), par conséquent un scan de l'index entraînera forcément une lecture de la page de données pointée par les feuilles de l'index, donc autant effactuer directement un Seq Scan sur les pages de données.
Effectuez un VACUUM ANALYZE sur la table, et refaites un EXPLAIN ANALYZE histoire de voir si le plan d'exécution change.
Bonjour,
Merci pour la réponse et désolé pour le post en anglais.
Quant au problème j'ai essayé d'ajouter une foreign key mais cela ne change rien.
Ce que je ne comprends pas c'est pourquoi la première requête a besoin de scan toutes les partitions alors que la clé de partition est fournie implicitement via la jointure, j'aimerais savoir comment mieux écrire mes requêtes pour éviter ce comportement.
Bonjour.
Vous avez dans votre table_ref des valeurs qui 'pointent' sur les 3 partitions, donc de toute façon, il devra aller chercher dans les 3 partitions.
ça vous donne quoi :
select pg_relation_size(relname::text) from pg_stat_user_tables where relname like 'table_part_%';
et
select n_live_tup,n_dead_tup from pg_stat_user_tables where relname like 'table_part_%';
??
Pour ceux que cela intéresse, un backup pgbackrest "full" qui prend ~ 14 heures, est restauré en en peu moins de 10 heures.
$ cat /etc/mke2fs.conf
[defaults]
base_features = sparse_super,filetype,resize_inode,dir_index,ext_attr
default_mntopts = acl,user_xattr
enable_periodic_fsck = 0
blocksize = 4096
inode_size = 256
inode_ratio = 16384
...
Indique que par défaut, un boc d'inodes de 256 octets sera écrit par mkfs pour 16384 octets formattés.
Le nombre d'inodes peut être spécifié directement avec l'option -N lors du mkfs. (Ne pas oublier qu'un fichier, selon sa taille, peut prendre plusieurs inodes).
Le nombre d'inodes présents, utilisés et libres peut être vérifié avec "df -i".
Euh, je ne connais pas vraiment de limite au nombre de fichiers.
Il y a une limite au nombre de fichiers ouverts simultanément oui.
Il y a aussi une limite au nombre de fichiers liée au nombre d'inodes qui a été défini lors de la création du filesystem.
Pour vos problèmes avec "tar" je suspecte que le problème n'est pas le nombre de fichiers, mais l'utilisation d'un jocker ("*") dans un répertoire qui a genre plusieurs milliers de fichiers, qui lorsqu'il est interprété remplit le buffer de noms de fichiers.
Bonjour,
Quels sont les codes retour lors d'erreurs pouvant survenir lors d'un vacuum ?
L'objectif est de superviser cette tâche.Merci
Cordialement
Dba95
Vous pouvez superviser les timestamps last_vacuum et last_analyze de la table pg_stat_user_tables pour vérifier la date où le VACUUM/ANALYZE s'est terminé pour la dernière fois
Je pense comprendre ce que tu veux faire avec le where mais je ne vois pas comment ça peut fonctionner.
Pour tester, j'ai utilisé une requête plus simple qui est censée afficher pour chaque individu la date de première observation et la dernière ce qui donne:SELECT ind.name as "Name" , S1.date as "First observation" , S2.date as "Last observation" FROM individuals as ind inner join sightings as S1 on S1.individual_ID = ind.individual_ID left join sightings as S2 on S2.individual_ID = ind.individual_ID WHERE NOT EXISTS (SELECT 1 FROM sightings as S1b WHERE S1.date > S1b.date and S1.individual_ID = S1b.individual_ID ) order by ind.name , S1.date , S2.date ;
Mais ça affiche X lignes par individu avec la date de première observation et toutes les autres dates d'observation
Et si je mets S2 à la place de S1b ça ne change rien, en intégrant le WHERE dans le inner join S2 non plus, pareil si je ne fais aucun inner join.
J'ai même essayé de remplacer 1 par S2.date ou s1b.date mais ça ne change rien
Non, il ne faut pas joindre à gauche sur S2.
Tu fais ta jointure simple sur S1 et S2 :
SELECT ind.name as "Name"
, S1.date as "First observation"
, S2.date as "Last observation"
FROM individuals as ind, sightings S1, sightings S2
WHERE
(
S1.individual_ID = ind.individual_ID
AND S2.individual_ID = ind.individual_ID
AND S2.individual_ID = S1.individual_ID -- ajout de la transitivité au cas où
)
AND NOT EXISTS
(SELECT 1 FROM sightings as S1b WHERE S1.date > S1b.date and S1.individual_ID = S1b.individual_ID )
AND NOT EXISTS
(SELECT 1 FROM sightings as S2b WHERE S2.date < S2b.date and S1.individual_ID = S1b.individual_ID )
order by ind.name
, S1.date
, S2.date
;
Sauf erreur de ma part cela devrait donner ce que tu recherches.
En règle générale, il faut éviter le "WHERE t1.sequence = (SELECT max(t2.squence) FROM t2 WHERE t1.id = t2.id)" parce que le max() est volatile, donc recalculé à chaque fois. Donc si ton ID possède 100 séquences, tu as un produit cartésien 100x100 = 10.000
Avec un "NOT EXISTS (SELECT 1 FROM t2 WHERE t1.sequence > t2.sequence and t1.id = t2.id )" chaque mauvais candidat sera éliminé dès qu'il sera trouvé une ligne avec une séquence supérieure. Donc, si tu as beaucoup de chance tu vas avoir un 100 + 99*1 = 199 ; et si tu es vraiment poissard tu vas avoir un 100x100=10.000.
Donc dans le pire des cas, tu te retrouves dans le cas du max() qui lui est de toute façon le pire des cas de manière constante.
"
Bonjour.
J'espère que je suis dans la bonne discussion
Après avoir galéré avec la migration de MariaDB vers POstGreSQL, j'ai voulu reprendre une requête créée en SQL approximatif MariaDB mais bien évidemment ça ne fonctionne pas.
C'est une requête qui doit permettre de récupérer les données de plusieurs tables à deux dates différentes sur une même ligne.SELECT ind.name as "Name" , ind.sex as "Sex" , ind.is_dead as "Dead" , S1.troop_ID as "Troop" , min(S1.date) as "First observation" , S1.present as "Present" , max(S2.date) as "Last observation" , S2.present as "Present" FROM individuals as ind inner join sightings as S1 on S1.individual_ID = ind.individual_ID left join sightings as S2 on S2.individual_ID = ind.individual_ID and S2.date> S1.date group by ind.name , ind.sex , S1.troop_id order by ind.name , S1.date , S2.date ;
Y a t'il un moyen de contourner le problème des champs qui ne sont pas dans le group by ?
Merci d'avance
Au lieu de faire du min() max(), faire un WERE NOT EXISTS (SELECT 1 FROM sightings as S1b WHERE S1.date > S1b.date and S1.individual_ID = S1b.individual_ID )
Bonjour,
Selon votre expérience, lorsqu'on a une sauvegarde pgBackRest ; quel temps de restauration faut-il prévoir pour la restauration en cas de sinistre ?
AMHA ; si la sauvegarde "full" a pris 1h ; il faut prévoir 1h pour la restauration initiale.
Mais pour rejouer les WAL ? Est-ce que ça prend plus de temps que la somme des temps nécessaire pour les archiver, ou bien c'est le même ordre ?
Ah je ne connaissais pas, c'est très intéressant ! Merci.
Ok, merci beaucoup de me signaler cette histoire de saturation de messages, vu que c'est une base à très haut TP (et des tables à plus de 1G t-uples), c'est une option qui ne peut pas être tout à fait exclue, donc faire gaffe.
Encore que... que ce soit toujours ce message là qui soit ignoré pendant un an... Mais comme disait Murphy, s'il y a une possibilité que les choses aillent mal, elles iront mal un jour.
Merci pour l'info.
Bonjour,
J'ai un index pour lequel pg_stat_all_indexes.idx_scan est égal à zéro.
pg_stat_database.stats_reset de la db me donne un timestamp vieux de quasiment un an.
Suis-je _CERTAIN_ que cet index n'a jamais été utilisé depuis un an ? Ou bien est-il possible que les stats de cet index aient été réinitialisées sans que cela ne modifie pg_stat_database.stats_reset ?
C'est du PG 11.
Merci d'avance.
edit : ( en partant du principe que "track_counts" est toujours resté à "on" )
Cette variable doit contenir le nom complet d'un fichier .pgpass
AMHA il faudrait aussi vérifier l'OS qui est utilisé (Linux, AIX (oui ça existe encore...) etc. ) ainsi que l'architecture (x86 etc.) non ?
Je suis incapable d'expliquer le pourquoi du comment, mais je me souviens qu'il y a quelques années, chez BULL, des bench donnaient sous architecture POWER des comportements radicalement différents selon l'O/S et le dynamic_shared_memory_type...
Merci beaucoup.
Bonjour,
Nous avons nos systèmes de production avec du archive-log via pgbackrest sur un serveur _distant_
Il nous arrive d'avoir un archiver en erreur ; donc accumulation de WALs. Pour le moment, la procédure est de réinitialiser le stanza.
Manifestement, le serveur distant pgbackrest dit que le le WAL a déjà été enregistré avec le même checksum. Est-ce que quelqu'un a été déjà confronté à ce genre de problème ? Ça viendrait de quoi ?
Ps: je n'ai pas trouver comment passer en Résolu
Ce n'est pas l'habitude ici.
Pas besoin, les problèmes sont toujours résolus en quelques jours ;-)