删除了触发器以弹性的方式我在寻找一个目前在生产触发下降,因为它不再是必要的,但问题是,当我尝试最简单的方式,这是一样的东西如何在PostgreSQL的
drop trigger <triggername> on <tablename>
它造成了一个巨大的表锁,一切都冻结了!
什么触发的作用是:
当行被插入或更新,检查一个字段的内容,将它和填充另一个表。
我应该如何立即停用(并在此后放弃),而不会在生产环境中造成麻烦?
在此先感谢和我的英语很抱歉;)
删除了触发器以弹性的方式我在寻找一个目前在生产触发下降,因为它不再是必要的,但问题是,当我尝试最简单的方式,这是一样的东西如何在PostgreSQL的
drop trigger <triggername> on <tablename>
它造成了一个巨大的表锁,一切都冻结了!
什么触发的作用是:
当行被插入或更新,检查一个字段的内容,将它和填充另一个表。
我应该如何立即停用(并在此后放弃),而不会在生产环境中造成麻烦?
在此先感谢和我的英语很抱歉;)
你可以尝试ALTER TABLE ... DISABLE TRIGGER
- 但它需要锁定的相同的强度,所以我不认为它会做你多好。
在PostgreSQL 9.4中有一些工作使ALTER TABLE
对某些操作采取较弱的锁定。这可能对此有所帮助。与此同时,我想CREATE OR REPLACE FUNCTION
用一个简单的无操作功能代替触发器。
然后,为了真正删除触发器,我可能会写一个脚本,做:
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
迅速进行,代价是更大的中断。如果你的应用程序编写得很好,你只能考虑这种方法,这样他们只会在连接丢失等瞬时错误时重试事务。
另一种可能的方法是通过直接修改系统目录来禁用(不丢弃)触发器。
我想你的第二个SQL语句中的NOWAIT是一个错误。 –
不错,非常感谢您的完整答案!我会尽快尝试,但所提供的信息很棒,包含了我需要的方法!真棒! – Krynble
只需添加一个便条,我就可以运行查询,它的功能就像一个魅力!即时下降触发器完全弹性!非常感谢! – Krynble