Мы начали ALTER TABLE
запрос несколько часов назад и только недавно поняли (через pg_stat_activity
), что он ожидает блокировки. Мы обнаружили другой запрос, который удерживает блокировку таблицы, которую мы хотим изменить, и не отпускает ее.
Наш запрос является «простым» запросом (изменяющим тип данных столбца), но он выполняется для массивной таблицы.
Вместо того, чтобы убивать процесс, который держит блокировку, мы решили, что лучше убить ALTER TABLE
.
Мы не завернули ALTER TABLE
в транзакции.
Насколько я понимаю, тот факт, что наш запрос ожидает блокировки, означает, что он всегда ожидал блокировки и никогда ничего не менял.
Это правда? Безопасно ли нам сразу отменить наш ALTER TABLE
запрос? Или возможно, что запрос уже изменил что-то, и его отмена оставила бы нашу базу данных в каком-то наполовину состоянии?
PS: план состоит в том, чтобы отменить его с помощью SELECT pg_cancel_backend(pid);
. Если это плохая идея, пожалуйста, дайте мне знать.
источник
Ответы:
Правильно - если вы видите, что pg_stat_activity.waiting "true" для ALTER TABLE, это почти наверняка означает, что он терпеливо ожидает блокировки ACCESS EXCLUSIVE на своей целевой таблице и ее реальной работы (переписывает таблицу при необходимости, изменяет каталоги , восстановление индексов и т. д.) еще не началось.
Отмена запросов (или, что то же самое, откат транзакции) в PostgreSQL не имеет каких-либо рисков повреждения базы данных, которые вы могли бы напугать в некоторых других базах данных (например, ужасающее предупреждение внизу этой страницы). Вот почему пользователи, не являющиеся суперпользователями, в последних версиях могут свободно использовать
pg_cancel_backend()
иpg_terminate_backend()
уничтожать свои собственные запросы, выполняемые в других бэкэндах - их можно безопасно использовать, не беспокоясь о повреждении базы данных. В конце концов, PostgreSQL должен быть подготовлен к тому, чтобы справляться с любыми процессами, такими как SIGKILL от OOM killer, выключение сервера и т. Д. Вот для чего нужен журнал WAL .Возможно, вы также видели, что в PostgreSQL можно выполнять большинство команд DDL, вложенных в транзакцию (с несколькими операторами), например
(Потрясающе, если убедиться, что миграция схемы происходит либо вообще, либо вообще не происходит.) Однако вы сказали:
Это хорошо для одной команды - из документов ,
Поэтому отмена, что
ALTER TABLE
либо черезpg_cancel_backend()
Ctrl-C , либо из контрольной подсказки psql, будет иметь такой же эффект, как если бы вы сделали(хотя, как вы надеетесь, отмена этой дорогой процедуры
ALTER TABLE
может спасти базу данных от большого количества ненужных операций измельчения, если вы все равно собираетесьROLLBACK
.)источник
Чтобы уточнить правильный и превосходный ответ Джоша:
Да.
Было бы безопасно, даже если бы он был в процессе переписывания таблицы .
Если вы хотите, вы можете просто выключить весь сервер PostgreSQL или фактически машину, на которой он работает, перезапустить его, и все будет хорошо. DDL в PostgreSQL является транзакционным и безопасным при сбое.
Операции DDL регистрируются через WAL, и гарантируется, что их можно откатить или завершить после восстановления после сбоя или прерывания.
источник