【问题标题】:A bug in PostgreSQL suppress_redundant_updates_trigger?PostgreSQL suppress_redundant_updates_trigger 中的错误?
【发布时间】:2020-09-09 15:53:34
【问题描述】:

我在 PostgreSQL 中研究一组触发器,我想我偶然发现了内置函数/触发器 suppress_redundant_updates_trigger() 上的一个错误。它在我的配置(我的笔记本电脑上的 PostgreSQL 12)上完全可以重现。

首先我建立了一个表格,有两个“每行之前”触发器:

CREATE TABLE test (id int, val text);
INSERT INTO test VALUES (1, 'one'), (2, 'two');

CREATE OR REPLACE FUNCTION am_i_touched() RETURNS trigger LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
    RAISE NOTICE 'Yes, I am touched!';
    RETURN NEW;
END;
$BODY$;

CREATE TRIGGER az_test_suppress_redundant_update
    BEFORE UPDATE ON public.test
    FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();

-- Make sure trigger name is after the previous one 
-- in alphabetical order as it drives execution order
CREATE TRIGGER bz_am_I_touched
    BEFORE UPDATE ON public.test 
    FOR EACH ROW EXECUTE PROCEDURE am_i_touched();

然后我运行UPDATE test SET id = 1 WHERE id = 1。正如预期的那样,更新被第一个触发器抑制,因为该行保持不变,并且bz_am_i_touched() 永远不会触发。到目前为止一切顺利。

然后我跑了:

ALTER TABLE test ADD COLUMN newcol int

现在,我再次运行UPDATE test SET id = 1 WHERE id = 1...这一次,更新没有被禁止,bz_am_i_touched() 触发! PGAdmin (v4) 报告更新了一条记录,而不是像以前那样为零!

这是一次性事件。进一步UPDATE test SET id = 1 WHERE id = 1 按预期工作...但后来我尝试UPDATE test SET id = 2 WHERE id = 2...又出现了这种奇怪的行为 - 更新没有被禁止。

这是预期的行为吗?我不明白UPDATE test SET id = 1 WHERE id = 1 是如何导致更新不被禁止的。

【问题讨论】:

  • 听起来很可疑。您应该将其作为错误报告给 PostgreSQL。
  • 是的,我现在正在这样做......这并不像看起来那么牵强,因为许多与审计相关的设置都在精确地向表中添加列以及定义触发器。 ..这就是我正在做的事情。

标签: postgresql triggers postgresql-12


【解决方案1】:

newcol NULL 值的表示方式在新元组和旧元组之间是不同的。因此它们不被认为是相同的,因此不会抑制更新。

将元组与 memcmp 进行总体比较,因此即使是用户不可见的字节也会发现显着差异。它不会遍历每个字段,就哪些差异在语义上有意义做出单独的依赖于类型的决定。为了速度和简单性,这似乎是故意的。我怀疑这会被认为是一个错误。

【讨论】:

  • 感谢您的澄清。不幸的是,在设置非常标准的审计程序时,在设置触发器的同时向表中添加额外的列是很常见的:(。所以这个问题并不像人们想象的那么模糊。
  • 再想一想,我同意 Jeff 的观点:跳过不必要的更新固然不错,但不是必需的,因此,如果在添加列时执行一次更新并物理元组发生变化。毕竟,它只是一个性能特性,因此触发速度快很重要。
  • 嗨劳伦兹。当用作审计或归档功能的一部分时,它绝不仅仅是一种性能功能。触发器不会像在 table mods 之后宣传的那样工作,通常与您在实施审计程序时所做的类型完全相同。我使用标准的“NEW IS DISTINCT FROM OLD”运算符替换了它,相比之下,它像宣传的那样工作。在我的例子中,更改的记录会进入审计跟踪,并且自动化的第 3 方工具会定期更新数百万行,只针对十几个“真实”更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 2020-07-25
  • 2010-12-26
  • 2012-11-04
相关资源
最近更新 更多