繁体   English   中英

PostgreSQL:具有GRANT / DROP角色的可序列化事务

[英]PostgreSQL: Serializable transactions with GRANT/DROP role

我一直在阅读Postgres中关于可序列化事务的很多内容,但遇到了一个我无法解决的问题。 假设我有两个来自不同psql进程的Postgres会话A和B,并且在开始任何事务之前,我创建角色role1role2

myuser=# CREATE ROLE role1 ;
CREATE ROLE
myuser=# CREATE ROLE role2 ;
CREATE ROLE

此时,我可以通过myuser=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE ;在两个会话中启动事务myuser=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE ; 并通过SELECT * FROM pg_catalog.pg_roles;验证两个会话是否同时看到这两个角色SELECT * FROM pg_catalog.pg_roles;

让我们假设我从会话B中删除角色role2 ,验证它没有显示并提交:

myuser=# DROP ROLE role2 ;
DROP ROLE
myuser=# SELECT * FROM pg_catalog.pg_roles;
                    rolname                    | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig |  oid
-----------------------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
 role1                                         | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 16563
myuser=# commit ;
COMMIT

现在,让我们回到会议A:

即使在删除了role2并在会话B中提交之后,我们仍然可以看到会话A中的事务仍然看到两个角色(正如预期的那样,因为这是可序列化的):

myuser=# SELECT * FROM pg_catalog.pg_roles;
                    rolname                    | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig |  oid
-----------------------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+------
 role1                                         | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 16563
 role2                                         | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 16564

现在,让我们尝试GRANT命令。 这是奇怪的部分:

myuser=# GRANT role2 TO role1 ;
ERROR:  role "role2" does not exist

在运行GRANT之前,我们可以看到角色role1role2存在,但现在我们看到了这样的错误。 这是为什么?

谢谢!

对于“正常”(即非目录)表,这样的冲突操作会导致序列化错误 虽然可序列化事务看到数据库的旧状态,但任何修改已更改的值的尝试都会导致此类错误。

这种情况的不同之处在于存储角色和角色成员资格的表( pg_authidpg_auth_members )是目录表 (甚至是共享目录,因为角色适用于所有数据库),并且这些处理和错误消息略有不同。

即使错误消息令人惊讶,操作失败也是必要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM