Ручное восстановление данных системного каталога СУБД
Этот раздел является шагом 13 к сценарию восстановления данных системного каталога.
При выявлении проблем в работе СУБД после успешного обновления и некоторого периода эксплуатации может возникнуть необходимость в корректировке системных данных каталога или откате их изменений, произведенных во время обновления.
В случае кластерной конфигурации все действия по изменению системного каталога производятся только на основном узле, при этом репликация осуществляется во время синхронизации (разделы «Откат таблиц системного каталога СУБД» и «После восстановления не получилось снять дамп какой-либо из баз данных СУБД»). Переименование директорий пользовательских табличных пространств, изменение версии системного каталога производится как на мастере, так и на реплике.
Восстановление стенда после неуспешного обновления
Ошибка возникла до запуска утилиты inplace_upgrade.sh
При возникновении ошибки до запуска утилиты inplace_upgrade.sh
в случае, когда автоматический откат не выполнился, перейдите к инструкции отката.
Ошибка возникла при запуске утилиты inplace_upgrade.sh в режиме UPDATE, утилита вернула код 5
При возникновении ошибки при запуске утилиты inplace_upgrade.sh
до обновления системных каталогов, предусмотрено автоматическое восстановление версии системного каталога и пользовательских табличных пространств. Если автоматический откат не выполнился, перейдите к инструкции отката.
Ошибка возникла при запуске утилиты inplace_upgrade.sh в режиме UPDATE, утилита вернула код 4
При возникновении ошибки при запуске утилиты inplace_upgrade.sh
после начала обновления системных каталогов, предусмотрено автоматическое восстановление версии системного каталога и пользовательских табличных пространств. Если автоматический откат не выполнился, требуется откат бинарных файлов и настроек по инструкции отката. После отката бинарных файлов необходимо запустить утилиту inplace_upgrade.sh
с командой reset
:
./inplace_upgrade.sh -d <pgdata> -l <директория логов> -p <порт> -h <хост> -u <суперпользователь> -b <база данных для подключения по умолчанию> -s <директория с утилитой> -m <директория для sql-дампов> -B <директория бэкапа> reset -t <директория утилит postgres and pg_ctl> -T <директория утилит psql and pg_dump>
После получения кода возврата 0
откат считается успешным.
Ошибка при работе утилиты inplace_upgrade.sh в режиме UPDATE, утилита вернула код 1
Завершение утилиты inplace_upgrade.sh
с кодом 1
требует ручного восстановления. Ниже рассматриваются возможные ситуации.
Для отката бинарных файлов и настроек сценария обновления требуется обратиться к инструкции отката.
Неуспешное изменение версии системного каталога в файле global/pg_control при обновлении
Первое изменение, которое производит скрипт inplace_upgrade.sh
, заключается в вызове утилиты update_catalog_version
для обновления версии системного каталога. Перед обновлением файла global/pg_control
утилита update_catalog_version
формирует файл резервного копирования pg_control.bak
в директории --backupdir
. Утилита update_catalog_version
вызывается также и при автоматическом восстановлении в случае неудачного обновления – при этом создается дополнительная резервная копия, которая помещается в директорию <--backupdir>/reset_pg_control/pg_control.bak
.
Ниже рассматриваются возможные ситуации возникновения сбоя при работе утилиты update_catalog_version
:
-
Ошибка обновления версии системного каталога утилитой
update_catalog_version
.Ошибка возникла во время работы утилиты
update_catalog_version
до момента начала обновления каталога. Данная ситуация сопровождается сообщением в логе:update_catalog_version: error: Catalog version has not been updated, file <pgdata>/global/pg_control is corrupted
-
Выполните команду:
sudo cp <директория бэкапа>/pg_control.bak $PGDATA/global/pg_control
-
После успешного завершения работы утилиты проверьте утилитой
pg_controldata
содержимое файлаpg_control
:pg_controldata -D $PGDATA
Вывод:
...
Catalog version number: <старая версия системного каталога>
...
-
-
Ошибка при повторном вызове утилиты
update_catalog_version
.Ошибка возникла во время работы утилиты
update_catalog_version
во время автоматического восстановления, инициированного утилитойinplace_upgrade.sh
.Данная ситуация сопровождается следующим сообщением в логе:
pg_ctl start: waiting for server to start.................... done server started
...
ERROR: ... # Ошибка во время работы inplace_upgrade.sh
...
INFO: renamed '/pgdata/06/tablespaces/Tbl_t/PG_15_<новая версия системного каталога>' -> '/pgdata/06/tablespaces/Tbl_t/PG_15_<старая версия системного каталога>'
...
ERROR: update_catalog_version: Catalog version has not been updated, file <pgdata>/global/pg_control is corruptedВнимание!За время работы утилиты
inplace_upgrade.sh
может поменяться позиция LSN, это приведет к изменению текущего WAL-файла и файлаpg_control
. Поэтому в команде ниже работа производится именно с текущимpg_control
, который был сохранен перед повторным вызовом утилиты.-
Выполните команду:
sudo cp <директория бэкапа>/reset_pg_control/pg_control.bak $PGDATA/global/pg_control
-
Проверьте права на доступ к файлу PostgreSQL. Запустите утилиту
update_catalog_version
:update_catalog_version -c <новая версия системного каталога> -C <старая версия системного каталога> -D $PGDATA -b <директория для бэкапа pg_control> -f
-
После успешного завершения работы
update_catalog_version
проверьте утилитойpg_controldata
содержимое файлаpg_control
:update_catalog_version
pg_controldata -D $PGDATA
update_catalog_versionВывод:
...
Catalog version number: <старая версия системного каталога>
...
-
Ошибка восстановления имени папки пользовательского табличного пространства в соответствии со старой версией системного каталога
Ошибка возникает во время автоматического восстановления, инициированного утилитой inplace_upgrade.sh
при переименовании папки пользовательского табличного пространства.
Для восстановления пользовательских табличных пространств необходимо получить из файла <директория бэкапа>/user_tbls.txt
все пользовательские табличные пространства, относящиеся к СУБД и произвести переименование содержащихся в них папок PG_<версия PostgreSQL>_<версия системного каталога>
в соответствии с возвращаемой версией системного каталога.
Данная ситуация сопровождается следующим сообщением в логе:
ERROR: ... # Ошибка во время работы inplace_upgrade.sh
...
ERROR: mv: cannot move ...
-
Выполните:
sudo mv <пользовательский tablespace>/PG_15_202409231 <пользовательский tablespace>/PG_15_202310091
-
Проверьте содержимое директории пользовательского табличного пространства командой
ls
:ls <директория пользовательского табличного пространства> -la
drwx------ 3 postgres postgres 4096 Oct 16 14:28 .
drwx------ 3 postgres postgres 4096 Oct 16 14:28 ..
drwx------ 3 postgres postgres 4096 Oct 16 14:28 PG_<версия PostgreSQL>_<старая версия системного каталога>
Ошибка обновления СУБД после успешного обновления утилитой inplace_upgrade.sh и возврата кода 0
В случае проблемы в работе обновления СУБД после успешной отработки утилиты inplace_upgrade.sh
необходимо произвести откат бинарных файлов к старой версии по инструкции отката и вернуть системный каталог в состояние, соответствующее старой версии СУБД. Для возвращения системного каталога в исходное состояние необходимо записать старую версию системного каталога в файл global/pg_control
, переименовать папки в пользовательских табличных пространствах в соответствии со старой версией системного каталога и выполнить ручную корректировку данных системного каталога для отмены изменений, произошедших в нем во время обновления.
Откат версии системного каталога в файле global/pg_control
-
Запустите утилиту
update_catalog_version
:update_catalog_version -c <новая версия системного каталога> -C <старая версия системного каталога> -D $PGDATA -b <директория для бэкапа pg_control> -f
-
После успешного завершения работы
update_catalog_version
проверьте утилитойpg_controldata
содержимое файлаpg_control
на соответствие старой версии системного каталога.
Откат папок в пользовательских табличных пространствах СУБД
Для восстановления пользовательских табличных пространств, получите из файла <директория бэкапа>/user_tbls.txt
все пользовательские пространства, относящиеся к СУБД и переименуйте содержащиеся в них папки PG_<версия PostgreSQL>_<версия системного каталога>
в соответствии с возвращаемой версией системного каталога.
Пример:
sudo mv <пользовательский tablespace>/PG_15_202409231 <пользовательский tablespace>/PG_15_202310091
Проверьте права на доступ к файлу PostgreSQL.
Откат таблиц системного каталога СУБД
Для восстановления таблиц системного каталога:
-
Проанализируйте SQL-скрипты обновления в папке
installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/
для определения объектов, которые были добавлены или изменены при обновлении. Пример можно найти в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», пункт 4, «Содержимое папкиpg_inplace_upgrade/sql_upgrade_6xx
». -
Проанализируйте файл
<logdir>/inplace_upgrade.log
для определения добавленных (измененных) объектов и их параметров.Пример содержимого лога, показывающий, какие объекты были созданы:
2024-10-23 09:44:16.621 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.binary_upgrade_set_next_pg_proc_oid: "3814|binary_upgrade_set_next_pg_proc_oid|11|10|12|1|0|0|-|f|f|f|t|f|s|s|1|0|2278|26||||||binary_upgrade_set_next_pg_proc_oid||||"
2024-10-23 09:44:16.621 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 27 at RAISE
2024-10-23 09:44:16.622 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.binary_upgrade_set_next_namespace_oid: "3813|binary_upgrade_set_next_namespace_oid|11|10|12|1|0|0|-|f|f|f|t|f|s|s|1|0|2278|26||||||binary_upgrade_set_next_namespace_oid||||"
2024-10-23 09:44:16.622 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 47 at RAISE
2024-10-23 09:44:16.623 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.stop_recovery_event: "9306|stop_recovery_event|11|10|12|1|0|0|-|f|f|f|t|f|s|s|6|0|2278|""25 25 25 16 23 16""|""{25|25|25|16|23|16}""|""{i|i|i|i|i|i}""|""{action|dbname|dump_file|is_backup|time_in_min|result}""|||stop_recovery_event||||"
2024-10-23 09:44:16.623 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 68 at RAISE
2024-10-23 09:44:16.623 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.start_recovery_event: "9307|start_recovery_event|11|10|12|1|0|0|-|f|f|f|t|f|s|s|4|0|16|""25 25 25 16""|""{25|25|25|16}""|""{i|i|i|i}""|""{action|dbname|dump_file|is_backup}""|||start_recovery_event||||"
2024-10-23 09:44:16.623 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 90 at RAISE
2024-10-23 09:44:16.625 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.pg_integrity_add_file: "9308|pg_integrity_add_file|11|10|12|1|0|0|-|f|f|f|t|f|s|s|1|0|16|25|{25}|{i}|{file_check}|||IntegrityAddFiles||||{postgres=X/postgres}"
2024-10-23 09:44:16.625 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 113 at RAISE
2024-10-23 09:44:16.625 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.pg_integrity_add_catalog: "9309|pg_integrity_add_catalog|11|10|12|1|0|0|-|f|f|f|t|f|s|s|2|0|16|""25 25""|""{25|25}""|""{i|i}""|""{db_name|catalog_name}""|||IntegrityAddCatalog||||{postgres=X/postgres}"
2024-10-23 09:44:16.625 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 136 at RAISE
2024-10-23 09:44:16.626 MSK [2967393] [unknown] NOTICE: CREATE FUNCTION pg_catalog.pg_integrity_check: "9310|pg_integrity_check|11|10|12|1|0|0|-|f|f|f|t|f|s|s|0|0|16|""""||||||IntegrityCheck||||{postgres=X/postgres}"
2024-10-23 09:44:16.626 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 156 at RAISE
2024-10-23 09:44:16.629 MSK [2967393] [unknown] NOTICE: CREATE VIEW pg_catalog.pg_stat_progress_unite: "12001|pg_stat_progress_unite|11|12004|0|10|0|0|0|0|-1|0|0|f|f|p|v|6|0|t|f|f|f|f|t|n|f|0|0|0|||"
2024-10-23 09:44:16.629 MSK [2967393] [unknown] CONTEXT: PL/pgSQL function inline_code_block line 187 at RAISE
backend> 2024-10-23 09:44:16.629 MSK [2967393] [unknown] NOTICE: shutting down
2024-10-23 09:44:16.629 MSK [2967393] [unknown] LOG: checkpoint starting: shutdown immediate
2024-10-23 09:44:16.630 MSK [2967393] [unknown] LOG: checkpoint complete: wrote 44 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.001 s, sync=0.001 s, total=0.001 s; sync files=0, longest=0.000 s, average=0.000 s; distance=215 kB, estimate=215 kB
2024-10-23 09:44:16.633 MSK [2967393] [unknown] NOTICE: database system is shut down -
Проанализируйте файл
<logdir>/postgres_updade.log
для определения добавленных (измененных) объектов и их параметров. -
Проанализируйте (сравните) дампы системных каталогов СУБД до и после обновления и определите их отличия. Данный пункт выполняется если есть доступ к дампам (они не защищены политиками безопасности).
-
Проанализируйте SQL-скрипты отката в папке
installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/
для изучения скриптов отката добавленных объектов. Пример можно найти в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», «Пример SQL-скрипта восстановления». -
На основе информации, полученной в пунктах 1-5, определите, какие объекты были изменены или добавлены в результате обновления. Для всех объектов напишите SQL-скрипт отката (более подробно написание скриптов описано в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД»).
-
Составьте общие SQL-скрипты по правилам, описанным в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», «SQL-скрипт отката с rollback для проверки отсутствия ошибок написания», «SQL-скрипт отката без rollback для отката изменений».
-
Для кластерной конфигурации создайте временной слот физической репликации для предотвращения удаления WAL-файлов, которые потребуются позднее для синхронизации реплики.
psql -d postgres -qtAX -c "SELECT * FROM pg_create_physical_replication_slot('$slot_reset_name', 'TRUE');"
-
Получите список всех баз данных:
psql -d postgres -qtAX -c "SELECT datname FROM pg_database;"
-
Остановите СУБД. Для кластера остановите процесс репликации, основной узел и реплику, дальнейшие действия выполняйте на основном узле.
-
Запустите СУБД в режиме
binary-mode
:pg_ctl -D <директория pgdata> -l <файл для логов> -o -b start
-
Для осуществления предварительной проверки скрипта выполните вариант скрипта с
ROLLBACK
в конце. Выполните скрипт во всех базах данных, требующих корректировки. Для получения доступа к базеtemplate0
необходимо выставить в таблицеpg_database
параметрdatallowconn = TRUE
. Без этого доступ к базеtemplate0
будет запрещен.Пример:
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
psql -d template0 -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
psql -d template1 -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d postgres -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d $user_db -qtAX -c "<sql-скрипт с ROLLBACK>"
...Если во время проверки скриптов не возникло ошибок, то выполните вариант скрипта без
ROLLBACK
.Затем выполните скрипт во всех базах данных, требующих корректировки.
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
psql -d template0 -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
psql -d template1 -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d postgres -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d $user_db -qtAX -c "<sql-скрипт без ROLLBACK>"
...Если в результате применения скриптов не возникло ошибок, то остановите СУБД и перейдите к следующему пункту. Если в результате выполнения скриптов возникли ошибки, то повторите пункты 1-12.
-
После успешного выполнения скрипта во всех базах данных, остановите СУБД:
pg_ctl -D <директория pgdata> stop
-
Запустите СУБД в обычном режиме:
pg_ctl -D <директория pgdata> -l <файл для логов> start
-
Снимите дампы системных каталогов во всех базах данных для проверки их консистентности. Пример:
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
pg_dump -d template0 -n pg_catalog --exclude-table pr_* 1> dump_template0.sql 2> dump_template0.err
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
pg_dump -d template1 -n pg_catalog --exclude-table pr_* 1> dump_template1.sql 2> dump_template1.err
pg_dump -d postgres -n pg_catalog --exclude-table pr_* 1> dump_postgres.sql 2> dump_postgres.err
...Если все дампы снялись без ошибок, то восстановление считается успешным. Если нет, то вернитесь к пунктам 1-13.
-
Остановите СУБД:
pg_ctl -D <директория pgdata> stop
-
Для standalone-конфигурации откат считается завершенным. Для кластерной конфигурации требуется запуск реплики и синхронизация ее с мастером посредством репликации.
-
После успешной синхронизации реплики с основным узлом, удалите временный слот репликации:
Внимание!Если временный слот физической репликации будет удален до окончания успешной синхронизации, могут быть потеряны актуальные WAL-файлы. Синхронизация реплики в этом случае будет невозможна.
SELECT * FROM pg_drop_replication_slot('tmp_update_slot');
Восстановление стенда после неуспешного отката
Ошибка при работе inplace_upgrade.sh в режиме reset, вернула код 1
Режим reset
является этапом автоматического отката системного каталога к исходному состоянию, остальные действия ручного восстановления описаны в инструкции отката. Во время этого этапа выполняется восстановление объектов:
- файла
pg_control
; - WAL-файла, соответствующему восстановленному файлу
pg_control
; - папки
pg_slots
; - файлов папки
global
, относящихся к системному каталогу; - файлов папки
base
, относящихся к системному каталогу; - файлов, находящихся в папках пользовательских табличных пространств и относящихся к системному каталогу;
- исходной структуры системного каталога (
PGDATA
).
Ниже приведены гипотетически возможные ошибки в результате работы скрипта inplace_upgrade.sh
в режиме reset
.
Невозможно восстановить какой-либо из файлов СУБД (в папках pg_wal, global, base и т.д.)
Для решения проанализируйте <logdir>/inplace_upgrade.log
и определите место возникновения ошибки. После чего скопируйте все файлы из директорий, указанных в файле <директория бэкапа>/backup_db/backup_db.txt
в директории назначения СУБД.
В данном разделе рассмотрен пример восстановления файлов СУБД:
-
Выполните команды:
sudo cp -rf <директория бэкапа>/backup_db/pg_wal/ pgdata/06/data/
sudo cp -rf <директория бэкапа>/backup_db/pg_slots/ pgdata/06/data/
sudo cp -rf <директория бэкапа>/backup_db/base/ pgdata/06/data/
sudo cp -rf <директория бэкапа>/backup_db/global/ pgdata/06/data/
sudo cp -rf <директория бэкапа>/backup_db/user_tbsps <директория пользовательского табличного пространства>/
... -
Запустите СУБД со старыми бинарными файлами (откат к ним описан в инструкции отката):
pg_ctl start
-
Снимите SQL-дамп системных каталогов во всех базах данных. Пример снятия дампа:
# Для возможности снятия sql-дампа с базы данных template0 необходимо установить параметр datallowconn в значение TRUE
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
pg_dump -d template0 -n pg_catalog --exclude-table pr_* 1> dump_template0.sql 2> dump_template0.err
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
pg_dump -d template1 -n pg_catalog --exclude-table pr_* 1> dump_template1.sql 2> dump_template1.err
pg_dump -d postgres -n pg_catalog --exclude-table pr_* 1> dump_postgres.sql 2> dump_postgres.err
...В случае успешного снятия дампов откат считается успешным.
После восстановления не получилось снять дамп какой-либо из баз данных СУБД
Если возникла проблема снятия дампа системного каталога на какой-либо из баз данных после автоматического восстановления, то выполните действия:
-
Проанализируйте файл
<logdir>/inplace_upgrade.log
для определения первоначального места ошибки при обновлении. -
Проанализируйте файл
<logdir>/postgres_updade.log
для определения проблемы в СУБД (если она есть). -
Сравните дампы системных каталогов СУБД до обновления, после обновления, а также после отката. Необходимо определить их отличия. Данный пункт выполняется если есть доступ к дампам. Рекомендуется использовать команду
diff
для сравнения SQL-дампов. -
На основе информации, полученной в пунктах 1-3, определите, какие объекты были повреждены или неправильно добавлены. Для всех поврежденных объектов напишите SQL-скрипт отката.
примечаниеSQL-скрипты восстановления пишутся в соответствии с правилами написания SQL-скриптов для обновления системных данных каталога.
В директории
installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/
есть папки, соответствующие версиям Pangolin (например 616). В них присутствуют директорииreset_sql/
, в которых содержатся примеры скриптов отката. В папкахbinary_upgrade_sql/
иupgrade_sql/
содержатся скрипты обновления, с помощью которых ранее была произведена неудачная попытка обновления.Содержимое папки
pg_inplace_upgrade/sql_upgrade_6xx
:+sql_upgrade_6xx
|+6.1.0
||CATALOG_VERSION
|+6.1.1
||CATALOG_VERSION
|+6.1.2
||CATALOG_VERSION
|+6.1.3
||CATALOG_VERSION
|+reset_sql
|+binary_upgrade_sql
|+upgrade_sql
|+6.1.4
||CATALOG_VERSION
|+6.1.5
||CATALOG_VERSION
|+6.1.6
||CATALOG_VERSION
|+reset_sql
|+upgrade_sql
|+6.1.7
||CATALOG_VERSION
|+6.1.8
||CATALOG_VERSION
|+6.1.9
||CATALOG_VERSION
|+6.2.0
||CATALOG_VERSION
|+reset_sql
|+upgrade_sql
|+6.3.0
||CATALOG_VERSION
|+reset_sql
|+upgrade_sql
|+6.4.0
||CATALOG_VERSION
|+reset_sql
|+binary_upgrade_sqlНапример, если обновление с 6.1.6 на 6.4.0, то необходимо проанализировать скрипты обновления и отката для версий 6.2.0, 6.3.0, 6.4.0. В соответствии с результатами анализа, полученными во всех предыдущих пунктах, нужно написать скрипты отката, которые необходимы для восстановления системных каталогов. Возможно потребуется использование уже готовых скриптов от разработчиков в папках
reset_sql
(может потребоваться корректировка).Пример SQL-скрипта восстановления:
-- Проверка наличия представления в системном каталоге
-- Если его нет, то скрипт написан неверно
IF EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE
proname = 'my_view') THEN
-- Печать текущего состояния pg_class до удаления представления
SELECT rtrim(ltrim(replace(pg_class::text, ',', '|'), '('), ')') INTO msg FROM pg_catalog.pg_class WHERE relname = 'my_view';
RAISE NOTICE 'CREATE VIEW pg_catalog.my_view: %', quote_ident(msg);
DROP VIEW pg_catalog.my_view;
ELSE
RAISE EXCEPTION 'The "my_view" view is already missing, there may be a product version error.';
END IF;
-- Проверка отсутствия объекта в системном каталоге
IF EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname = 'my_view') THEN
RAISE EXCEPTION 'Not found my_view';
END IF;
SET allow_system_table_mods = false;Отдельные SQL-скрипты отката встраиваются в общие SQL-скрипты отката. SQL-скрипт отката с
ROLLBACK
для проверки отсутствия ошибок написания:do $$
DECLARE
msg TEXT;
BEGIN
-- Включение возможности изменения системных таблиц
SET allow_system_table_mods = true;
SET LOCAL search_path TO pg_catalog;
-- sql-cкрипты восстановления
SET allow_system_table_mods = false;
ROLLBACK;
END
$$;SQL-скрипт отката без
ROLLBACK
для отката изменений:do $$
DECLARE
msg TEXT;
BEGIN
-- Включение возможности изменения системных таблиц
SET allow_system_table_mods = true;
SET LOCAL search_path TO pg_catalog;
-- sql-cкрипты восстановления
SET allow_system_table_mods = false;
END
$$;SQL-скрипт c последующим
ROLLBACK
необходим для проверки наличия ошибок в SQL-скриптах.SQL-скрипт без
ROLLBACK
необходим для восстановления системных каталогов, после того как была проведена проверка SQL-скриптом сROLLBACK
. -
После составления скрипта восстановления системного каталога, запустите СУБД в режиме
binary-mode
:pg_ctl -D <директория pgdata> -l <файл для логов> -o -b start
-
Посредством
psql
запишите скрипт во все поврежденные базы данных (предварительно сROLLBACK
). Пример:psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
psql -d template0 -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
psql -d template1 -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d postgres -qtAX -c "<sql-скрипт с ROLLBACK>"
psql -d $user_db -qtAX -c "<sql-скрипт с ROLLBACK>"
...Если в результате применения скриптов не возникло ошибок, то запустите скрипты для всех баз данных без
ROLLBACK
:psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
psql -d template0 -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
psql -d template1 -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d postgres -qtAX -c "<sql-скрипт без ROLLBACK>"
psql -d $user_db -qtAX -c "<sql-скрипт без ROLLBACK>"
...Если в результате применения скриптов не возникло ошибок, то остановите СУБД и перейдите к следующему пункту. Если в результате выполнения скриптов возникли ошибки, то повторите пункты 1-6.
-
После успешной записи всех скриптов, остановите СУБД:
pg_ctl -D <директория pgdata> stop
-
Запустите СУБД в обычном режиме:
pg_ctl -D <директория pgdata> -l <файл для логов> start
-
Снимите дампы системных каталогов со всех поврежденных баз данных для проверки их консистентности. Пример снятия дампа:
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';"
pg_dump -d template0 -n pg_catalog --exclude-table pr_* 1> dump_template0.sql 2> dump_template0.err
psql -d postgres -qtAX -c "UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';"
pg_dump -d template1 -n pg_catalog --exclude-table pr_* 1> dump_template1.sql 2> dump_template1.err
pg_dump -d postgres -n pg_catalog --exclude-table pr_* 1> dump_postgres.sql 2> dump_postgres.err
...Если все дампы снялись успешно, то восстановление считается успешным. Если нет, то вернитесь к пунктам 1-7.
-
Остановите СУБД:
pg_ctl -D <директория pgdata> stop
Ошибка после работы inplace_upgrade.sh в режиме reset, вернула код 0
Проблема возникла в сценарии отката обновления после успешного выполнения inplace_upgrade.sh
в режиме reset
. Обратитесь к инструкции отката.
Корректировка данных системного каталога СУБД в случае обнаружения проблем на этапе эксплуатации
В случае возникновения проблем в работе СУБД, связанных с прошедшим обновлением, приведите состояние объектов системного каталога к виду, обеспечивающему нормальное функционирование СУБД в новой версии.
Рекомендуется выполнить действия:
- Выполните анализ логов СУБД, определите, с какими объектами системного каталога связаны проблемы в работе.
- Проанализируйте SQL-скрипты обновления в папке
installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/
, с помощью которых выполнялось обновление СУБД (более подробно описано в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», п. 4). - Проанализируйте логи обновления
inplace_upgrade.sh
(<logdir>/inplace_upgrade.log
,<logdir>/postgres_updade.log
) для определения состояния обновленных объектов до и после обновления. - На основе пунктов 1-3 составьте SQL-скрипты корректировки обновления в соответствии с правилами написания SQL-скриптов для обновления системных данных каталога и далее действуйте в соответствии с разделом «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», п. 6-9.