Вопрос или проблема
Я не уверен, как я попал в эту ситуацию, но недавно наше приложение не может удалить ни одной строки из одной конкретной таблицы. Я проверил, и мы не можем даже удалить ее из оболочки 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
Заключение
В вашем случае, так как проблема была решена добавлением или изменением триггера, это подтверждает, что именно триггеры могут блокировать операции удаления. В будущем, когда вы будете сталкиваться с подобными ошибками и проблемами с удалением, проверка триггеров и ограничений должна стать частью вашего стандартного диагностического процесса.
Если возникнут дополнительные вопросы или проблемы, пожалуйста, дайте знать.