@@ -1001,9 +1001,31 @@ repack_one_table(const repack_table *table, const char *orderby)
1001
1001
elog (DEBUG2 , "sql_pop : %s" , table -> sql_pop );
1002
1002
1003
1003
/*
1004
- * 1. Setup workspaces and a trigger.
1004
+ * 1. Setup advisory lock and trigger on main table .
1005
1005
*/
1006
1006
elog (DEBUG2 , "---- setup ----" );
1007
+
1008
+ /* Obtain an advisory lock on the table's OID, to make sure no other
1009
+ * pg_repack is working on the table. (Not a real concern with only
1010
+ * full-table repacks, but mainly for index-only repacks.)
1011
+ */
1012
+ params [0 ] = utoa (table -> target_oid , buffer );
1013
+ res = pgut_execute (connection , "SELECT pg_try_advisory_lock($1::bigint)" ,
1014
+ 1 , params );
1015
+ if (PQresultStatus (res ) != PGRES_TUPLES_OK )
1016
+ {
1017
+ elog (ERROR , "%s" , PQerrorMessage (connection ));
1018
+ have_error = true;
1019
+ goto cleanup ;
1020
+ }
1021
+ else if (strcmp (getstr (res , 0 , 0 ), "t" ) != 0 )
1022
+ {
1023
+ elog (WARNING , "Another pg_repack command may be running on the table. Please try again later." );
1024
+ have_error = true;
1025
+ goto cleanup ;
1026
+ }
1027
+ CLEARPGRES (res );
1028
+
1007
1029
if (!(lock_exclusive (connection , utoa (table -> target_oid , buffer ), table -> lock_table , TRUE)))
1008
1030
{
1009
1031
elog (WARNING , "lock_exclusive() failed for %s" , table -> target_name );
@@ -1015,8 +1037,6 @@ repack_one_table(const repack_table *table, const char *orderby)
1015
1037
* Check z_repack_trigger is the trigger executed last so that
1016
1038
* other before triggers cannot modify triggered tuples.
1017
1039
*/
1018
- params [0 ] = utoa (table -> target_oid , buffer );
1019
-
1020
1040
res = execute ("SELECT repack.conflicted_triggers($1)" , 1 , params );
1021
1041
if (PQntuples (res ) > 0 )
1022
1042
{
@@ -1289,7 +1309,6 @@ repack_one_table(const repack_table *table, const char *orderby)
1289
1309
elog (DEBUG2 , "---- drop ----" );
1290
1310
1291
1311
command ("BEGIN ISOLATION LEVEL READ COMMITTED" , 0 , NULL );
1292
- params [0 ] = utoa (table -> target_oid , buffer );
1293
1312
command ("SELECT repack.repack_drop($1)" , 1 , params );
1294
1313
command ("COMMIT" , 0 , NULL );
1295
1314
@@ -1308,6 +1327,10 @@ repack_one_table(const repack_table *table, const char *orderby)
1308
1327
command ("COMMIT" , 0 , NULL );
1309
1328
}
1310
1329
1330
+ /* Release advisory lock on table. */
1331
+ res = pgut_execute (connection , "SELECT pg_advisory_unlock($1::bigint)" ,
1332
+ 1 , params );
1333
+
1311
1334
cleanup :
1312
1335
CLEARPGRES (res );
1313
1336
termStringInfo (& sql );
@@ -1772,7 +1795,7 @@ repack_all_indexes(char *errbuf, size_t errsize){
1772
1795
elog (ERROR , "%s" , PQerrorMessage (connection ));
1773
1796
goto cleanup ;
1774
1797
}
1775
- else if (strcmp (getstr (res2 , 0 , 0 ), "f " ) = = 0 )
1798
+ else if (strcmp (getstr (res2 , 0 , 0 ), "t " ) ! = 0 )
1776
1799
{
1777
1800
snprintf (errbuf , errsize , "Another pg_repack command may be running on the table. Please try again later." );
1778
1801
goto cleanup ;
@@ -1798,8 +1821,10 @@ repack_all_indexes(char *errbuf, size_t errsize){
1798
1821
elog (WARNING , "skipping invalid index: %s" , getstr (res , i , 0 ));
1799
1822
}
1800
1823
ret = true;
1824
+
1801
1825
cleanup :
1802
1826
CLEARPGRES (res );
1827
+ CLEARPGRES (res2 );
1803
1828
disconnect ();
1804
1829
termStringInfo (& sql );
1805
1830
return ret ;
0 commit comments