После восстановления нет нужной таблицы, однако после выполнения DDL-команды, она появляется
twistmind opened this issue · 3 comments
Доброго времени суток!
Для снятия бекапов и восстановления пользуюсь 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`
Список бекапов второго инстанса:

Конфиг второго инстанса:
#### 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
Здравствуйте, я подозреваю, что при восстановлении сервер не имеет доступа к wal архиву.
В конце восстановления сервер пишет в лог что-то вроде
redo done at 0/50001A0 system usage
если моя теория верна - в вашем случае этот lsn заканчивается до момента создания таблицы test_recovery.
При бекапе используется 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-файлы он не стал воспроизводить, а только тот (те), которые помогли достичь консистентного состояния?
Скорее всего проблема все-таки связана была с дефолтным портом в конфиге 2-ого инстанса, когда я первые бекапы делал. Если порт перед FULL-бекапом поменять на 5433, то проблемы, вроде как, нет. А вот если порт будет указан 1-ого инстанса, то будет происходить подобная фигня, даже несмотря на то, что путь к каталогу указан 2-ого инстанса.
Скорее всего все-таки это можно было бы устранить в утилите:
запрет запуска бекапа, если указанный через аргумент порт не соответствует тому, который указан в postgresql.conf, что лежит в бекапируемом каталоге. Хоть это и пользовательская ошибка, но если подобное ведет к неправильному поведению, то можно относительно легко предотвратить.
Ишью можно закрыть, если вопросов нет.