@@ -204,6 +204,7 @@ static void repack_one_table(repack_table *table, const char *order_by);
204
204
static bool repack_table_indexes (PGresult * index_details );
205
205
static bool repack_all_indexes (char * errbuf , size_t errsize );
206
206
static void repack_cleanup (bool fatal , const repack_table * table );
207
+ static void repack_cleanup_callback (bool fatal , void * userdata );
207
208
static bool rebuild_indexes (const repack_table * table );
208
209
209
210
static char * getstr (PGresult * res , int row , int col );
@@ -235,13 +236,14 @@ static bool only_indexes = false;
235
236
static int wait_timeout = 60 ; /* in seconds */
236
237
static int jobs = 0 ; /* number of concurrent worker conns. */
237
238
static bool dryrun = false;
239
+ static unsigned int temp_obj_num = 0 ; /* temporary objects counter */
238
240
239
241
/* buffer should have at least 11 bytes */
240
242
static char *
241
243
utoa (unsigned int value , char * buffer )
242
244
{
243
245
sprintf (buffer , "%u" , value );
244
- return buffer ;
246
+ return strdup ( buffer ) ;
245
247
}
246
248
247
249
static pgut_option options [] =
@@ -990,7 +992,7 @@ static void
990
992
repack_one_table (repack_table * table , const char * orderby )
991
993
{
992
994
PGresult * res = NULL ;
993
- const char * params [2 ];
995
+ const char * params [3 ];
994
996
int num ;
995
997
char * vxid = NULL ;
996
998
char buffer [12 ];
@@ -1041,6 +1043,9 @@ repack_one_table(repack_table *table, const char *orderby)
1041
1043
1042
1044
if (dryrun )
1043
1045
return ;
1046
+
1047
+ /* push repack_cleanup_callback() on stack to clean temporary objects */
1048
+ pgut_atexit_push (repack_cleanup_callback , & table -> target_oid );
1044
1049
1045
1050
/*
1046
1051
* 1. Setup advisory lock and trigger on main table.
@@ -1146,8 +1151,11 @@ repack_one_table(repack_table *table, const char *orderby)
1146
1151
CLEARPGRES (res );
1147
1152
1148
1153
command (table -> create_pktype , 0 , NULL );
1154
+ temp_obj_num ++ ;
1149
1155
command (table -> create_log , 0 , NULL );
1156
+ temp_obj_num ++ ;
1150
1157
command (table -> create_trigger , 0 , NULL );
1158
+ temp_obj_num ++ ;
1151
1159
command (table -> enable_trigger , 0 , NULL );
1152
1160
printfStringInfo (& sql , "SELECT repack.disable_autovacuum('repack.log_%u')" , table -> target_oid );
1153
1161
command (sql .data , 0 , NULL );
@@ -1287,6 +1295,7 @@ repack_one_table(repack_table *table, const char *orderby)
1287
1295
goto cleanup ;
1288
1296
1289
1297
command (table -> create_table , 0 , NULL );
1298
+ temp_obj_num ++ ;
1290
1299
printfStringInfo (& sql , "SELECT repack.disable_autovacuum('repack.table_%u')" , table -> target_oid );
1291
1300
if (table -> drop_columns )
1292
1301
command (table -> drop_columns , 0 , NULL );
@@ -1379,7 +1388,8 @@ repack_one_table(repack_table *table, const char *orderby)
1379
1388
elog (DEBUG2 , "---- drop ----" );
1380
1389
1381
1390
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 );
1383
1393
command ("COMMIT" , 0 , NULL );
1384
1394
1385
1395
/*
@@ -1399,7 +1409,7 @@ repack_one_table(repack_table *table, const char *orderby)
1399
1409
1400
1410
/* Release advisory lock on table. */
1401
1411
params [0 ] = REPACK_LOCK_PREFIX_STR ;
1402
- params [1 ] = buffer ;
1412
+ params [1 ] = utoa ( table -> target_oid , buffer ) ;
1403
1413
1404
1414
res = pgut_execute (connection , "SELECT pg_advisory_unlock($1, CAST(-2147483648 + $2::bigint AS integer))" ,
1405
1415
2 , params );
@@ -1679,6 +1689,26 @@ lock_exclusive(PGconn *conn, const char *relid, const char *lock_query, bool sta
1679
1689
return ret ;
1680
1690
}
1681
1691
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
+
1682
1712
/*
1683
1713
* The userdata pointing a table being re-organized. We need to cleanup temp
1684
1714
* objects before the program exits.
@@ -1693,7 +1723,7 @@ repack_cleanup(bool fatal, const repack_table *table)
1693
1723
else
1694
1724
{
1695
1725
char buffer [12 ];
1696
- const char * params [1 ];
1726
+ const char * params [2 ];
1697
1727
1698
1728
/* Try reconnection if not available. */
1699
1729
if (PQstatus (connection ) != CONNECTION_OK ||
@@ -1702,7 +1732,8 @@ repack_cleanup(bool fatal, const repack_table *table)
1702
1732
1703
1733
/* do cleanup */
1704
1734
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 );
1706
1737
}
1707
1738
}
1708
1739
0 commit comments