Восстановление данных PostgreSQL после потери pg_control

от автора

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

Данные в журнал пишутся до того как пользователь базы данных получит сообщение об успешном применении изменений. Этот журнал называется журналом упреждающей записи (Write-Ahead Log или просто WAL), а файлы журнала хранятся в каталоге pg_xlog. Также периодически PostgreSQL сбрасывает измененные аккумулированные данные из буферного кэша на диск. Этот процесс согласования данных называется контрольной точкой (checkpoint). Контрольная точка выполняется также при каждом штатном выключении экземпляра PostgreSQL.

Информация о том, с какими внутренними значениями завершилась контрольная точка, хранится в файле global/pg_control и потому этот файл должен быть доступен СУБД еще до момента восстановления данных. Если PostgreSQL отключается нештатно, то изменения из файлов журнала (pg_xlog) применяются к файлам БД, начиная с позиции последней контрольной точки. Этот процесс называется восстановлением данных.

В файле pg_control находится информация:

  • версия формата control-файла,
  • контрольная сумма записанных в этот файл данных,
  • версия формата файлов БД,
  • уникальный идентификатор экземпляра БД,
  • текущее состояние: работает/остановлен,
  • позиция в журнале, соответствующая запущенной и предыдущей контрольным точкам,
  • текущая ветвь времени (timeline),
  • максимальный видимый номер транзакции (xid),
  • максимальный номер внутреннего счетчика объектов (oid),
  • время создания,
  • и многое другое.

Посмотреть содержимое pg_control можно при помощи утилиты pg_controldata:

$ pg_controldata /var/lib/pgsql/9.5/data  pg_control version number:            942 Catalog version number:               201510051 Database system identifier:           6242923005164171508 Database cluster state:               in production pg_control last modified:             Fri Apr 29 01:00:00 2016 Latest checkpoint location:           EEAF/BAA5520 Prior checkpoint location:            EEAF/BAA5440 ... Latest checkpoint's NextXID:          7/876524573 Latest checkpoint's NextOID:          264355612 Latest checkpoint's NextMultiXactId:  134512401 Latest checkpoint's NextMultiOffset:  547842659 ...

Если содержимое pg_control было потеряно, то PostgreSQL не сможет запустить процедуру восстановления. Если же случилось так, что файлы БД неожиданно пропали, что может произойти при аварийном отключении с параметром fsync=off, то правильным способом восстановления является переключение на резервную копию. Эта статья может быть полезна в тех случаях, когда нужно в минимальные сроки восстановить работоспособность базы, но невозможно переключиться на резервную копию и можно пожертвовать частью данных.

Файл pg_control не защищен от сбоев, и восстановить его можно только при помощи утилиты pg_resetxlog или hex-редактором. Используя pg_resetxlog, вы можете потерять часть данных. Вы отказываетесь от всех текущих журналов транзакций и считаете, что PostgreSQL завершил свою работу штатно: все данные записаны в файлы, как будто только что завершилась контрольная точка. Вам также придется выбрать максимальный видимый номер счетчика транзакций. Если вы выберете номер транзакции слишком большим, то в файлах данных не окажется информации, которую СУБД еще не сбросила на диск из оперативной памяти, как это сделал бы процесс контрольной точки. Если же вы выберете номер транзакции слишком маленьким, то данные, записанные позднее, окажутся невидимыми.

Логично выбрать момент контрольной точки, но откуда можно достать это значение? На помощь приходит штатная утилита pg_xlogdump, которой можно посмотреть содержимое WAL-файлов. Вам необходимо выбрать самый свежий файл, в котором находится запись о контрольной точке, с типом записи XLOG:

$ pg_xlogdump -r XLOG pg_xlog/$FILE ... rmgr: XLOG        len (rec/tot):     80/   106, tx:          0, lsn: EEAF/0BAA5B40, prev EEAF/0BAA5B08, desc: CHECKPOINT_ONLINE redo EEAF/BAA5B08; tli 2; prev tli 2; fpw true; xid 7/876524573; oid 264355612; multi 134512401; offset 547842659; oldest xid 686019718 in DB 16400; oldest multi 128391103 in DB 16400; oldest/newest commit timestamp xid: 0/0; oldest running xid 876524573; online 

В данном случае можно выбрать такие параметры для pg_resetxlog:

$ pg_resetxlog -x 876524573 -o 264355612 -m 134512401,128391103 -n /var/lib/pgsql/9.5/data

Чтобы указанная команда применила значения, вам необходимо запустить ее без ключа -n и с дополнительным ключом -f. Команда очистит содержимое каталога pg_xlog и запишет новые значения в файл pg_control. После этого вы сможете запустить PostgreSQL без восстановления данных.

Если для восстановления вы выбрали контрольную точку, то, чтобы не попасть в ситуацию, когда вытесненные данные из буферного кэша оказались записанными в файлы БД, рекомендуется до старта экземпляра выставить значение параметра autovacuum=off и снять логическую резервную копию при помощи утилиты pg_dump. Если при снятии резервной копии возникают ошибки, то воспользуйтесь параметром zero_damaged_pages=on. После снятия логического резервной копии её необходимо восстановить на новом экземпляре PostgreSQL.

Всем успешной эксплуатации PostgreSQL и резервных копий под рукой!

ссылка на оригинал статьи https://habrahabr.ru/post/282770/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *