Je rédige ce message concernant une erreur de “chunk manquant” dans une table postgres qui échouait mes sauvegardes quotidiennes. J’ai réussi à résoudre le problème et je souhaite exposer la méthode que j’ai utilisée au cas où elle pourrait être utile à quelqu’un d’autre rencontrant ce problème. Ce n’est en aucun cas un guide ou des instructions professionnelles sur la manière de résoudre correctement les erreurs de “chunk manquant” de postgres car je ne suis pas un expert et je l’ai fait sans beaucoup de connaissances, mais cela a fonctionné à la fin.
L’erreur que j’ai reçue pendant les sauvegardes :
pg_dump: error: Dumping the contents of table "stylesheet_cache" failed: PQgetResult() failed.
pg_dump: error: Error message from server: ERROR: missing chunk number 0 for toast value 1903804 in pg_toast_22663
pg_dump: error: The command was: COPY public.stylesheet_cache (id, target, digest, content, created_at, updated_at, theme_id, source_map) TO stdout;
Le problème se situait donc dans la table stylesheet_cache, l’erreur : ERROR: missing chunk number 0 for toast value 1903804 in pg_toast_22663.
J’utilise Discourse sous Docker, voici donc ce que j’ai fait :
ssh into the server
cd /path/to/discourse
./launcher rebuild app
su postgres -c "psql discourse"
Une fois dans postgres, j’ai essayé de REINDEX la table en espérant que cela résoudrait le problème.
discourse=# select reltoastrelid::regclass from pg_class where relname = 'stylesheet_cache';
reltoastrelid
-------------------------
pg_toast.pg_toast_18396
(1 row)
REINDEX table stylesheet_cache;
REINDEX table pg_toast.pg_toast_18396;
VACUUM analyze stylesheet_cache;
J’ai essayé de faire la sauvegarde à nouveau, elle a toujours échoué, j’ai donc dû continuer à chercher la corruption.
J’ai calculé le nombre total de lignes dans ma table avec :
select count(*) from stylesheet_cache;
J’ai obtenu un compte de 2260 lignes.
J’ai cherché la ligne exacte qui était corrompue et je l’ai supprimée. J’ai supposé que stylesheet_cache n’était pas quelque chose qui pouvait vraiment casser toute ma base de données. Comme je l’ai mentionné, je ne suis pas un expert, donc j’ai peut-être pris un risque trop important, soyez prudent lorsque vous faites cela, car vous pourriez endommager votre base de données.
J’ai utilisé les requêtes LIMIT et OFFSET pour trouver les lignes corrompues.
select * from stylesheet_cache order by id limit 100 offset 0;
J’ai joué avec l’offset et la limite jusqu’à obtenir l’erreur “Missing chunk…” puis j’ai affiné avec LIMIT 1 et l’offset de la ligne corrompue. Dans mon cas, il y avait 5 lignes corrompues.
Vous pourriez utiliser un script sh pour trouver la ligne avec moins d’effort. J’ai procédé manuellement, ce qui a pris du temps, mais vous pourriez utiliser ceci :
#!/bin/sh
j=0
while [ $j -lt 2260 ]
do
psql -U postgres -d discourse -c "SELECT * FROM stylesheet_cache LIMIT 1 offset $j" >/dev/null || echo $j
j=$(($j+1))
done
J’ai cherché l’id de la ligne corrompue avec la commande suivante :
select id from stylesheet_cache order by id limit 1 offset 450;
id
----
11498
L’id de ma ligne corrompue était donc 11498.
J’ai supprimé la ligne avec :
delete from stylesheet_cache where id = 11498;
Après avoir supprimé les lignes corrompues, j’ai à nouveau procédé au REINDEX :
REINDEX table stylesheet_cache;
REINDEX table pg_toast.pg_toast_40948;
VACUUM analyze stylesheet_cache;
Et j’ai essayé de faire la sauvegarde à nouveau, cette fois cela a fonctionné. Je me suis guidé en utilisant ces instructions de récupération postgres : Postgres error: Missing chunk 0 for toast value in pg_toast · GitHub
AVERTISSEMENT : ceci n’est pas un avis d’expert, alors procédez avec prudence si vous avez des corruptions similaires de “chunk manquant” et que vous essayez de les corriger.