From: | Floris Van Nee <florisvannee(at)Optiver(dot)com> |
---|---|
To: | "pgsql-bugs(at)lists(dot)postgresql(dot)org" <pgsql-bugs(at)lists(dot)postgresql(dot)org> |
Cc: | Ferdi Smit <FerdiSmit(at)Optiver(dot)com> |
Subject: | incorrect pg_dump output due to not handling dropped roles correctly |
Date: | 2019-11-15 09:01:23 |
Message-ID: | 1573808483712.96817@Optiver.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
I noticed I wasn't able to apply my usual pg_dump schema output without errors anymore after I dropped some roles. After some digging, I found it has to do with Postgres not correctly updating the pg_init_privs table upon dropping roles. I can reproduce a similar scenario with the following steps (output from v13devel, but AFAIK all versions affected, I ran into the issue on v11.2):
postgres=# create role test;
CREATE ROLE
postgres=# alter default privileges in schema public grant all privileges on tables to test;
ALTER DEFAULT PRIVILEGES
postgres=# create extension pg_stat_statements;
CREATE EXTENSION
postgres=# select * from pg_catalog.pg_init_privs
where objoid=(select 'pg_stat_statements'::regclass);
objoid | classoid | objsubid | privtype | initprivs
--------+----------+----------+----------+-------------------------------------------------------------------------------
16409 | 1259 | 0 | e | {florisvannee=arwdDxt/florisvannee,test=arwdDxt/florisvannee,=r/florisvannee}
(1 row)
postgres=# drop owned by test;
DROP OWNED
postgres=# drop role test;
DROP ROLE
postgres=# select * from pg_catalog.pg_init_privs
where objoid=(select 'pg_stat_statements'::regclass);
objoid | classoid | objsubid | privtype | initprivs
--------+----------+----------+----------+--------------------------------------------------------------------------------
16409 | 1259 | 0 | e | {florisvannee=arwdDxt/florisvannee,16404=arwdDxt/florisvannee,=r/florisvannee}
(1 row)
If we do a pg_dump on this, there'll be a line like this in the output:
REVOKE ALL ON TABLE public.pg_stat_statements FROM "16404";
This fails when restoring, because there's no role '16404'.
Can I manually fix this by updating pg_init_privs catalog table? Eg. in the example, I could run something like?
update pg_catalog.pg_init_privs
set initprivs=(select array_agg(p) from unnest(initprivs) p where not (p::text like '16404%'))
where initprivs <> (select array_agg(p) from unnest(initprivs) p where not (p::text like '16404%'))
;
Dropping/recreating the extension seems to work too, but I'd like to avoid that if possible (that may be a solution for pg_stat_statements, but isn't necessarily possible for every extension).
I'm pretty sure I once ran into a similar issue before, when doing a pg_upgrade in-place from 10 to 11. I couldn't run pg_upgrade until - back then I fixed it by dropping/recreating the extension, but didn't know exactly what was causing it, so I didn't report it here. From glancing at the code, this seems to be following some similar code paths in dump/restore. Just so you know the impact may not be limited to manual pg_dump actions, but also potentially pg_upgrade if my memory is correct.
-Floris
From | Date | Subject | |
---|---|---|---|
Next Message | Thomas Butz | 2019-11-15 09:03:48 | Re: BUG #16095: Segfault while executing trigger |
Previous Message | Juan José Santamaría Flecha | 2019-11-15 08:14:59 | Re: BUG #16108: Colorization to the output of command-line has unproperly behaviors at Windows platform |