PostgreSQL: Serializable Transactions with the GRANT / DROP Role

I read a lot about serializable transactions in Postgres, but ran into a problem that I could not solve. Suppose I have two Postgres A and B sessions from different psql processes and that before starting any transactions I create roles role1androle2

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

At this point, I can start transactions in both sessions through myuser=# BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE ;and make sure that both sessions see both roles, throughSELECT * FROM pg_catalog.pg_roles;

Suppose I drop the role role2from session B, make sure it is not shown and not committed:

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

Now back to session A:

Even after deleting role2and committing inside session B, we can still see that the transaction in session A still sees both roles (as expected, since it is serializable):

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 , role1 role2, ​​. ?

!

+4
1

"" (.. ) , , . , , , .

, , (pg_authid pg_auth_members), ( , ), .

, , .

+3

Source: https://habr.com/ru/post/1689590/


All Articles