@@ -456,7 +456,6 @@ static void reset_conflict_info_fields(RetainConflictInfoData *data);
456
456
static bool should_stop_conflict_info_retention (RetainConflictInfoData * data );
457
457
static void adjust_xid_advance_interval (RetainConflictInfoData * data ,
458
458
bool new_xid_found );
459
- static void update_conflict_retention_status (void );
460
459
461
460
static void apply_handle_commit_internal (LogicalRepCommitData * commit_data );
462
461
static void apply_handle_insert_internal (ApplyExecutionData * edata ,
@@ -4126,10 +4125,6 @@ maybe_advance_nonremovable_xid(RetainConflictInfoData *data,
4126
4125
if (!am_leader_apply_worker ())
4127
4126
return ;
4128
4127
4129
- /* Exit early if we have already stopped retaining */
4130
- if (MyLogicalRepWorker -> stop_conflict_info_retention )
4131
- return ;
4132
-
4133
4128
switch (data -> phase )
4134
4129
{
4135
4130
case RCI_GET_CANDIDATE_XID :
@@ -4374,6 +4369,19 @@ wait_for_local_flush(RetainConflictInfoData *data)
4374
4369
if (last_flushpos < data -> remote_lsn )
4375
4370
return ;
4376
4371
4372
+ /*
4373
+ * If conflict info retention was previously stopped due to a timeout, and
4374
+ * the time required to advance the non-removable transaction ID has now
4375
+ * decreased to within acceptable limits, log a message.
4376
+ */
4377
+ if (MyLogicalRepWorker -> stop_conflict_info_retention )
4378
+ ereport (LOG ,
4379
+ errmsg ("logical replication worker for subscription \"%s\" will resume retaining conflict information" ,
4380
+ MySubscription -> name ),
4381
+ errdetail ("The time spent applying changes up to LSN %X/%X is now within the maximum limit of %u ms." ,
4382
+ LSN_FORMAT_ARGS (data -> remote_lsn ),
4383
+ max_conflict_retention_duration ));
4384
+
4377
4385
/*
4378
4386
* Reaching here means the remote WAL position has been received, and
4379
4387
* all transactions up to that position on the publisher have been
@@ -4382,6 +4390,7 @@ wait_for_local_flush(RetainConflictInfoData *data)
4382
4390
*/
4383
4391
SpinLockAcquire (& MyLogicalRepWorker -> relmutex );
4384
4392
MyLogicalRepWorker -> oldest_nonremovable_xid = data -> candidate_xid ;
4393
+ MyLogicalRepWorker -> stop_conflict_info_retention = false;
4385
4394
SpinLockRelease (& MyLogicalRepWorker -> relmutex );
4386
4395
4387
4396
elog (DEBUG2 , "confirmed remote flush up to %X/%X: new oldest_nonremovable_xid %u" ,
@@ -4423,9 +4432,8 @@ reset_conflict_info_fields(RetainConflictInfoData *data)
4423
4432
* LogicalRepWorker->stop_conflict_info_retention to true, notify the launcher to
4424
4433
* invalidate the slot, and return true. Return false otherwise.
4425
4434
*
4426
- * Currently, the retention will not resume automatically unless user manually
4427
- * disables retain_conflict_info and re-enables it after confirming that the
4428
- * replication slot has been dropped.
4435
+ * The retention will resume automatically if the worker has confirmed that the
4436
+ * retention duration is now within the max_conflict_retention_duration.
4429
4437
*/
4430
4438
static bool
4431
4439
should_stop_conflict_info_retention (RetainConflictInfoData * data )
@@ -4450,19 +4458,26 @@ should_stop_conflict_info_retention(RetainConflictInfoData *data)
4450
4458
max_conflict_retention_duration ))
4451
4459
return false;
4452
4460
4453
- ereport (LOG ,
4454
- errmsg ("logical replication worker for subscription \"%s\" will stop retaining conflict information" ,
4455
- MySubscription -> name ),
4456
- errdetail ("The time spent advancing the non-removable transaction ID has exceeded the maximum limit of %u ms." ,
4457
- max_conflict_retention_duration ));
4458
-
4459
- SpinLockAcquire (& MyLogicalRepWorker -> relmutex );
4460
- MyLogicalRepWorker -> oldest_nonremovable_xid = InvalidFullTransactionId ;
4461
- MyLogicalRepWorker -> stop_conflict_info_retention = true;
4462
- SpinLockRelease (& MyLogicalRepWorker -> relmutex );
4463
-
4464
- /* Notify launcher to invalidate the conflict slot */
4465
- ApplyLauncherWakeup ();
4461
+ /*
4462
+ * Log a message and reset relevant data when the worker is about to stop
4463
+ * retaining conflict information.
4464
+ */
4465
+ if (!MyLogicalRepWorker -> stop_conflict_info_retention )
4466
+ {
4467
+ ereport (LOG ,
4468
+ errmsg ("logical replication worker for subscription \"%s\" will stop retaining conflict information" ,
4469
+ MySubscription -> name ),
4470
+ errdetail ("The time spent advancing the non-removable transaction ID has exceeded the maximum limit of %u ms." ,
4471
+ max_conflict_retention_duration ));
4472
+
4473
+ SpinLockAcquire (& MyLogicalRepWorker -> relmutex );
4474
+ MyLogicalRepWorker -> oldest_nonremovable_xid = InvalidFullTransactionId ;
4475
+ MyLogicalRepWorker -> stop_conflict_info_retention = true;
4476
+ SpinLockRelease (& MyLogicalRepWorker -> relmutex );
4477
+
4478
+ /* Notify launcher to invalidate the conflict slot */
4479
+ ApplyLauncherWakeup ();
4480
+ }
4466
4481
4467
4482
reset_conflict_info_fields (data );
4468
4483
@@ -4510,51 +4525,6 @@ adjust_xid_advance_interval(RetainConflictInfoData *data, bool new_xid_found)
4510
4525
}
4511
4526
}
4512
4527
4513
- /*
4514
- * Update the conflict retention status for the current apply worker. It checks
4515
- * whether the worker should stop retaining conflict information due to
4516
- * invalidation of the replication slot ("pg_conflict_detection").
4517
- *
4518
- * Currently, the replication slot is invalidated only if the duration for
4519
- * retaining conflict information exceeds the allowed maximum.
4520
- */
4521
- static void
4522
- update_conflict_retention_status (void )
4523
- {
4524
- ReplicationSlotInvalidationCause cause = RS_INVAL_NONE ;
4525
- ReplicationSlot * slot ;
4526
-
4527
- /* Exit early if retaining conflict information is not required */
4528
- if (!MySubscription -> retainconflictinfo )
4529
- return ;
4530
-
4531
- /*
4532
- * Only the leader apply worker manages conflict retention (see
4533
- * maybe_advance_nonremovable_xid() for details).
4534
- */
4535
- if (!am_leader_apply_worker ())
4536
- return ;
4537
-
4538
- LWLockAcquire (ReplicationSlotControlLock , LW_SHARED );
4539
-
4540
- slot = SearchNamedReplicationSlot (CONFLICT_DETECTION_SLOT , false);
4541
-
4542
- if (slot )
4543
- {
4544
- SpinLockAcquire (& slot -> mutex );
4545
- cause = slot -> data .invalidated ;
4546
- SpinLockRelease (& slot -> mutex );
4547
-
4548
- Assert (cause == RS_INVAL_NONE || cause == RS_INVAL_CONFLICT_RETENTION_DURATION );
4549
- }
4550
-
4551
- LWLockRelease (ReplicationSlotControlLock );
4552
-
4553
- SpinLockAcquire (& MyLogicalRepWorker -> relmutex );
4554
- MyLogicalRepWorker -> stop_conflict_info_retention = cause != RS_INVAL_NONE ;
4555
- SpinLockRelease (& MyLogicalRepWorker -> relmutex );
4556
- }
4557
-
4558
4528
/*
4559
4529
* Exit routine for apply workers due to subscription parameter changes.
4560
4530
*/
@@ -4726,16 +4696,6 @@ maybe_reread_subscription(void)
4726
4696
CommitTransactionCommand ();
4727
4697
4728
4698
MySubscriptionValid = true;
4729
-
4730
- /*
4731
- * Update worker status to avoid unnecessary conflict retention if the
4732
- * replication slot ("pg_conflict_detection") was invalidated prior to
4733
- * enabling the retain_conflict_info option. This is also necessary to
4734
- * restart conflict retention if the user has disabled and subsequently
4735
- * re-enabled the retain_conflict_info option, resulting in the
4736
- * replication slot being recreated.
4737
- */
4738
- update_conflict_retention_status ();
4739
4699
}
4740
4700
4741
4701
/*
@@ -5382,8 +5342,6 @@ InitializeLogRepWorker(void)
5382
5342
MySubscription -> name )));
5383
5343
5384
5344
CommitTransactionCommand ();
5385
-
5386
- update_conflict_retention_status ();
5387
5345
}
5388
5346
5389
5347
/*
0 commit comments