@@ -227,7 +227,7 @@ static bool rebuild_indexes(const repack_table *table);
227227static char * getstr (PGresult * res , int row , int col );
228228static Oid getoid (PGresult * res , int row , int col );
229229static bool advisory_lock (PGconn * conn , const char * relid );
230- static bool lock_exclusive (PGconn * conn , const char * relid , const char * lock_query , bool start_xact );
230+ static bool lock_exclusive (PGconn * conn , const char * relid , const char * lock_query , bool start_xact , const repack_table * apply_log_table );
231231static bool kill_ddl (PGconn * conn , Oid relid , bool terminate );
232232static bool lock_access_share (PGconn * conn , Oid relid , const char * target_name );
233233
@@ -1298,7 +1298,7 @@ repack_one_table(repack_table *table, const char *orderby)
12981298 if (!advisory_lock (connection , buffer ))
12991299 goto cleanup ;
13001300
1301- if (!(lock_exclusive (connection , buffer , table -> lock_table , true)))
1301+ if (!(lock_exclusive (connection , buffer , table -> lock_table , true, NULL )))
13021302 {
13031303 if (no_kill_backend )
13041304 elog (INFO , "Skipping repack %s due to timeout" , table -> target_name );
@@ -1621,7 +1621,7 @@ repack_one_table(repack_table *table, const char *orderby)
16211621 /* Bump our existing AccessShare lock to AccessExclusive */
16221622
16231623 if (!(lock_exclusive (conn2 , utoa (table -> target_oid , buffer ),
1624- table -> lock_table , false)))
1624+ table -> lock_table , false, table )))
16251625 {
16261626 elog (WARNING , "lock_exclusive() failed in conn2 for %s" ,
16271627 table -> target_name );
@@ -1635,7 +1635,7 @@ repack_one_table(repack_table *table, const char *orderby)
16351635 printfStringInfo (& sql , "LOCK TABLE repack.table_%u IN ACCESS EXCLUSIVE MODE" ,
16361636 table -> target_oid );
16371637 if (!(lock_exclusive (conn2 , utoa (table -> temp_oid , buffer ),
1638- sql .data , false)))
1638+ sql .data , false, NULL )))
16391639 {
16401640 elog (WARNING , "lock_exclusive() failed in conn2 for table_%u" ,
16411641 table -> target_oid );
@@ -1654,7 +1654,7 @@ repack_one_table(repack_table *table, const char *orderby)
16541654
16551655 command ("BEGIN ISOLATION LEVEL READ COMMITTED" , 0 , NULL );
16561656 if (!(lock_exclusive (connection , utoa (table -> target_oid , buffer ),
1657- table -> lock_table , false)))
1657+ table -> lock_table , false, NULL )))
16581658 {
16591659 elog (WARNING , "lock_exclusive() failed in connection for %s" ,
16601660 table -> target_name );
@@ -1908,9 +1908,14 @@ static bool advisory_lock(PGconn *conn, const char *relid)
19081908 * start_xact: whether we will issue a BEGIN ourselves. If not, we will
19091909 * use a SAVEPOINT and ROLLBACK TO SAVEPOINT if our query
19101910 * times out, to avoid leaving the transaction in error state.
1911+ * apply_log_table: if non-NULL, call apply_log() on this table between
1912+ * locking attempts. This prevents lots of log from
1913+ * building up if getting the exclusive lock takes many
1914+ * retries over a long period.
19111915 */
19121916static bool
1913- lock_exclusive (PGconn * conn , const char * relid , const char * lock_query , bool start_xact )
1917+ lock_exclusive (PGconn * conn , const char * relid , const char * lock_query ,
1918+ bool start_xact , const repack_table * apply_log_table )
19141919{
19151920 time_t start = time (NULL );
19161921 int i ;
@@ -1991,6 +1996,8 @@ lock_exclusive(PGconn *conn, const char *relid, const char *lock_query, bool sta
19911996 pgut_command (conn , "ROLLBACK TO SAVEPOINT repack_sp1" , 0 , NULL );
19921997 if (timeout_msec < wait_msec )
19931998 usleep (1000 * (wait_msec - timeout_msec ));
1999+ if (apply_log_table )
2000+ apply_log (conn , apply_log_table , 0 );
19942001 continue ;
19952002 }
19962003 else
@@ -2031,7 +2038,7 @@ repack_cleanup_callback(bool fatal, void *userdata)
20312038 reconnect (ERROR );
20322039
20332040 command ("BEGIN ISOLATION LEVEL READ COMMITTED" , 0 , NULL );
2034- if (!(lock_exclusive (connection , params [0 ], table -> lock_table , false)))
2041+ if (!(lock_exclusive (connection , params [0 ], table -> lock_table , false, NULL )))
20352042 {
20362043 pgut_rollback (connection );
20372044 elog (ERROR , "lock_exclusive() failed in connection for %s during cleanup callback" ,
@@ -2071,7 +2078,7 @@ repack_cleanup(bool fatal, const repack_table *table)
20712078 params [1 ] = utoa (temp_obj_num , num_buff );
20722079
20732080 command ("BEGIN ISOLATION LEVEL READ COMMITTED" , 0 , NULL );
2074- if (!(lock_exclusive (connection , params [0 ], table -> lock_table , false)))
2081+ if (!(lock_exclusive (connection , params [0 ], table -> lock_table , false, NULL )))
20752082 {
20762083 pgut_rollback (connection );
20772084 elog (ERROR , "lock_exclusive() failed in connection for %s during cleanup" ,
@@ -2225,7 +2232,7 @@ repack_table_indexes(PGresult *index_details)
22252232 resetStringInfo (& sql );
22262233 appendStringInfo (& sql , "LOCK TABLE %s IN ACCESS EXCLUSIVE MODE" ,
22272234 table_name );
2228- if (!(lock_exclusive (connection , params [1 ], sql .data , true)))
2235+ if (!(lock_exclusive (connection , params [1 ], sql .data , true, NULL )))
22292236 {
22302237 elog (WARNING , "lock_exclusive() failed in connection for %s" ,
22312238 table_name );
0 commit comments