为什么我不能在 table 上并行执行 truncate 和 grant 语句?
Why can't I execute truncate and grant statement on a table in parallel?
我的用例是我需要在 table 上同时执行 GRANT
和 TRUNCATE
语句。
示例场景:
当我尝试并行执行以下语句时(两个独立的终端):
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
.
的更新
GRANT
和 TRUNCATE
都必须更新 pg_class
中 table 的行,一个更改 relacl
,另一个更改 relfilenode
.
现在,虽然对正常 table 的更新受到锁定保护,但目录更新并非如此。他们使用某种“乐观锁定”,除了第一个并发修改之外的所有修改都会导致此错误。
现在你可以称这是一个错误,但我要说的是,如果你的应用程序中有足够多的并发 GRANT
和 TRUNCATE
语句,这就会成为一个问题,那么申请。
您可能会发现 Tom Lane 的 this e-mail 在这个主题上很有启发性。
我的用例是我需要在 table 上同时执行 GRANT
和 TRUNCATE
语句。
示例场景:
当我尝试并行执行以下语句时(两个独立的终端):
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
.
GRANT
和 TRUNCATE
都必须更新 pg_class
中 table 的行,一个更改 relacl
,另一个更改 relfilenode
.
现在,虽然对正常 table 的更新受到锁定保护,但目录更新并非如此。他们使用某种“乐观锁定”,除了第一个并发修改之外的所有修改都会导致此错误。
现在你可以称这是一个错误,但我要说的是,如果你的应用程序中有足够多的并发 GRANT
和 TRUNCATE
语句,这就会成为一个问题,那么申请。
您可能会发现 Tom Lane 的 this e-mail 在这个主题上很有启发性。