Ошибка коррупции Postgres: повторяющиеся строки с одним и тем же первичным ключом - PullRequest
0 голосов
/ 15 мая 2018

Я недавно столкнулся с ошибкой Postgres (моя БД повреждена), в основном, некоторые строки в БД дублированы (вместе с первичным ключом).Прежде чем я продолжу, вот ошибки, упомянутые в этом посте:

ERROR:  uncommitted xmin 393410960 from before xid cutoff 393413059 needs to be frozen

ИЛИ

ERROR:  failed to find parent tuple for heap-only tuple at (3,8) in table "your_table"

Очевидно, значение xmin 393410960, значение отсечения393413059 и ctid значение (3,8) может отличаться в вашем случае.


Как я получаю эти ошибки:

Если выхотите получить эти ошибки (и у вас есть эта проблема), вот как вы могли бы их найти:

your_db=# VACUUM FULL your_table;
ERROR:  uncommitted xmin 393410960 from before xid cutoff 393413059 needs to be frozen

И получить вторую ошибку:

your_db=# REINDEX TABLE your_table;
ERROR:  failed to find parent tuple for heap-only tuple at (3,8) in table "your_table"

DON 'Т ПАНИКА!Решение этой проблемы приведено ниже:)

1 Ответ

0 голосов
/ 15 мая 2018

Прежде чем читать это, обратите внимание Я не несу никакой ответственности за потерю или повреждение данных или любые проблемы, которые это вызывает!

Я бы посоветовал вам сделать резервную копию всего!Но не делайте pgdump, делайте полное резервное копирование файловой системы.Используйте rsync и поместите его где-нибудь еще.

Также могут быть и другие решения, поэтому не делайте этого сначала, прежде чем проводить дополнительные исследования.Однако я могу заявить, что это сработало для меня.


Поэтому, чтобы это исправить, я следовал совету, данному в посте по адресу:

http://www.postgresql -archive.org / BUG-10189-Limit-в-9-3-4-нет-больше-работа-при-заказ-использование-а-композит-разнотипный-индекс-td5802079.html

По сути, я сделал следующее:

your_db=# BEGIN;
BEGIN
your_db=# DELETE FROM your_table WHERE ctid='(3,8)';
DELETE 1
your_db=# END;
COMMIT
your_db=# VACUUM FULL your_table;
VACUUM
your_db=# REINDEX TABLE your_table;
REINDEX

Только те строки, которые начинаются с your_db=#, - это те, которые я написал.Итак, что вы можете видеть, это то, что я удалил поврежденную строку и затем выполнил переиндексацию.Если это не удается, вы удаляете следующую поврежденную строку и переиндексируете, пока она не будет выполнена успешно.

Надеюсь, это поможет.

...