Как удалить триггер устойчивым образом в postgresql

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

drop trigger <triggername> on <tablename>

это вызвало огромный замок стола, и все замерло!

триггер делает следующее:

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

Как я должен приступить к мгновенно отключить (и падение после этого) без причинять перебранку в нашей производственной среде?

спасибо заранее и извините за мой английский ;)

1 ответов


вы могли бы попробовать ALTER TABLE ... DISABLE TRIGGER - но для этого требуется такая же сила замка, поэтому я не думаю, что это принесет вам много пользы.

в PostgreSQL 9.4 есть работа, чтобы сделать ALTER TABLE возьмите более слабые блокировки для некоторых операций. Это может помочь.

тем временем, я бы CREATE OR REPLACE FUNCTION для замены триггера простой функцией no-op.

тогда, чтобы фактически сбросить триггер, я, вероятно, напишу сценарий, который делает:

BEGIN;
LOCK TABLE the_table IN ACCESS EXCLUSIVE MODE NOWAIT;
DROP TRIGGER ...;
COMMIT;

если кто-нибудь использует таблица, которую скрипт прервет при LOCK TABLE.

затем я запустил его в цикле, пока он не преуспел.

если это не сработало (если таблица всегда занят), но если большинство транзакций были действительно короткими, я мог бы попытаться LOCK TABLE без NOWAIT, но установите короткий statement_timeout. Таким образом, сценарий будет чем-то вроде:

BEGIN;
SET LOCAL statement_timeout = '5s';
LOCK TABLE the_table IN ACCESS EXCLUSIVE MODE NOWAIT;
DROP TRIGGER ...;
COMMIT;

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

если бы ни один из подходов не был эффективным-скажем, из-за множества длительных транзакций - я бы, вероятно, просто принял необходимость заблокировать его на некоторое время. Я бы начал drop trigger тогда я pg_terminate_backend все параллельные транзакции, которые содержали блокировки в таблице, поэтому их соединения упали и их транзакции завершились. Что бы drop trigger действуйте быстро, ценой больших разрушений. Вы можете рассмотреть такой подход, только если ваши приложения хорошо написаны, поэтому они будут просто повторять транзакции на временных ошибках, таких как падения соединения.

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