Перейти к основному содержимому

Ручное восстановление данных системного каталога СУБД

Внимание!

Этот раздел является шагом 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
  1. Выполните команду:

    sudo cp <директория бэкапа>/pg_control.bak $PGDATA/global/pg_control
  2. После успешного завершения работы утилиты проверьте утилитой 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, который был сохранен перед повторным вызовом утилиты.

  1. Выполните команду:

    sudo cp <директория бэкапа>/reset_pg_control/pg_control.bak $PGDATA/global/pg_control
  2. Проверьте права на доступ к файлу PostgreSQL. Запустите утилиту update_catalog_version:

    update_catalog_version -c <новая версия системного каталога> -C <старая версия системного каталога> -D $PGDATA -b <директория для бэкапа pg_control> -f
  3. После успешного завершения работы 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 ...
  1. Выполните:

    sudo mv <пользовательский tablespace>/PG_15_202409231 <пользовательский tablespace>/PG_15_202310091
  2. Проверьте содержимое директории пользовательского табличного пространства командой 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

  1. Запустите утилиту update_catalog_version:

    update_catalog_version -c <новая версия системного каталога> -C <старая версия системного каталога> -D $PGDATA -b <директория для бэкапа pg_control> -f
  2. После успешного завершения работы update_catalog_version проверьте утилитой pg_controldata содержимое файла pg_control на соответствие старой версии системного каталога.

Откат папок в пользовательских табличных пространствах СУБД

Для восстановления пользовательских табличных пространств, получите из файла <директория бэкапа>/user_tbls.txt все пользовательские пространства, относящиеся к СУБД и переименуйте содержащиеся в них папки PG_<версия PostgreSQL>_<версия системного каталога> в соответствии с возвращаемой версией системного каталога.

Пример:

sudo mv <пользовательский tablespace>/PG_15_202409231 <пользовательский tablespace>/PG_15_202310091

Проверьте права на доступ к файлу PostgreSQL.

Откат таблиц системного каталога СУБД

Для восстановления таблиц системного каталога:

  1. Проанализируйте SQL-скрипты обновления в папке installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/ для определения объектов, которые были добавлены или изменены при обновлении. Пример можно найти в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», пункт 4, «Содержимое папки pg_inplace_upgrade/sql_upgrade_6xx».

  2. Проанализируйте файл <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
  3. Проанализируйте файл <logdir>/postgres_updade.log для определения добавленных (измененных) объектов и их параметров.

  4. Проанализируйте (сравните) дампы системных каталогов СУБД до и после обновления и определите их отличия. Данный пункт выполняется если есть доступ к дампам (они не защищены политиками безопасности).

  5. Проанализируйте SQL-скрипты отката в папке installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/ для изучения скриптов отката добавленных объектов. Пример можно найти в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», «Пример SQL-скрипта восстановления».

  6. На основе информации полученной в пунктах 1-5, определите, какие объекты были изменены или добавлены в результате обновления. Для всех объектов напишите SQL-скрипт отката (более подробно написание скриптов описано в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД»).

  7. Составьте общие SQL-скрипты по правилам, описанным в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», «SQL-скрипт отката с rollback для проверки отсутствия ошибок написания», «SQL-скрипт отката без rollback для отката изменений».

  8. Для кластерной конфигурации создайте временной слот физической репликации для предотвращения удаления WAL-файлов, которые потребуются позднее для синхронизации реплики.

    psql -d postgres -qtAX -c "SELECT * FROM pg_create_physical_replication_slot('$slot_reset_name', 'TRUE');"
  9. Получите список всех баз данных:

    psql -d postgres -qtAX -c "SELECT datname FROM pg_database;"
  10. Остановите СУБД. Для кластера остановите процесс репликации, основной узел и реплику, дальнейшие действия выполняйте на основном узле.

  11. Запустите СУБД в режиме binary-mode:

    pg_ctl -D <директория pgdata> -l <файл для логов> -o -b start
  12. Для осуществления предварительной проверки скрипта выполните вариант скрипта с 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.

  13. После успешного выполнения скрипта во всех базах данных остановите СУБД:

    pg_ctl -D <директория pgdata> stop
  14. Запустите СУБД в обычном режиме:

    pg_ctl -D <директория pgdata> -l <файл для логов> start
  15. Снимите дампы системных каталогов во всех базах данных для проверки их консистентности. Пример:

    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.

  16. Остановите СУБД:

    pg_ctl -D <директория pgdata> stop
  17. Для standalone-конфигурации откат считается завершенным. Для кластерной конфигурации требуется запуск реплики и синхронизация ее с мастером посредством репликации.

  18. После успешной синхронизации реплики с основным узлом удалите временный слот репликации:

    Внимание!

    Если временный слот физической репликации будет удален до окончания успешной синхронизации, могут быть потеряны актуальные 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 в директории назначения СУБД.

