I'm trying to upgrade PostgreSQL 12 cluster to version 13, with following script:
/usr/lib/postgresql/13/bin/pg_upgrade --check \
--old-datadir=/var/lib/postgresql/12/main \
--new-datadir=/var/lib/postgresql/13/main \
--old-bindir=/usr/lib/postgresql/12/bin \
--new-bindir=/usr/lib/postgresql/13/bin \
--old-options=' -c config_file=/etc/postgresql/12/main/postgresql.conf' \
--new-options=' -c config_file=/etc/postgresql/13/main/postgresql.conf' \
--old-port=5432 \
--new-port=5433
The check returns:
*Clusters are compatible*
However during the actual upgrade the process fails miserably due to pg_catalog.pg_pltemplate
table:
pg_restore: creating ACL "pg_catalog.TABLE "pg_pltemplate""
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 17728; 0 0 ACL TABLE "pg_pltemplate" postgres
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_pltemplate" does not exist
It appears to be an old issue, however the upgrade script does not check these templates.
So far it appears that this query should return an empty result, otherwise you're in troubles:
$ psql -c "SELECT * FROM information_schema.role_table_grants WHERE table_name='pg_pltemplate';"
grantor | grantee | table_catalog | table_schema | table_name | privilege_type | is_grantable | with_hierarchy
----------+----------+---------------+--------------+---------------+----------------+--------------+----------------
postgres | postgres | postgres | pg_catalog | pg_pltemplate | TRIGGER | YES | NO
postgres | postgres | postgres | pg_catalog | pg_pltemplate | REFERENCES | YES | NO
postgres | postgres | postgres | pg_catalog | pg_pltemplate | TRUNCATE | YES | NO
postgres | postgres | postgres | pg_catalog | pg_pltemplate | DELETE | YES | NO
postgres | postgres | postgres | pg_catalog | pg_pltemplate | UPDATE | YES | NO
postgres | postgres | postgres | pg_catalog | pg_pltemplate | SELECT | YES | YES
postgres | postgres | postgres | pg_catalog | pg_pltemplate | INSERT | YES | NO
postgres | PUBLIC | postgres | pg_catalog | pg_pltemplate | SELECT | NO | YES
REVOKING these privileges:
REVOKE SELECT ON "pg_catalog"."pg_pltemplate" FROM PUBLIC;
REVOKE ALL ON "pg_catalog"."pg_pltemplate" FROM postgres;
doesn't really help as the REVOKE
statement gets saved to schema:
pg_restore: error: could not execute query: ERROR: relation "pg_catalog.pg_pltemplate" does not exist
Command was: REVOKE ALL ON TABLE "pg_catalog"."pg_pltemplate" FROM "postgres";
REVOKE SELECT ON TABLE "pg_catalog"."pg_pltemplate" FROM PUBLIC;
this can be checked (also the result should be empty) using:
pg_dump --port 5432 --schema-only --quote-all-identifiers | grep pg_pltemplate
before performing the upgrade.
Any ideas how to get rid of the pg_catalog.pg_pltemplate
table altogether?
REVOKE
in a database that doesn't have a problem. The premise that your control query should return empty seems wrong. It should return exactly what you show in the question. I think what you need is the opposite: you should find and fix the databases that don't have these exact grants onpg_pltemplate
.