diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2020-06-24 14:15:17 -0400 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2020-06-24 14:15:17 -0400 |
commit | 12e52ba5a76e56aacdfbbb269e6b45c53d80c477 (patch) | |
tree | b33a4d46713ebdadb9bc320edab0bf1725cbc2ec | |
parent | 411493d701e2f97e778dc1ff14fb7169eea2e94c (diff) | |
download | postgresql-12e52ba5a76e56aacdfbbb269e6b45c53d80c477.tar.gz postgresql-12e52ba5a76e56aacdfbbb269e6b45c53d80c477.zip |
Save slot's restart_lsn when invalidated due to size
We put it aside as invalidated_at, which let us show "lost" in
pg_replication slot. Prior to this change, the state value was reported
as NULL.
Backpatch to 13.
Author: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org>
Discussion: https://postgr.es/m/20200617.101707.1735599255100002667.horikyota.ntt@gmail.com
Discussion: https://postgr.es/m/20200407.120905.1507671100168805403.horikyota.ntt@gmail.com
-rw-r--r-- | src/backend/replication/slot.c | 1 | ||||
-rw-r--r-- | src/backend/replication/slotfuncs.c | 11 | ||||
-rw-r--r-- | src/include/access/xlog.h | 2 | ||||
-rw-r--r-- | src/include/replication/slot.h | 3 | ||||
-rw-r--r-- | src/test/recovery/t/019_replslot_limit.pl | 2 |
5 files changed, 16 insertions, 3 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index a7bbcf34991..e8761f3a180 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -1226,6 +1226,7 @@ restart: (uint32) restart_lsn))); SpinLockAcquire(&s->mutex); + s->data.invalidated_at = s->data.restart_lsn; s->data.restart_lsn = InvalidXLogRecPtr; SpinLockRelease(&s->mutex); ReplicationSlotRelease(); diff --git a/src/backend/replication/slotfuncs.c b/src/backend/replication/slotfuncs.c index 06e4955de73..3fc54cb9bab 100644 --- a/src/backend/replication/slotfuncs.c +++ b/src/backend/replication/slotfuncs.c @@ -283,6 +283,7 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) bool nulls[PG_GET_REPLICATION_SLOTS_COLS]; WALAvailability walstate; XLogSegNo last_removed_seg; + XLogRecPtr targetLSN; int i; if (!slot->in_use) @@ -342,7 +343,15 @@ pg_get_replication_slots(PG_FUNCTION_ARGS) else nulls[i++] = true; - walstate = GetWALAvailability(slot_contents.data.restart_lsn); + /* + * Report availability from invalidated_at when the slot has been + * invalidated; otherwise slots would appear as invalid without any + * more clues as to what happened. + */ + targetLSN = XLogRecPtrIsInvalid(slot_contents.data.restart_lsn) ? + slot_contents.data.invalidated_at : + slot_contents.data.restart_lsn; + walstate = GetWALAvailability(targetLSN); switch (walstate) { diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index e917dfe92d8..12d7b89e7ac 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -326,7 +326,7 @@ extern void ShutdownXLOG(int code, Datum arg); extern void InitXLOGAccess(void); extern void CreateCheckPoint(int flags); extern bool CreateRestartPoint(int flags); -extern WALAvailability GetWALAvailability(XLogRecPtr restart_lsn); +extern WALAvailability GetWALAvailability(XLogRecPtr targetLSN); extern XLogRecPtr CalculateMaxmumSafeLSN(void); extern void XLogPutNextOid(Oid nextOid); extern XLogRecPtr XLogRestorePoint(const char *rpName); diff --git a/src/include/replication/slot.h b/src/include/replication/slot.h index 917876010eb..31362585ecb 100644 --- a/src/include/replication/slot.h +++ b/src/include/replication/slot.h @@ -79,6 +79,9 @@ typedef struct ReplicationSlotPersistentData /* oldest LSN that might be required by this replication slot */ XLogRecPtr restart_lsn; + /* restart_lsn is copied here when the slot is invalidated */ + XLogRecPtr invalidated_at; + /* * Oldest LSN that the client has acked receipt for. This is used as the * start_lsn point in case the client doesn't specify one, and also as a diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl index cba7df920c0..f1be984cc9a 100644 --- a/src/test/recovery/t/019_replslot_limit.pl +++ b/src/test/recovery/t/019_replslot_limit.pl @@ -186,7 +186,7 @@ ok( find_in_log( $result = $node_master->safe_psql('postgres', "SELECT slot_name, active, restart_lsn IS NULL, wal_status, min_safe_lsn FROM pg_replication_slots WHERE slot_name = 'rep1'" ); -is($result, "rep1|f|t||", 'check that the slot became inactive'); +is($result, "rep1|f|t|lost|", 'check that the slot became inactive'); # The standby no longer can connect to the master $logstart = get_log_size($node_standby); |