为什么我不能在 table 上并行执行 truncate 和 grant 语句?

Why can't I execute truncate and grant statement on a table in parallel?

我的用例是我需要在 table 上同时执行 GRANTTRUNCATE 语句。

示例场景:

当我尝试并行执行以下语句时(两个独立的终端):

while true; do psql -U <user> -d <database> -c 'GRANT select ON test1 TO <user>;'; done

while true; do psql -U <user> -d <database> -c 'TRUNCATE test1;'; done

我收到以下错误:

ERROR:  tuple concurrently updated

我不明白错误的原因。 TRUNCATE 语句与特权无关。那为什么我不能同时执行这些语句呢?

PostgreSQL 抱怨的并发更新不是对 table test1 的更新,而是对目录 table pg_class.

的更新

GRANTTRUNCATE 都必须更新 pg_class 中 table 的行,一个更改 relacl,另一个更改 relfilenode.

现在,虽然对正常 table 的更新受到锁定保护,但目录更新并非如此。他们使用某种“乐观锁定”,除了第一个并发修改之外的所有修改都会导致此错误。

现在你可以称这是一个错误,但我要说的是,如果你的应用程序中有足够多的并发 GRANTTRUNCATE 语句,这就会成为一个问题,那么申请。

您可能会发现 Tom Lane 的 this e-mail 在这个主题上很有启发性。