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

时间:2017-09-25 04:00:43

标签: postgresql concurrentmodification

我的用例是我需要同时在表上执行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语句与权限无关。那为什么我不能同时执行这些语句呢?

1 个答案:

答案 0 :(得分:4)

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

GRANTTRUNCATE都必须更新pg_class中的表格行,一行更改relacl,另一行更改relfilenode

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

现在您可以将此称为错误,但我要说如果您的应用程序中有足够的并发GRANTTRUNCATE语句,这就成了一个问题,那么就会出现问题。该应用程序有问题。

你可能会发现Tom Lane this e-mail对这个问题很有启发性。