Skip to content

Commit

Permalink
Issue #437: Cleanup temporary indexes on error (with --only-indexes)
Browse files Browse the repository at this point in the history
When using --only-indexes pg_repack uses different approach to repack
indexes, which is running CREATE INDEX CONCURRENTLY command to create a
temporary index and swapping the target index and the temporary index
afterwards.
That approach didn't use any cleanup callbacks and therefore in case of
an error temporary indexes wouldn't be cleaned up.

The commit adds the callback repack_cleanup_index.
  • Loading branch information
za-arthur committed Jan 26, 2025
1 parent 9f36c65 commit b3c42a5
Showing 1 changed file with 42 additions and 20 deletions.
62 changes: 42 additions & 20 deletions bin/pg_repack.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ static bool repack_table_indexes(PGresult *index_details);
static bool repack_all_indexes(char *errbuf, size_t errsize);
static void repack_cleanup(bool fatal, const repack_table *table);
static void repack_cleanup_callback(bool fatal, void *userdata);
static void repack_cleanup_index(bool fatal, void *userdata);
static bool rebuild_indexes(const repack_table *table);

static char *getstr(PGresult *res, int row, int col);
Expand Down Expand Up @@ -2078,6 +2079,39 @@ repack_cleanup(bool fatal, const repack_table *table)
}
}

/*
* Cleanup temporary objects, created during index repacking (with option
* --index-only), on error.
*/
static void
repack_cleanup_index(bool fatal, void *userdata)
{
StringInfoData sql, sql_drop;
PGresult *index_details = (PGresult *) userdata;
char *schema_name;
int num;

schema_name = getstr(index_details, 0, 5);
num = PQntuples(index_details);

initStringInfo(&sql);
initStringInfo(&sql_drop);

appendStringInfoString(&sql, "DROP INDEX CONCURRENTLY IF EXISTS ");
appendStringInfo(&sql, "\"%s\".", schema_name);

for (int i = 0; i < num; i++)
{
Oid index = getoid(index_details, i, 1);

resetStringInfo(&sql_drop);
appendStringInfo(&sql_drop, "%s\"index_%u\"", sql.data, index);
command(sql_drop.data, 0, NULL);
}
termStringInfo(&sql_drop);
termStringInfo(&sql);
}

/*
* Indexes of a table are repacked.
*/
Expand All @@ -2086,7 +2120,7 @@ repack_table_indexes(PGresult *index_details)
{
bool ret = false;
PGresult *res = NULL, *res2 = NULL;
StringInfoData sql, sql_drop;
StringInfoData sql;
char buffer[2][12];
const char *create_idx, *schema_name, *table_name, *params[3];
Oid table, index;
Expand Down Expand Up @@ -2117,6 +2151,8 @@ repack_table_indexes(PGresult *index_details)
ereport(ERROR, (errcode(EINVAL),
errmsg("Unable to obtain advisory lock on \"%s\"", table_name)));

pgut_atexit_push(repack_cleanup_index, index_details);

for (i = 0; i < num; i++)
{
char *isvalid = getstr(index_details, i, 2);
Expand Down Expand Up @@ -2241,30 +2277,16 @@ repack_table_indexes(PGresult *index_details)
pgut_command(connection, "COMMIT", 0, NULL);
ret = true;

drop_idx:
resetStringInfo(&sql);
initStringInfo(&sql_drop);
appendStringInfoString(&sql, "DROP INDEX CONCURRENTLY ");
appendStringInfo(&sql, "\"%s\".", schema_name);
pgut_atexit_pop(repack_cleanup_index, index_details);

for (i = 0; i < num; i++)
{
index = getoid(index_details, i, 1);
if (repacked_indexes[i])
{
initStringInfo(&sql_drop);
appendStringInfo(&sql_drop, "%s\"index_%u\"", sql.data, index);
command(sql_drop.data, 0, NULL);
}
else
elog(INFO, "Skipping drop of index_%u", index);
}
termStringInfo(&sql_drop);
termStringInfo(&sql);
drop_idx:
if (num_repacked > 0)
repack_cleanup_index(false, index_details);

done:
CLEARPGRES(res);
free(repacked_indexes);
termStringInfo(&sql);

return ret;
}
Expand Down

0 comments on commit b3c42a5

Please sign in to comment.