postgrespro / pg_probackup

Backup and recovery manager for PostgreSQL
https://postgrespro.github.io/pg_probackup/
Other
703 stars 86 forks source link

После восстановления нет нужной таблицы, однако после выполнения DDL-команды, она появляется #607

Open twistmind opened 1 year ago

twistmind commented 1 year ago

Доброго времени суток!

Для снятия бекапов и восстановления пользуюсь pg_probackup версии 2.5.12 СУБД - PostgreSQL 14.7

В бекапе имеется тестовая таблица test_recovery в базе postgres, при восстановлении того же инстанса (с которого брался бекап) хоть в режиме FULL, хоть DELTA (хоть с CHECKSUM, хоть нет) - таблица пропадает, однако ее file node id присутствует в base/14486/ после самого восстановления. Но при подключении СУБД ее почему-то не видит. Хотя если попытаться создать эту же таблицу, то выдается ошибка по системной таблице, что объект с таким типом уже существует:

    postgres=# select * from test_recovery;
    ERROR:  relation "test_recovery" does not exist

    postgres=# create table test_recovery (d timestamptz);
    ERROR:  duplicate key value violates unique constraint "pg_type_typname_nsp_index"
    DETAIL:  Key (typname, typnamespace)=(test_recovery, 2200) already exists.

А если попытаться выполнить успешную транзакцию с DDL-командой, то таблица становится доступной:

    postgres=# create temporary table foo on commit drop as select 1;
    postgres=# select * from test_recovery;
               d
    -------------------------------
    2023-07-27 11:24:09.129152
    (1 row)

Не всегда правда она становится сразу доступной и с данными, иногда появляется только таблица без данных, а данные после второй DDL-команды... ну, либо это совпадение, возможно. Иногда таблица появляется после переподключения через psql, а не сразу. Я проверял также возможность ее появления без DDL-команды чуть позже (мало ли), она сама точно не появляется.

Дополнительные данные: на сервере два инстанса - второй создавался из бекапа первого, но не в качестве реплики, а отдельного инстанса для тестов на порту 5433. Затем на втором инстансе создал эту тестовую таблицу и начал делать бекапы с этого второго инстанса, затем удалять таблицу или менять ее данные и с ручным CHECKPOINT и без него, затем восстанавливать и смотреть результаты.

Команда для бекапа:

`pg_probackup-14 backup -B /home/postgres/pgbcks/ -b DELTA --instance=pg14_2 -j 8 --stream --temp-slot --compress-algorithm=zlib --compress-level=5`

Команда для восстановления:

`pg_probackup-14 restore -B /home/postgres/pgbcks/ --instance pg14_2 -j 8 -i RYG6K0`

Список бекапов второго инстанса: image

Конфиг второго инстанса:

    #### Backup instance information
    pgdata = /home/postgres/pg14_2/data

    system-identifier = 7120186727137849989

    xlog-seg-size = 16777216
    #### Connection parameters
    pgdatabase = postgres
    pgport = 5433
    #### Replica parameters
    replica-timeout = 5min
    #### Archive parameters
    archive-timeout = 5min
    #### Retention parameters
    retention-redundancy = 0

    retention-window = 0

    wal-depth = 0
fukanchik commented 1 year ago

Здравствуйте, я подозреваю, что при восстановлении сервер не имеет доступа к wal архиву.

В конце восстановления сервер пишет в лог что-то вроде

redo done at 0/50001A0 system usage

если моя теория верна - в вашем случае этот lsn заканчивается до момента создания таблицы test_recovery.

twistmind commented 1 year ago

При бекапе используется STREAM - не ARСHIVE-метод, зачем ему доступ к архиву WAL? Его вообще нет и не планируется делать непрерывное архивирование. При STREAM-методе я ожидаю, что все WAL-файлы, которые могут появиться в процессе создания копии (или уже появились до) также заархивируются и при восстановлении воспроизведутся, разве нет? pg_probackup разве не вызывает CHECKPOINT перед бекапом? Если делает, значит все изменения, сделанные мной перед запуском бекапа должны быть минимум в WAL-файлах уже сброшенные из оперативы на диск.

Вот лог сервера:

2023-07-31 08:49:21.269 "database system was interrupted; last known up at 2023-07-31 08:13:20 MSK",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.269 "creating missing WAL directory ""pg_wal/archive_status""",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.731 "redo starts at C6/1A000028",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.739 "consistent recovery state reached at C6/1A0001A0",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.740 "invalid record length at C6/1B000060: wanted 24, got 0",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.740 "redo done at C6/1B000028 system usage",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.776 "checkpoint starting: end-of-recovery immediate",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.945 "checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 1 recycled; write=0.138 s, sync=0.001 s, total=0.174 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=16384 kB",,,,,,,,,"","startup",,0
2023-07-31 08:49:21.962 "database system is ready to accept connections",,,,,,,,,"","postmaster",,0

Здесь смущает запись end-of-recovery immediate - это не говорит о том, что все WAL-файлы он не стал воспроизводить, а только тот (те), которые помогли достичь консистентного состояния?

twistmind commented 1 year ago

Скорее всего проблема все-таки связана была с дефолтным портом в конфиге 2-ого инстанса, когда я первые бекапы делал. Если порт перед FULL-бекапом поменять на 5433, то проблемы, вроде как, нет. А вот если порт будет указан 1-ого инстанса, то будет происходить подобная фигня, даже несмотря на то, что путь к каталогу указан 2-ого инстанса.

Скорее всего все-таки это можно было бы устранить в утилите: запрет запуска бекапа, если указанный через аргумент порт не соответствует тому, который указан в postgresql.conf, что лежит в бекапируемом каталоге. Хоть это и пользовательская ошибка, но если подобное ведет к неправильному поведению, то можно относительно легко предотвратить.

Ишью можно закрыть, если вопросов нет.