Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0ec3c29

Browse files
author
Amit Kapila
committed
Avoid updating inactive_since for invalid replication slots.
It is possible for the inactive_since value of an invalid replication slot to be updated multiple times, which is unexpected behavior like during the release of the slot or at the time of restart. This is harmless because invalid slots are not allowed to be accessed but it is not prudent to update invalid slots. We are planning to invalidate slots due to other reasons like idle time and it will look odd that the slot's inactive_since displays the recent time in this field after invalidated due to idle time. So, this patch ensures that the inactive_since field of slots is not updated for invalid slots. In the passing, ensure to use the same inactive_since time for all the slots at restart while restoring them from the disk. Author: Nisha Moond <nisha.moond412@gmail.com> Author: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Vignesh C <vignesh21@gmail.com> Reviewed-by: Peter Smith <smithpb2250@gmail.com> Reviewed-by: Hou Zhijie <houzj.fnst@fujitsu.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Discussion: https://postgr.es/m/CABdArM7QdifQ_MHmMA=Cc4v8+MeckkwKncm2Nn6tX9wSCQ-+iw@mail.gmail.com
1 parent b2bdb97 commit 0ec3c29

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

doc/src/sgml/system-views.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2566,7 +2566,8 @@ SELECT * FROM pg_locks pl LEFT JOIN pg_prepared_xacts ppx
25662566
</para>
25672567
<para>
25682568
The time when the slot became inactive. <literal>NULL</literal> if the
2569-
slot is currently being streamed.
2569+
slot is currently being streamed. If the slot becomes invalid,
2570+
this value will never be updated.
25702571
Note that for slots on the standby that are being synced from a
25712572
primary server (whose <structfield>synced</structfield> field is
25722573
<literal>true</literal>), the <structfield>inactive_since</structfield>

src/backend/replication/logical/slotsync.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,9 +1541,7 @@ update_synced_slots_inactive_since(void)
15411541
if (now == 0)
15421542
now = GetCurrentTimestamp();
15431543

1544-
SpinLockAcquire(&s->mutex);
1545-
s->inactive_since = now;
1546-
SpinLockRelease(&s->mutex);
1544+
ReplicationSlotSetInactiveSince(s, now, true);
15471545
}
15481546
}
15491547

src/backend/replication/slot.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -644,9 +644,7 @@ ReplicationSlotAcquire(const char *name, bool nowait, bool error_if_invalid)
644644
* Reset the time since the slot has become inactive as the slot is active
645645
* now.
646646
*/
647-
SpinLockAcquire(&s->mutex);
648-
s->inactive_since = 0;
649-
SpinLockRelease(&s->mutex);
647+
ReplicationSlotSetInactiveSince(s, 0, true);
650648

651649
if (am_walsender)
652650
{
@@ -720,16 +718,12 @@ ReplicationSlotRelease(void)
720718
*/
721719
SpinLockAcquire(&slot->mutex);
722720
slot->active_pid = 0;
723-
slot->inactive_since = now;
721+
ReplicationSlotSetInactiveSince(slot, now, false);
724722
SpinLockRelease(&slot->mutex);
725723
ConditionVariableBroadcast(&slot->active_cv);
726724
}
727725
else
728-
{
729-
SpinLockAcquire(&slot->mutex);
730-
slot->inactive_since = now;
731-
SpinLockRelease(&slot->mutex);
732-
}
726+
ReplicationSlotSetInactiveSince(slot, now, true);
733727

734728
MyReplicationSlot = NULL;
735729

@@ -2218,6 +2212,7 @@ RestoreSlotFromDisk(const char *name)
22182212
bool restored = false;
22192213
int readBytes;
22202214
pg_crc32c checksum;
2215+
TimestampTz now = 0;
22212216

22222217
/* no need to lock here, no concurrent access allowed yet */
22232218

@@ -2408,9 +2403,13 @@ RestoreSlotFromDisk(const char *name)
24082403
/*
24092404
* Set the time since the slot has become inactive after loading the
24102405
* slot from the disk into memory. Whoever acquires the slot i.e.
2411-
* makes the slot active will reset it.
2406+
* makes the slot active will reset it. Use the same inactive_since
2407+
* time for all the slots.
24122408
*/
2413-
slot->inactive_since = GetCurrentTimestamp();
2409+
if (now == 0)
2410+
now = GetCurrentTimestamp();
2411+
2412+
ReplicationSlotSetInactiveSince(slot, now, false);
24142413

24152414
restored = true;
24162415
break;

src/include/replication/slot.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ typedef struct ReplicationSlotCtlData
228228
ReplicationSlot replication_slots[1];
229229
} ReplicationSlotCtlData;
230230

231+
/*
232+
* Set slot's inactive_since property unless it was previously invalidated.
233+
*/
234+
static inline void
235+
ReplicationSlotSetInactiveSince(ReplicationSlot *s, TimestampTz ts,
236+
bool acquire_lock)
237+
{
238+
if (acquire_lock)
239+
SpinLockAcquire(&s->mutex);
240+
241+
if (s->data.invalidated == RS_INVAL_NONE)
242+
s->inactive_since = ts;
243+
244+
if (acquire_lock)
245+
SpinLockRelease(&s->mutex);
246+
}
247+
231248
/*
232249
* Pointers to shared memory
233250
*/

0 commit comments

Comments
 (0)