diff --git a/contrib/pg_upgrade/dump.c b/contrib/pg_upgrade/dump.c index 943ced96aef..633d5e678f5 100644 --- a/contrib/pg_upgrade/dump.c +++ b/contrib/pg_upgrade/dump.c @@ -12,10 +12,6 @@ #include "pg_upgrade.h" #include -#include "catalog/pg_authid.h" - -/* pick a OID that will never be used for TOAST tables */ -#define OPTIONALLY_CREATE_TOAST_OID BOOTSTRAP_SUPERUSERID void @@ -72,71 +68,3 @@ generate_old_dump(void) end_progress_output(); check_ok(); } - - -/* - * It is possible for there to be a mismatch in the need for TOAST tables - * between the old and new servers, e.g. some pre-9.1 tables didn't need - * TOAST tables but will need them in 9.1+. (There are also opposite cases, - * but these are handled by setting binary_upgrade_next_toast_pg_class_oid.) - * - * We can't allow the TOAST table to be created by pg_dump with a - * pg_dump-assigned oid because it might conflict with a later table that - * uses that oid, causing a "file exists" error for pg_class conflicts, and - * a "duplicate oid" error for pg_type conflicts. (TOAST tables need pg_type - * entries.) - * - * Therefore, a backend in binary-upgrade mode will not create a TOAST - * table unless an OID as passed in via pg_upgrade_support functions. - * This function is called after the restore and uses ALTER TABLE to - * auto-create any needed TOAST tables which will not conflict with - * restored oids. - */ -void -optionally_create_toast_tables(void) -{ - int dbnum; - - prep_status("Creating newly-required TOAST tables"); - - for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) - { - PGresult *res; - int ntups; - int rowno; - int i_nspname, - i_relname; - DbInfo *active_db = &new_cluster.dbarr.dbs[dbnum]; - PGconn *conn = connectToServer(&new_cluster, active_db->db_name); - - res = executeQueryOrDie(conn, - "SELECT n.nspname, c.relname " - "FROM pg_catalog.pg_class c, " - " pg_catalog.pg_namespace n " - "WHERE c.relnamespace = n.oid AND " - " n.nspname NOT IN ('pg_catalog', 'information_schema') AND " - "c.relkind IN ('r', 'm') AND " - "c.reltoastrelid = 0"); - - ntups = PQntuples(res); - i_nspname = PQfnumber(res, "nspname"); - i_relname = PQfnumber(res, "relname"); - for (rowno = 0; rowno < ntups; rowno++) - { - /* enable auto-oid-numbered TOAST creation if needed */ - PQclear(executeQueryOrDie(conn, "SELECT binary_upgrade.set_next_toast_pg_class_oid('%d'::pg_catalog.oid);", - OPTIONALLY_CREATE_TOAST_OID)); - - /* dummy command that also triggers check for required TOAST table */ - PQclear(executeQueryOrDie(conn, "ALTER TABLE %s.%s RESET (binary_upgrade_dummy_option);", - quote_identifier(PQgetvalue(res, rowno, i_nspname)), - quote_identifier(PQgetvalue(res, rowno, i_relname)))); - } - - PQclear(res); - - PQfinish(conn); - } - - check_ok(); -} diff --git a/contrib/pg_upgrade/pg_upgrade.c b/contrib/pg_upgrade/pg_upgrade.c index 464ba98a653..9b757129a88 100644 --- a/contrib/pg_upgrade/pg_upgrade.c +++ b/contrib/pg_upgrade/pg_upgrade.c @@ -525,13 +525,11 @@ create_new_objects(void) /* * We don't have minmxids for databases or relations in pre-9.3 - * clusters, so set those after we have restores the schemas. + * clusters, so set those after we have restored the schema. */ if (GET_MAJOR_VERSION(old_cluster.major_version) < 903) set_frozenxids(true); - optionally_create_toast_tables(); - /* regenerate now that we have objects in the databases */ get_db_and_rel_infos(&new_cluster); diff --git a/contrib/pg_upgrade/pg_upgrade.h b/contrib/pg_upgrade/pg_upgrade.h index 876a0d16bae..be087cf8cd3 100644 --- a/contrib/pg_upgrade/pg_upgrade.h +++ b/contrib/pg_upgrade/pg_upgrade.h @@ -333,7 +333,6 @@ void disable_old_cluster(void); /* dump.c */ void generate_old_dump(void); -void optionally_create_toast_tables(void); /* exec.c */ diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index bfafcac2523..cbac4dd037f 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -20,7 +20,6 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" -#include "catalog/pg_authid.h" #include "catalog/pg_namespace.h" #include "catalog/pg_opclass.h" #include "catalog/pg_type.h" @@ -40,9 +39,6 @@ static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptions); static bool needs_toast_table(Relation rel); -/* pick a OID that will never be used for TOAST tables */ -#define OPTIONALLY_CREATE_TOAST_OID BOOTSTRAP_SUPERUSERID - /* * AlterTableCreateToastTable @@ -154,50 +150,38 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio if (rel->rd_rel->reltoastrelid != InvalidOid) return false; + /* + * Check to see whether the table actually needs a TOAST table. + */ if (!IsBinaryUpgrade) { + /* Normal mode, normal check */ if (!needs_toast_table(rel)) return false; } else { /* - * Check to see whether the table needs a TOAST table. + * In binary-upgrade mode, create a TOAST table if and only if + * pg_upgrade told us to (ie, a TOAST table OID has been provided). * - * If an update-in-place TOAST relfilenode is specified, force TOAST file - * creation even if it seems not to need one. This handles the case - * where the old cluster needed a TOAST table but the new cluster - * would not normally create one. + * This indicates that the old cluster had a TOAST table for the + * current table. We must create a TOAST table to receive the old + * TOAST file, even if the table seems not to need one. + * + * Contrariwise, if the old cluster did not have a TOAST table, we + * should be able to get along without one even if the new version's + * needs_toast_table rules suggest we should have one. There is a lot + * of daylight between where we will create a TOAST table and where + * one is really necessary to avoid failures, so small cross-version + * differences in the when-to-create heuristic shouldn't be a problem. + * If we tried to create a TOAST table anyway, we would have the + * problem that it might take up an OID that will conflict with some + * old-cluster table we haven't seen yet. */ - - /* - * If a TOAST oid is not specified, skip TOAST creation as we will do - * it later so we don't create a TOAST table whose OID later conflicts - * with a user-supplied OID. This handles cases where the old cluster - * didn't need a TOAST table, but the new cluster does. - */ - if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid)) + if (!OidIsValid(binary_upgrade_next_toast_pg_class_oid) || + !OidIsValid(binary_upgrade_next_toast_pg_type_oid)) return false; - - /* - * If a special TOAST value has been passed in, it means we are in - * cleanup mode --- we are creating needed TOAST tables after all user - * tables with specified OIDs have been created. We let the system - * assign a TOAST oid for us. The tables are empty so the missing - * TOAST tables were not a problem. - */ - if (binary_upgrade_next_toast_pg_class_oid == OPTIONALLY_CREATE_TOAST_OID) - { - /* clear as it is not to be used; it is just a flag */ - binary_upgrade_next_toast_pg_class_oid = InvalidOid; - - if (!needs_toast_table(rel)) - return false; - } - - /* both should be set, or not set */ - Assert(OidIsValid(binary_upgrade_next_toast_pg_class_oid) == - OidIsValid(binary_upgrade_next_toast_pg_type_oid)); } /*