#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-скрипт глобального дампа. Исправить повреждение там было достаточно просто. После этого все обновилось в обычном режиме.