Как мне восстановить поврежденную системную таблицу в PostgreSQL

#database #postgresql #corruption

#База данных #postgresql #повреждение

Вопрос:

Я только что попытался выполнить pg_upgrade для довольно большого кластера баз данных PostgreSQL с версии 8.3.0 до версии 9.0.4. Все выглядело так, как будто все будет работать просто отлично, пока новая схема не была создана в целевом кластере. По какой-то причине он дважды пытался создать групповую роль.

После просмотра всех сценариев было совершенно очевидно, что он дублировал групповую роль 4 раза. Я восстановил базу данных 8.3.0, и было совершенно очевидно, что в pg_authid таблице повторяется строка.

Я попытался перевести базу данных в однопользовательский режим, чтобы попытаться REINDEX TABLE pg_authid . При попытке создать новый индекс с дублированными значениями произошел сбой.

Я попытался удалить роль группы-нарушителя. Это удалило одну из 4 строк в pg_authid , но, похоже, еще больше запутало ситуацию.

Я видел упоминание о том, что запуск полного вакуума в таблице может устранить такое повреждение, но у меня мало надежды на то, что это сработает. Итак, пока данные восстанавливаются, я буду выуживать идеи.

Комментарии:

1. Вам лучше спросить в списках рассылки postgresql: archives.postgresql.org/pgsql-general

Ответ №1:

Вы точно выполнили pg_upgrade шаги? Если это так, у вас должен быть доступен ваш старый каталог данных, и вы можете вернуться к нему при необходимости …. правильно? 🙁

REINDEX TABLE Не решит вашу проблему, но a

 # From old database
pg_dump -t my_problem_table(s) ... > my_screwed_up_data.sql
pg_dump -T my_problem_table(s) ... > my_not_screwed_up_data.sql


# Fix whatever isn't right
${EDITOR} my_screwed_up_data.sql

# In to a fresh database instance
cat my_screwed_up_data.sql | psql
cat my_not_screwed_up_data.sql | psql
  

возможно, вы начнете. Вероятно, вам придется выполнить шаги два и три несколько раз, пока все не загрузится правильно. Надеюсь, это просто ваши системные каталоги, которые содержат поддельные данные.

Комментарии:

1. Я надеялся избежать выполнения каких-либо операций дампа / восстановления. Мне удалось получить все мои данные в новом экземпляре базы данных с помощью pg_dumpall редактирования файла дампа и перезагрузки всего в новую базу данных. Это более или менее то, что вы предлагаете, и это работает нормально, но для завершения этого процесса потребуется безумное количество времени. Я надеялся сделать pg_upgrade с --link опцией, чтобы сократить процесс обновления до разумного периода времени.

2. Согласен. Я бы сообщил об этой ошибке, если вы еще этого не сделали. На практике, кстати, я обычно использую pgbouncer прослушивание порта 5432 как способ «указать» на нужную базу данных, чтобы SELECT пользователи могли перейти к функционирующей версии базы данных. Это очень, очень хороший рабочий инструмент.

Ответ №2:

Изучали ли вы возможность изменения pg_upgrade, чтобы вы могли исправить неправильные инструкции, как предложил Шон, прежде чем приступить к обновлению? Я полагаю, что в pg_upgrade происходит дамп / восстановление системных таблиц.

Комментарии:

1. Вау, оказывается pg_upgrade , это легко изменить. Я просто поставил паузу в файле dump.c, прежде чем он использует SQL-скрипт глобального дампа. Исправить повреждение там было достаточно просто. После этого все обновилось в обычном режиме.