Skip to content

Commit e95c4bd

Browse files
committed
Fix pg_upgrade for invalid indexes
All versions of pg_upgrade upgraded invalid indexes caused by CREATE INDEX CONCURRENTLY failures and marked them as valid. The patch adds a check to all pg_upgrade versions and throws an error during upgrade or --check. Backpatch to 9.2, 9.1, 9.0. Patch slightly adjusted.
1 parent 970fb12 commit e95c4bd

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

contrib/pg_upgrade/check.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static void check_is_super_user(ClusterInfo *cluster);
2020
static void check_for_prepared_transactions(ClusterInfo *cluster);
2121
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
2222
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
23+
static void check_for_invalid_indexes(ClusterInfo *cluster);
2324
static void get_bin_version(ClusterInfo *cluster);
2425
static char *get_canonical_locale_name(int category, const char *locale);
2526

@@ -97,6 +98,7 @@ check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name)
9798
check_is_super_user(&old_cluster);
9899
check_for_prepared_transactions(&old_cluster);
99100
check_for_reg_data_type_usage(&old_cluster);
101+
check_for_invalid_indexes(&old_cluster);
100102
check_for_isn_and_int8_passing_mismatch(&old_cluster);
101103

102104
/* old = PG 8.3 checks? */
@@ -924,6 +926,95 @@ check_for_reg_data_type_usage(ClusterInfo *cluster)
924926
}
925927

926928

929+
/*
930+
* check_for_invalid_indexes()
931+
*
932+
* CREATE INDEX CONCURRENTLY can create invalid indexes if the index build
933+
* fails. These are dumped as valid indexes by pg_dump, but the
934+
* underlying files are still invalid indexes. This checks to make sure
935+
* no invalid indexes exist, either failed index builds or concurrent
936+
* indexes in the process of being created.
937+
*/
938+
static void
939+
check_for_invalid_indexes(ClusterInfo *cluster)
940+
{
941+
int dbnum;
942+
FILE *script = NULL;
943+
bool found = false;
944+
char output_path[MAXPGPATH];
945+
946+
prep_status("Checking for invalid indexes from concurrent index builds");
947+
948+
snprintf(output_path, sizeof(output_path), "invalid_indexes.txt");
949+
950+
for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
951+
{
952+
PGresult *res;
953+
bool db_used = false;
954+
int ntups;
955+
int rowno;
956+
int i_nspname,
957+
i_relname;
958+
DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
959+
PGconn *conn = connectToServer(cluster, active_db->db_name);
960+
961+
res = executeQueryOrDie(conn,
962+
"SELECT n.nspname, c.relname "
963+
"FROM pg_catalog.pg_class c, "
964+
" pg_catalog.pg_namespace n, "
965+
" pg_catalog.pg_index i "
966+
"WHERE (i.indisvalid = false OR "
967+
" i.indisready = false) AND "
968+
" i.indexrelid = c.oid AND "
969+
" c.relnamespace = n.oid AND "
970+
/* we do not migrate these, so skip them */
971+
" n.nspname != 'pg_catalog' AND "
972+
" n.nspname != 'information_schema' AND "
973+
/* indexes do not have toast tables */
974+
" n.nspname != 'pg_toast'");
975+
976+
ntups = PQntuples(res);
977+
i_nspname = PQfnumber(res, "nspname");
978+
i_relname = PQfnumber(res, "relname");
979+
for (rowno = 0; rowno < ntups; rowno++)
980+
{
981+
found = true;
982+
if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
983+
pg_log(PG_FATAL, "Could not open file \"%s\": %s\n",
984+
output_path, getErrorText(errno));
985+
if (!db_used)
986+
{
987+
fprintf(script, "Database: %s\n", active_db->db_name);
988+
db_used = true;
989+
}
990+
fprintf(script, " %s.%s\n",
991+
PQgetvalue(res, rowno, i_nspname),
992+
PQgetvalue(res, rowno, i_relname));
993+
}
994+
995+
PQclear(res);
996+
997+
PQfinish(conn);
998+
}
999+
1000+
if (script)
1001+
fclose(script);
1002+
1003+
if (found)
1004+
{
1005+
pg_log(PG_REPORT, "fatal\n");
1006+
pg_log(PG_FATAL,
1007+
"Your installation contains invalid indexes due to failed or\n"
1008+
"currently running CREATE INDEX CONCURRENTLY operations. You\n"
1009+
"cannot upgrade until these indexes are valid or removed. A\n"
1010+
"list of the problem indexes is in the file:\n"
1011+
" %s\n\n", output_path);
1012+
}
1013+
else
1014+
check_ok();
1015+
}
1016+
1017+
9271018
static void
9281019
get_bin_version(ClusterInfo *cluster)
9291020
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy