diff options
author | Robert Haas | 2017-05-19 20:49:38 +0000 |
---|---|---|
committer | Robert Haas | 2017-05-19 20:49:38 +0000 |
commit | a95410e2ec39b6776381fd01198dc57a063e8185 (patch) | |
tree | 3cf687880944d9f509e9f421da6370d9c784f52a /src/bin/pg_upgrade/version.c | |
parent | e807d8b16338c97e60e41344d0fc13bd9cf540be (diff) |
pg_upgrade: Handle hash index upgrades more smoothly.
Mark any old hash indexes as invalid so that they don't get used, and
create a script to run REINDEX on all of them. Without this, we'd
still try to use any upgraded hash indexes, but it would fail.
Amit Kapila, reviewed by me. Per a suggestion from Tom Lane.
Discussion: http://postgr.es/m/CAA4eK1Jidtagm7Q81q-WoegOVgkotv0OxvHOjFxcvFRP4X=mSw@mail.gmail.com
Diffstat (limited to 'src/bin/pg_upgrade/version.c')
-rw-r--r-- | src/bin/pg_upgrade/version.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/bin/pg_upgrade/version.c b/src/bin/pg_upgrade/version.c index a3651aadede..814eaa522c4 100644 --- a/src/bin/pg_upgrade/version.c +++ b/src/bin/pg_upgrade/version.c @@ -287,3 +287,115 @@ old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster) else check_ok(); } + +/* + * old_9_6_invalidate_hash_indexes() + * 9.6 -> 10 + * Hash index binary format has changed from 9.6->10.0 + */ +void +old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode) +{ + int dbnum; + FILE *script = NULL; + bool found = false; + char *output_path = "reindex_hash.sql"; + + prep_status("Checking for hash indexes"); + + for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++) + { + PGresult *res; + bool db_used = false; + int ntups; + int rowno; + int i_nspname, + i_relname; + DbInfo *active_db = &cluster->dbarr.dbs[dbnum]; + PGconn *conn = connectToServer(cluster, active_db->db_name); + + /* find hash indexes */ + res = executeQueryOrDie(conn, + "SELECT n.nspname, c.relname " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_index i, " + " pg_catalog.pg_am a, " + " pg_catalog.pg_namespace n " + "WHERE i.indexrelid = c.oid AND " + " c.relam = a.oid AND " + " c.relnamespace = n.oid AND " + " a.amname = 'hash'" + ); + + ntups = PQntuples(res); + i_nspname = PQfnumber(res, "nspname"); + i_relname = PQfnumber(res, "relname"); + for (rowno = 0; rowno < ntups; rowno++) + { + found = true; + if (!check_mode) + { + if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL) + pg_fatal("could not open file \"%s\": %s\n", output_path, + strerror(errno)); + if (!db_used) + { + PQExpBufferData connectbuf; + + initPQExpBuffer(&connectbuf); + appendPsqlMetaConnect(&connectbuf, active_db->db_name); + fputs(connectbuf.data, script); + termPQExpBuffer(&connectbuf); + db_used = true; + } + fprintf(script, "REINDEX INDEX %s.%s;\n", + quote_identifier(PQgetvalue(res, rowno, i_nspname)), + quote_identifier(PQgetvalue(res, rowno, i_relname))); + } + } + + PQclear(res); + + if (!check_mode && db_used) + { + /* mark hash indexes as invalid */ + PQclear(executeQueryOrDie(conn, + "UPDATE pg_catalog.pg_index i " + "SET indisvalid = false " + "FROM pg_catalog.pg_class c, " + " pg_catalog.pg_am a, " + " pg_catalog.pg_namespace n " + "WHERE i.indexrelid = c.oid AND " + " c.relam = a.oid AND " + " c.relnamespace = n.oid AND " + " a.amname = 'hash'")); + } + + PQfinish(conn); + } + + if (script) + fclose(script); + + if (found) + { + report_status(PG_WARNING, "warning"); + if (check_mode) + pg_log(PG_WARNING, "\n" + "Your installation contains hash indexes. These indexes have different\n" + "internal formats between your old and new clusters, so they must be\n" + "reindexed with the REINDEX command. After upgrading, you will be given\n" + "REINDEX instructions.\n\n"); + else + pg_log(PG_WARNING, "\n" + "Your installation contains hash indexes. These indexes have different\n" + "internal formats between your old and new clusters, so they must be\n" + "reindexed with the REINDEX command. The file:\n" + " %s\n" + "when executed by psql by the database superuser will recreate all invalid\n" + "indexes; until then, none of these indexes will be used.\n\n", + output_path); + } + else + check_ok(); +} |