Skip to content

Commit ad109ed

Browse files
committed
This patch contains repack_cleanup_callback() which calls to repack_drop() for cleaning temporary objects. repack_cleanup_callback() will be pushed on stack using pgut_atexit_push() at beginning so that it will pop on abort or exit of program.
This patch includes one global counter (temp_obj_num) which counts number of temporary objects created by pg_repack. Correct order of deletion of temporary object as per count avoids unintentional error messages.
1 parent f4703be commit ad109ed

File tree

4 files changed

+79
-28
lines changed

4 files changed

+79
-28
lines changed

bin/pg_repack.c

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ static void repack_one_table(repack_table *table, const char *order_by);
204204
static bool repack_table_indexes(PGresult *index_details);
205205
static bool repack_all_indexes(char *errbuf, size_t errsize);
206206
static void repack_cleanup(bool fatal, const repack_table *table);
207+
static void repack_cleanup_callback(bool fatal, void *userdata);
207208
static bool rebuild_indexes(const repack_table *table);
208209

209210
static char *getstr(PGresult *res, int row, int col);
@@ -235,13 +236,14 @@ static bool only_indexes = false;
235236
static int wait_timeout = 60; /* in seconds */
236237
static int jobs = 0; /* number of concurrent worker conns. */
237238
static bool dryrun = false;
239+
static unsigned int temp_obj_num = 0; /* temporary objects counter */
238240

239241
/* buffer should have at least 11 bytes */
240242
static char *
241243
utoa(unsigned int value, char *buffer)
242244
{
243245
sprintf(buffer, "%u", value);
244-
return buffer;
246+
return strdup(buffer);
245247
}
246248

247249
static pgut_option options[] =
@@ -990,7 +992,7 @@ static void
990992
repack_one_table(repack_table *table, const char *orderby)
991993
{
992994
PGresult *res = NULL;
993-
const char *params[2];
995+
const char *params[3];
994996
int num;
995997
char *vxid = NULL;
996998
char buffer[12];
@@ -1041,6 +1043,9 @@ repack_one_table(repack_table *table, const char *orderby)
10411043

10421044
if (dryrun)
10431045
return;
1046+
1047+
/* push repack_cleanup_callback() on stack to clean temporary objects */
1048+
pgut_atexit_push(repack_cleanup_callback, &table->target_oid);
10441049

10451050
/*
10461051
* 1. Setup advisory lock and trigger on main table.
@@ -1146,8 +1151,11 @@ repack_one_table(repack_table *table, const char *orderby)
11461151
CLEARPGRES(res);
11471152

11481153
command(table->create_pktype, 0, NULL);
1154+
temp_obj_num++;
11491155
command(table->create_log, 0, NULL);
1156+
temp_obj_num++;
11501157
command(table->create_trigger, 0, NULL);
1158+
temp_obj_num++;
11511159
command(table->enable_trigger, 0, NULL);
11521160
printfStringInfo(&sql, "SELECT repack.disable_autovacuum('repack.log_%u')", table->target_oid);
11531161
command(sql.data, 0, NULL);
@@ -1287,6 +1295,7 @@ repack_one_table(repack_table *table, const char *orderby)
12871295
goto cleanup;
12881296

12891297
command(table->create_table, 0, NULL);
1298+
temp_obj_num++;
12901299
printfStringInfo(&sql, "SELECT repack.disable_autovacuum('repack.table_%u')", table->target_oid);
12911300
if (table->drop_columns)
12921301
command(table->drop_columns, 0, NULL);
@@ -1379,7 +1388,8 @@ repack_one_table(repack_table *table, const char *orderby)
13791388
elog(DEBUG2, "---- drop ----");
13801389

13811390
command("BEGIN ISOLATION LEVEL READ COMMITTED", 0, NULL);
1382-
command("SELECT repack.repack_drop($1)", 1, params);
1391+
params[1] = utoa(temp_obj_num, buffer);
1392+
command("SELECT repack.repack_drop($1, $2)", 2, params);
13831393
command("COMMIT", 0, NULL);
13841394

13851395
/*
@@ -1399,7 +1409,7 @@ repack_one_table(repack_table *table, const char *orderby)
13991409

14001410
/* Release advisory lock on table. */
14011411
params[0] = REPACK_LOCK_PREFIX_STR;
1402-
params[1] = buffer;
1412+
params[1] = utoa(table->target_oid, buffer);
14031413

14041414
res = pgut_execute(connection, "SELECT pg_advisory_unlock($1, CAST(-2147483648 + $2::bigint AS integer))",
14051415
2, params);
@@ -1679,6 +1689,26 @@ lock_exclusive(PGconn *conn, const char *relid, const char *lock_query, bool sta
16791689
return ret;
16801690
}
16811691

1692+
/* This function calls to repack_drop() to clean temporary objects on error
1693+
* in creation of temporary objects.
1694+
*/
1695+
void
1696+
repack_cleanup_callback(bool fatal, void *userdata)
1697+
{
1698+
Oid target_table = *(Oid *) userdata;
1699+
const char *params[2];
1700+
char buffer[12];
1701+
1702+
if(fatal)
1703+
{
1704+
params[0] = utoa(target_table, buffer);
1705+
params[1] = utoa(temp_obj_num, buffer);
1706+
1707+
reconnect(ERROR);
1708+
command("SELECT repack.repack_drop($1, $2)", 2, params);
1709+
}
1710+
}
1711+
16821712
/*
16831713
* The userdata pointing a table being re-organized. We need to cleanup temp
16841714
* objects before the program exits.
@@ -1693,7 +1723,7 @@ repack_cleanup(bool fatal, const repack_table *table)
16931723
else
16941724
{
16951725
char buffer[12];
1696-
const char *params[1];
1726+
const char *params[2];
16971727

16981728
/* Try reconnection if not available. */
16991729
if (PQstatus(connection) != CONNECTION_OK ||
@@ -1702,7 +1732,8 @@ repack_cleanup(bool fatal, const repack_table *table)
17021732

17031733
/* do cleanup */
17041734
params[0] = utoa(table->target_oid, buffer);
1705-
command("SELECT repack.repack_drop($1)", 1, params);
1735+
params[1] = utoa(temp_obj_num, buffer);
1736+
command("SELECT repack.repack_drop($1, $2)", 2, params);
17061737
}
17071738
}
17081739

