|
12 | 12 | #include "pg_upgrade.h"
|
13 | 13 |
|
14 | 14 | #include <sys/types.h>
|
| 15 | +#include "catalog/binary_upgrade.h" |
| 16 | + |
15 | 17 |
|
16 | 18 | void
|
17 | 19 | generate_old_dump(void)
|
@@ -67,3 +69,71 @@ generate_old_dump(void)
|
67 | 69 | end_progress_output();
|
68 | 70 | check_ok();
|
69 | 71 | }
|
| 72 | + |
| 73 | + |
| 74 | +/* |
| 75 | + * It is possible for there to be a mismatch in the need for TOAST tables |
| 76 | + * between the old and new servers, e.g. some pre-9.1 tables didn't need |
| 77 | + * TOAST tables but will need them in 9.1+. (There are also opposite cases, |
| 78 | + * but these are handled by setting binary_upgrade_next_toast_pg_class_oid.) |
| 79 | + * |
| 80 | + * We can't allow the TOAST table to be created by pg_dump with a |
| 81 | + * pg_dump-assigned oid because it might conflict with a later table that |
| 82 | + * uses that oid, causing a "file exists" error for pg_class conflicts, and |
| 83 | + * a "duplicate oid" error for pg_type conflicts. (TOAST tables need pg_type |
| 84 | + * entries.) |
| 85 | + * |
| 86 | + * Therefore, a backend in binary-upgrade mode will not create a TOAST |
| 87 | + * table unless an OID as passed in via pg_upgrade_support functions. |
| 88 | + * This function is called after the restore and uses ALTER TABLE to |
| 89 | + * auto-create any needed TOAST tables which will not conflict with |
| 90 | + * restored oids. |
| 91 | + */ |
| 92 | +void |
| 93 | +optionally_create_toast_tables(void) |
| 94 | +{ |
| 95 | + int dbnum; |
| 96 | + |
| 97 | + prep_status("Creating newly-required TOAST tables"); |
| 98 | + |
| 99 | + for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++) |
| 100 | + { |
| 101 | + PGresult *res; |
| 102 | + int ntups; |
| 103 | + int rowno; |
| 104 | + int i_nspname, |
| 105 | + i_relname; |
| 106 | + DbInfo *active_db = &new_cluster.dbarr.dbs[dbnum]; |
| 107 | + PGconn *conn = connectToServer(&new_cluster, active_db->db_name); |
| 108 | + |
| 109 | + res = executeQueryOrDie(conn, |
| 110 | + "SELECT n.nspname, c.relname " |
| 111 | + "FROM pg_catalog.pg_class c, " |
| 112 | + " pg_catalog.pg_namespace n " |
| 113 | + "WHERE c.relnamespace = n.oid AND " |
| 114 | + " n.nspname NOT IN ('pg_catalog', 'information_schema') AND " |
| 115 | + "c.relkind IN ('r', 'm') AND " |
| 116 | + "c.reltoastrelid = 0"); |
| 117 | + |
| 118 | + ntups = PQntuples(res); |
| 119 | + i_nspname = PQfnumber(res, "nspname"); |
| 120 | + i_relname = PQfnumber(res, "relname"); |
| 121 | + for (rowno = 0; rowno < ntups; rowno++) |
| 122 | + { |
| 123 | + /* enable auto-oid-numbered TOAST creation if needed */ |
| 124 | + PQclear(executeQueryOrDie(conn, "SELECT binary_upgrade.set_next_toast_pg_class_oid('%d'::pg_catalog.oid);", |
| 125 | + OPTIONALLY_CREATE_TOAST_OID)); |
| 126 | + |
| 127 | + /* dummy command that also triggers check for required TOAST table */ |
| 128 | + PQclear(executeQueryOrDie(conn, "ALTER TABLE %s.%s RESET (binary_upgrade_dummy_option);", |
| 129 | + quote_identifier(PQgetvalue(res, rowno, i_nspname)), |
| 130 | + quote_identifier(PQgetvalue(res, rowno, i_relname)))); |
| 131 | + } |
| 132 | + |
| 133 | + PQclear(res); |
| 134 | + |
| 135 | + PQfinish(conn); |
| 136 | + } |
| 137 | + |
| 138 | + check_ok(); |
| 139 | +} |
0 commit comments