Ich schreibe diesen Beitrag bezüglich eines Fehlers bei fehlenden Chunks in einer Postgres-Tabelle, der meine täglichen Backups fehlschlagen ließ. Ich konnte das Problem beheben und möchte die von mir verwendete Methode darlegen, falls sie jemandem helfen kann, der auf dieses Problem stößt. Dies ist in keiner Weise eine Anleitung oder professionelle Anweisung zur korrekten Behebung von Postgres-Fehlern bei fehlenden Chunks, da ich kein Experte bin und dies ohne viel Wissen getan habe, aber es hat am Ende funktioniert.
Der Fehler, den ich während der Backups erhielt:
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;
Das Problem lag also in der Tabelle stylesheet_cache, ERROR: missing chunk number 0 for toast value 1903804 in pg_toast_22663.
Ich verwende Discourse in Docker, also habe ich Folgendes getan:
ssh into the server
cd /path/to/discourse
./launcher rebuild app
su postgres -c "psql discourse"
Sobald ich in Postgres war, versuchte ich, die Tabelle neu zu indizieren, in der Hoffnung, dass dies das Problem lösen würde.
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;
Ich versuchte erneut, das Backup durchzuführen, es schlug immer noch fehl, also musste ich weiter nach der Beschädigung suchen.
Ich berechnete die Gesamtzahl der Zeilen in meiner Tabelle mit:
select count(*) from stylesheet_cache;
Ich erhielt eine Anzahl von 2260 Zeilen.
Ich suchte nach der genauen Zeile, die beschädigt war, und löschte sie. Irgendwie ging ich davon aus, dass stylesheet_cache nichts ist, was meine gesamte Datenbank wirklich beschädigen könnte. Wie ich bereits erwähnte, bin ich kein Experte, daher habe ich vielleicht einen zu großen Vertrauensvorschuss gewagt. Seien Sie vorsichtig, wenn Sie dies tun, da Sie Ihre Datenbank durcheinander bringen könnten.
Ich verwendete die Abfragen LIMIT und OFFSET, um die beschädigten Zeilen zu finden.
select * from stylesheet_cache order by id limit 100 offset 0;
Ich spielte mit offset und limit, bis ich den Fehler Missing chunk... erhielt und grenzte ihn dann auf LIMIT 1 und den Offset der beschädigten Zeile ein. In meinem Fall waren 5 Zeilen beschädigt.
Sie könnten ein Shell-Skript verwenden, um die Zeile mit weniger Aufwand zu finden. Ich habe den manuellen Weg gewählt, der einige Zeit in Anspruch nahm, aber Sie könnten Folgendes verwenden:
#!/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
Ich suchte nach der ID der beschädigten Zeile mit dem folgenden Befehl:
select id from stylesheet_cache order by id limit 1 offset 450;
id
----
11498
Die ID meiner beschädigten Zeile war also 11498.
Ich löschte die Zeile mit
delete from stylesheet_cache where id = 11498;
Nachdem ich die beschädigten Zeilen gelöscht hatte, ging ich erneut zum REINDEX:
REINDEX table stylesheet_cache;
REINDEX table pg_toast.pg_toast_40948;
VACUUM analyze stylesheet_cache;
Und versuchte erneut, das Backup durchzuführen. Dieses Mal funktionierte es. Ich habe mich an diesen Postgres-Wiederherstellungsanweisungen orientiert: Postgres error: Missing chunk 0 for toast value in pg_toast · GitHub
HAFTUNGSAUSSCHLUSS: Dies ist keine Expertenmeinung. Gehen Sie mit Vorsicht vor, wenn Sie ähnliche Beschädigungen durch fehlende Chunks haben und versuchen, diese zu beheben.