bin/pgut/pgut.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,9 @@ call_atexit_callbacks(bool fatal)
11801180
pgut_atexit_item *item;
11811181

11821182
for (item = pgut_atexit_stack; item; item = item->next)
1183+
{
11831184
item->callback(fatal, item->userdata);
1185+
}
11841186
}
11851187

11861188
static void
@@ -1195,10 +1197,11 @@ on_cleanup(void)
11951197
static void
11961198
exit_or_abort(int exitcode)
11971199
{
1200+
call_atexit_callbacks(true);
11981201
if (in_cleanup)
11991202
{
12001203
/* oops, error in cleanup*/
1201-
call_atexit_callbacks(true);
1204+
in_cleanup = false;
12021205
abort();
12031206
}
12041207
else

lib/pg_repack.sql.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ CREATE FUNCTION repack.repack_swap(oid) RETURNS void AS
247247
'MODULE_PATHNAME', 'repack_swap'
248248
LANGUAGE C VOLATILE STRICT;
249249

250-
CREATE FUNCTION repack.repack_drop(oid) RETURNS void AS
250+
CREATE FUNCTION repack.repack_drop(oid, int) RETURNS void AS
251251
'MODULE_PATHNAME', 'repack_drop'
252252
LANGUAGE C VOLATILE STRICT;
253253

lib/repack.c

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ Datum
928928
repack_drop(PG_FUNCTION_ARGS)
929929
{
930930
Oid oid = PG_GETARG_OID(0);
931+
int numobj = PG_GETARG_INT32(1);
931932
const char *relname = get_quoted_relname(oid);
932933
const char *nspname = get_quoted_nspname(oid);
933934

@@ -943,14 +944,38 @@ repack_drop(PG_FUNCTION_ARGS)
943944
/* connect to SPI manager */
944945
repack_init();
945946

947+
/* drop log table */
948+
if(numobj > 0)
949+
{
950+
execute_with_format(
951+
SPI_OK_UTILITY,
952+
"DROP TABLE IF EXISTS repack.log_%u CASCADE",
953+
oid);
954+
--numobj;
955+
}
956+
957+
/* drop type for pk type */
958+
if(numobj > 0)
959+
{
960+
execute_with_format(
961+
SPI_OK_UTILITY,
962+
"DROP TYPE IF EXISTS repack.pk_%u",
963+
oid);
964+
--numobj;
965+
}
966+
946967
/*
947968
* drop repack trigger: We have already dropped the trigger in normal
948969
* cases, but it can be left on error.
949970
*/
950-
execute_with_format(
951-
SPI_OK_UTILITY,
952-
"DROP TRIGGER IF EXISTS z_repack_trigger ON %s.%s CASCADE",
953-
nspname, relname);
971+
if(numobj > 0)
972+
{
973+
execute_with_format(
974+
SPI_OK_UTILITY,
975+
"DROP TRIGGER IF EXISTS z_repack_trigger ON %s.%s CASCADE",
976+
nspname, relname);
977+
--numobj;
978+
}
954979

955980
#if PG_VERSION_NUM < 80400
956981
/* delete autovacuum settings */
@@ -965,23 +990,15 @@ repack_drop(PG_FUNCTION_ARGS)
965990
oid, oid);
966991
#endif
967992

968-
/* drop log table */
969-
execute_with_format(
970-
SPI_OK_UTILITY,
971-
"DROP TABLE IF EXISTS repack.log_%u CASCADE",
972-
oid);
973-
974993
/* drop temp table */
975-
execute_with_format(
976-
SPI_OK_UTILITY,
977-
"DROP TABLE IF EXISTS repack.table_%u CASCADE",
978-
oid);
979-
980-
/* drop type for log table */
981-
execute_with_format(
982-
SPI_OK_UTILITY,
983-
"DROP TYPE IF EXISTS repack.pk_%u CASCADE",
984-
oid);
994+
if(numobj > 0)
995+
{
996+
execute_with_format(
997+
SPI_OK_UTILITY,
998+
"DROP TABLE IF EXISTS repack.table_%u CASCADE",
999+
oid);
1000+
--numobj;
1001+
}
9851002

9861003
SPI_finish();
9871004

0 commit comments

Comments
 (0)