Ошибка Postgres “Удаление в ожидании, будет заблокировано” неверна, но не может быть устранена.

Вопрос или проблема

Я не уверен, как я попал в эту ситуацию, но недавно наше приложение не может удалить ни одной строки из одной конкретной таблицы. Я проверил, и мы не можем даже удалить ее из оболочки psql. Вот ошибка:

vnms=# delete from alarm_action where id = 12345678;
ERROR:  Удаление ожидается, будет заблокировано

(12345678 — это недействительный, несуществующий ID. Ошибка возвращается мгновенно без паузы)

Мне кажется, что существует некий маркер “Удаление ожидается”, связанный с таблицей alarm_action, потому что я могу без проблем удалять строки из других таблиц. Но я не уверен, где находится этот маркер. Я пытался безуспешно найти сообщение об ошибке в Интернете. Затем я попробовал скачать исходный код postgresql с github, но также не нашел этого сообщения об ошибке.

Я также:

  • Перезагрузил postgres, изменений нет.
  • Переименовал базу данных в другое имя, изменений нет.
  • Сделал резервную копию, затем удалил базу данных, создал новую базу данных и восстановил резервную копию в нее. Это обновляет все oid, но сообщение об ошибке остается.
  • В то же время я вижу ту же ошибку, если удаляю из таблицы alarm_action как в старой (но переименованной) базе данных, так и в новой базе данных. Поскольку у них разные oid, похоже, что постоянство не связано с oid.
  • Я проверил pg_stat_activity, он пуст.
  • Я проверил pg_locks, все блокировки учтены. Я даже насильно удалил все блокировки с помощью pg_terminate_backend(). Это обновляет все pid и oid блокировок, но ошибка остается прежней. Это говорит о том, что ошибка не связана с pg_locks.

Ошибка “Удаление ожидается” тоже странная, потому что она конкретно касается какого-то удаления. Если это просто блокировка, она либо повиснет на некоторое время (в ожидании блокировки), либо вернет что-то вроде “Не удалось получить блокировку”.

У кого-нибудь есть идеи, о чем это сообщение “Удаление ожидается, будет заблокировано”? Как это отслеживается и как его можно разблокировать? Спасибо.

ETA: это теперь решено. Я выяснил, что кто-то в нашей команде добавил триггер, который неправильно блокирует удаление.

Ответ или решение

На основании вашего описания проблемы с ошибкой "Delete is pending, will be blocked", можно сделать вывод о нескольких возможных причинах и решениях.

1. Причина ошибки

Ошибка "Delete is pending, will be blocked" в PostgreSQL может возникать в результате наличия триггеров или ограничений, которые контролируют операции удаления. Это не является стандартной ошибкой, связаной с блокировками или замедлением работы базы данных. Все операции с базами данных в PostgreSQL выполняются в контексте транзакции, и если триггер или ограничение блокирует выполнение операции, может возникать сообщение о том, что удаление ожидает завершения.

2. Проверьте наличие триггеров

Если вы еще не сделали этого, вам стоит проверить наличие триггеров на таблице alarm_action:

SELECT tgname
FROM pg_trigger
WHERE tgrelid = 'alarm_action'::regclass;

Если триггеры существуют, вы можете получить информацию о том, какие действия они выполняют, просматривая информацию о триггерах через команду:

SELECT * 
FROM pg_trigger 
WHERE tgrelid = 'alarm_action'::regclass;

3. Удаление или модификация триггеров

Если вы обнаружите триггер, который блокирует операцию удаления, вы можете либо временно отключить его, либо изменить его логику. Чтобы отключить триггер, используйте следующее:

ALTER TABLE alarm_action DISABLE TRIGGER trigger_name;

Для повторного включения используйте:

ALTER TABLE alarm_action ENABLE TRIGGER trigger_name;

4. Проверка ограничений

Также стоит проверить существование ограничений (например, внешние ключи), которые могут блокировать удаление. Выполните:

SELECT conname
FROM pg_constraint
WHERE conrelid = 'alarm_action'::regclass;

Если вы найдете ограничения, рассмотрите возможность их временного отключения для проведения операций удаления.

5. Проверка прав доступа

Убедитесь, что у пользователя, выполняющего операцию удаления, есть необходимые права доступа на эту таблицу:

\dp alarm_action

Заключение

В вашем случае, так как проблема была решена добавлением или изменением триггера, это подтверждает, что именно триггеры могут блокировать операции удаления. В будущем, когда вы будете сталкиваться с подобными ошибками и проблемами с удалением, проверка триггеров и ограничений должна стать частью вашего стандартного диагностического процесса.

Если возникнут дополнительные вопросы или проблемы, пожалуйста, дайте знать.

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

Капча загружается...