On Fri, Jun 01, 2012 at 09:52:59AM -0400, Tom Lane wrote: > Bryan Murphy <bmurphy1...@gmail.com> writes: > > The old 9.0 cluster was created by ubuntu. In this cluster there was an > > ubuntu user with an oid of 10 and a postgres user with an oid of 16386. > > > The new 9.1 cluster was created with a custom build of postgres 9.1. This > > did not have an ubuntu user, and it had a postgres user with an oid of 10. > > OID 10 is the bootstrap superuser, which is created with the name of the > operating system user that ran initdb. So the above does not sound like > anything to do with custom vs stock builds, but with who did initdb. > > It seems that pg_upgrade needs a check to make sure that the bootstrap > superuser is named the same in old and new clusters.
[ Thread moved to hackers.] OK, I have studied this. First we preserve pg_authid.oid because oids are stored in pg_largeobject_metadata. Second, we dumpall all users, even the install user because (from pg_dumpall.c): * We dump CREATE ROLE followed by ALTER ROLE to ensure that the role * will acquire the right properties even if it already exists (ie, it * won't hurt for the CREATE to fail). This is particularly important * for the role we are connected as, since even with --clean we will * have failed to drop it. So, pg_upgrade has to strip out restoring the install user because that would cause an error on restore. That is done in dump.c::split_old_dump(). The problem is if the old and new install users have different oids, as the reporter verified. The attached patch adds checks to verify the the old/new servers have the same install-user oid. -- Bruce Momjian <br...@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + It's impossible for everything to be true. +
diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c new file mode 100644 index 465ecdd..ba81823 *** a/contrib/pg_upgrade/pg_upgrade.c --- b/contrib/pg_upgrade/pg_upgrade.c *************** *** 29,35 **** * We control all assignments of pg_enum.oid because these oids are stored * in user tables as enum values. * ! * We control all assignments of pg_auth.oid because these oids are stored * in pg_largeobject_metadata. */ --- 29,35 ---- * We control all assignments of pg_enum.oid because these oids are stored * in user tables as enum values. * ! * We control all assignments of pg_authid.oid because these oids are stored * in pg_largeobject_metadata. */ diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c new file mode 100644 index 2669c09..df77f53 *** a/contrib/pg_upgrade/check.c --- b/contrib/pg_upgrade/check.c *************** static void set_locale_and_encoding(Clus *** 16,22 **** static void check_new_cluster_is_empty(void); static void check_locale_and_encoding(ControlData *oldctrl, ControlData *newctrl); ! static void check_is_super_user(ClusterInfo *cluster); static void check_for_prepared_transactions(ClusterInfo *cluster); static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster); --- 16,22 ---- static void check_new_cluster_is_empty(void); static void check_locale_and_encoding(ControlData *oldctrl, ControlData *newctrl); ! static void check_is_super_user_get_oid(ClusterInfo *cluster); static void check_for_prepared_transactions(ClusterInfo *cluster); static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster); static void check_for_reg_data_type_usage(ClusterInfo *cluster); *************** check_old_cluster(bool live_check, char *** 69,75 **** /* * Check for various failure cases */ ! check_is_super_user(&old_cluster); check_for_prepared_transactions(&old_cluster); check_for_reg_data_type_usage(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); --- 69,75 ---- /* * Check for various failure cases */ ! check_is_super_user_get_oid(&old_cluster); check_for_prepared_transactions(&old_cluster); check_for_reg_data_type_usage(&old_cluster); check_for_isn_and_int8_passing_mismatch(&old_cluster); *************** check_new_cluster(void) *** 121,137 **** { set_locale_and_encoding(&new_cluster); get_db_and_rel_infos(&new_cluster); check_new_cluster_is_empty(); - check_for_prepared_transactions(&new_cluster); check_loadable_libraries(); - check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata); - if (user_opts.transfer_mode == TRANSFER_MODE_LINK) check_hard_link(); } --- 121,144 ---- { set_locale_and_encoding(&new_cluster); + check_locale_and_encoding(&old_cluster.controldata, &new_cluster.controldata); + get_db_and_rel_infos(&new_cluster); check_new_cluster_is_empty(); check_loadable_libraries(); if (user_opts.transfer_mode == TRANSFER_MODE_LINK) check_hard_link(); + + check_is_super_user_get_oid(&new_cluster); + /* We don't restore our own user, so both clusters better have equal user oids */ + if (old_cluster.user_oid != new_cluster.user_oid) + pg_log(PG_FATAL, + "Old and new cluster superusers have different values for pg_authid.oid"); + + check_for_prepared_transactions(&new_cluster); } *************** create_script_for_old_cluster_deletion(c *** 577,588 **** /* ! * check_is_super_user() * * Make sure we are the super-user. */ static void ! check_is_super_user(ClusterInfo *cluster) { PGresult *res; PGconn *conn = connectToServer(cluster, "template1"); --- 584,595 ---- /* ! * check_is_super_user_get_oid() * * Make sure we are the super-user. */ static void ! check_is_super_user_get_oid(ClusterInfo *cluster) { PGresult *res; PGconn *conn = connectToServer(cluster, "template1"); *************** check_is_super_user(ClusterInfo *cluster *** 591,597 **** /* Can't use pg_authid because only superusers can view it. */ res = executeQueryOrDie(conn, ! "SELECT rolsuper " "FROM pg_catalog.pg_roles " "WHERE rolname = current_user"); --- 598,604 ---- /* Can't use pg_authid because only superusers can view it. */ res = executeQueryOrDie(conn, ! "SELECT rolsuper, oid " "FROM pg_catalog.pg_roles " "WHERE rolname = current_user"); *************** check_is_super_user(ClusterInfo *cluster *** 599,604 **** --- 606,613 ---- pg_log(PG_FATAL, "database user \"%s\" is not a superuser\n", os_info.user); + cluster->user_oid = atooid(PQgetvalue(res, 0, 1)); + PQclear(res); PQfinish(conn); diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h new file mode 100644 index 26aa7bb..ef59c2b *** a/contrib/pg_upgrade/pg_upgrade.h --- b/contrib/pg_upgrade/pg_upgrade.h *************** typedef struct *** 230,235 **** --- 230,236 ---- char major_version_str[64]; /* string PG_VERSION of cluster */ uint32 bin_version; /* version returned from pg_ctl */ Oid pg_database_oid; /* OID of pg_database relation */ + Oid user_oid; /* OID of connected user */ char *tablespace_suffix; /* directory specification */ } ClusterInfo;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers