Я совершил неправильный оператор UPDATE
и потерял некоторые данные.
Можно ли откат сейчас, после того, как я уже сделал?
Любая помощь?
ROLLBACK
говорит NOTICE: there is no transaction in progress
.
Я совершил неправильный оператор UPDATE
и потерял некоторые данные.
Можно ли откат сейчас, после того, как я уже сделал?
Любая помощь?
ROLLBACK
говорит NOTICE: there is no transaction in progress
.
Нет, вы не можете отменить, откат или отмену фиксации.
(Примечание: если вы удалили каталог данных из файловой системы, НЕ останавливайте базу данных. Следующие рекомендации относятся к случайному завершению сценария DELETE
или подобного, а не сценария rm -rf /data/directory
).
Если эти данные были важны, ОСТАНОВИТЬ ВАШУ БАЗУ ДАННЫХ СЕЙЧАС и не перезапускать его. Используйте pg_ctl stop -m immediate
, чтобы контрольная точка не запускалась при завершении работы.
Вы не можете отменить транзакцию после ее совершения. Вам нужно будет восстановить данные из резервных копий или использовать восстановление по времени в момент времени, которое должно быть установлено до того, как произошел несчастный случай.
Если у вас не было никакого архивирования PITR/WAL, у вас нет резервных копий, у вас настоящие проблемы.
Как только ваша база данных будет остановлена, вы должны сделать уровень файловой системы всего каталога данных - папки, содержащей base
, pg_clog
и т.д. Скопируйте все это в новое место. Не делайте ничего с копией в новом месте, это единственная надежда на восстановление ваших данных, если у вас нет резервных копий. Сделайте другую копию на каком-либо съемном носителе, если сможете, а затем отключите это хранилище от компьютера. Помните, что вам нужна абсолютно каждая часть каталога данных, включая pg_xlog
и т.д. Никакая часть не имеет значения.
Точно как сделать копию зависит от операционной системы, в которой вы работаете. Где dir данных зависит от того, какая ОС вы работаете и как вы установили PostgreSQL.
Если вы быстро остановите свою БД, у вас может возникнуть надежда восстановить некоторые данные из таблиц. Это потому, что PostgreSQL использует multi-version concurrency control (MVCC) для управления одновременным доступом к его хранилищу. Иногда он будет писать новые версии строк, которые вы обновляете в таблице, оставляя старые на месте, но помеченные как "удаленные". Через некоторое время autovaccum появляется и помещает строки как свободное пространство, поэтому их можно перезаписать более поздними INSERT
или UPDATE
. Таким образом, старые версии строк UPDATE
d все еще могут находиться вокруг, присутствовать, но недоступны.
Кроме того, Pg записывается в две фазы. Первые данные записываются в журнал записи вперед (WAL). Только после того, как он был записан на WAL и ударил диск, он затем скопирован в "кучу" (основные таблицы), возможно, переписав старые данные, которые были там. Содержимое WAL копируется в основную кучу bgwriter
и периодическими контрольными точками. По умолчанию контрольные точки происходят каждые 5 минут. Если вам удастся остановить базу данных до того, как произойдет контрольная точка, и остановил ее, убив ее, потянув за вилку на машине или используя pg_ctl
в immediate
режиме, вы могли бы захватить данные до того, как произошел контрольный пункт, поэтому ваши старые данные с большей вероятностью будут находиться в куче.
Теперь, когда вы сделали полную копию данных dir на уровне файловой системы, вы можете запустить резервное копирование базы данных, если вам действительно нужно; данные все равно исчезнут, но вы сделали все возможное, чтобы дать себе некоторую надежду на его восстановление. Учитывая выбор, я бы, вероятно, оставил БД закрытым, чтобы быть в безопасности.
Теперь вам может понадобиться нанять эксперта в встроенных версиях PostgreSQL, чтобы помочь вам в попытке восстановления данных. Будьте готовы заплатить профессионалу за свое время, возможно, совсем немного времени.
Я разместил об этом в списке рассылки Pg, а Виктор Егоров связан с depesz post на pg_dirtyread, который похож на то, что вы хотите, хотя он не восстанавливает данные TOAST
ed, так что это ограниченная утилита. Попробуйте, если вам повезет, это может сработать.
Смотрите: pg_dirtyread на GitHub.
Я удалил то, что я написал в этом разделе, поскольку оно устарело этим инструментом.
См. также Основы хранения строк PostgreSQL
Смотрите мою запись в блоге Предотвращение повреждения базы данных PostgreSQL.
Если вы используете двухфазную фиксацию, вы могли бы ROLLBACK PREPARED
для трансмиссии, которая была подготовлена для совершать, но не полностью совершать. Что касается ближайшего, вы можете отменить уже совершенную транзакцию и не относится к вашей ситуации.