Восстановление файлов СУБД

В данном разделе рассмотрен пример воссатновления файлов СУБД:

  1. Выполните команды:

    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 <директория пользовательского табличного пространства>/
    ...
  2. Запустите СУБД со старыми бинарными файлами (откат к ним описан в инструкции отката):

    pg_ctl start
  3. Снимите 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
    ...

    В случае успешного снятия дампов откат считается успешным.

После восстановления не получилось снять дамп какой-либо из баз данных СУБД

Если возникла проблема снятия дампа системного каталога на какой-либо из баз данных после автоматического восстановления, то выполните действия:

  1. Проанализируйте файл <logdir>/inplace_upgrade.log для определения первоначального места ошибки при обновлении.

  2. Проанализируйте файл <logdir>/postgres_updade.log для определения проблемы в СУБД (если она есть).

  3. Сравните дампы системных каталогов СУБД до обновления, после обновления, а также после отката. Необходимо определить их отличия. Данный пункт выполняется если есть доступ к дампам. Рекомендуется использовать команду diff для сравнения SQL-дампов.

  4. На основе информации, полученной в пунктах 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.

  5. После составления скрипта восстановления системного каталога запустите СУБД в режиме binary-mode:

    pg_ctl -D <директория pgdata> -l <файл для логов> -o -b start
  6. Посредством 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.

  7. После успешной записи всех скриптов остановите СУБД:

    pg_ctl -D <директория pgdata> stop
  8. Запустите СУБД в обычном режиме:

    pg_ctl -D <директория pgdata> -l <файл для логов> start
  9. Снимите дампы системных каталогов со всех поврежденных баз данных для проверки их консистентности. Пример снятия дампа:

    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.

  10. Остановите СУБД:

    pg_ctl -D <директория pgdata> stop

Ошибка после работы inplace_upgrade.sh в режиме "reset", вернула код 0

Проблема возникла в сценарии отката обновления после успешного выполнения inplace_upgrade.sh в режиме reset. Обратитесь к инструкции отката.

Корректировка данных системного каталога СУБД в случае обнаружения проблем на этапе эксплуатации

В случае возникновения проблем в работе СУБД, связанных с прошедшим обновлением, приведите состояние объектов системного каталога к виду, обеспечивающему нормальное функционирование СУБД в новой версии.

Рекомендуется выполнить действия:

  1. Выполните анализ логов СУБД, определите, с какими объектами системного каталога связаны проблемы в работе.
  2. Проанализируйте SQL-скрипты обновления в папке installer/utilities/pg_inplace_upgrade/sql_upgrade_6xx/, с помощью которых выполнялось обновление СУБД (более подробно описано в разделе «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», п. 4).
  3. Проанализируйте логи обновления inplace_upgrade.sh (<logdir>/inplace_upgrade.log, <logdir>/postgres_updade.log) для определения состояния обновленных объектов до и после обновления.
  4. На основе пунктов 1-3 составьте SQL-скрипты корректировки обновления в соответствии с правилами написания SQL-скриптов для обновления системных данных каталога и далее действуйте в соответствии с разделом «После восстановления не получилось снять дамп какой-либо из баз данных СУБД», п. 6-9.