Kry*_*ble 7 postgresql triggers
我想放弃一个当前正在生产的触发因为它不再需要,但问题是当我尝试最简单的方法,这就像是
drop trigger <triggername> on <tablename>
Run Code Online (Sandbox Code Playgroud)
它造成巨大的桌锁,一切都冻结了!
触发器的作用是:
插入或更新行时,检查字段的内容,拆分它并填充另一个表.
我应该如何在不造成生产环境麻烦的情况下立即禁用(并在之后删除)?
提前致谢,对不起我的英文;)
Cra*_*ger 11
你可以尝试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;
Run Code Online (Sandbox Code Playgroud)
如果有人使用该表,脚本将在中止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;
Run Code Online (Sandbox Code Playgroud)
如果无法及时完成工作,这可以确保在短时间内中断.再次,我会定期运行它,直到它成功.
如果这两种方法都没有效果 - 比如说,由于很多长时间的交易 - 我可能只是接受了将其锁定一段时间的需要.我启动drop trigger然后我将pg_terminate_backend所有并发事务保持在表上的锁,以便他们的连接被删除,他们的事务终止.这样就drop trigger可以迅速进行,但代价是更大的破坏.如果您的应用程序编写得很好,您只能考虑这样的方法,这样他们就可以在连接丢失等瞬态错误上重试事务.
另一种可能的方法是通过直接修改系统目录来禁用(不丢弃)触发器.
| 归档时间: |
|
| 查看次数: |
1858 次 |
| 最近记录: |