Skip to content

Commit 2666975

Browse files
committed
Handle logical slot conflicts on standby
During WAL replay on the standby, when a conflict with a logical slot is identified, invalidate such slots. There are two sources of conflicts: 1) Using the information added in 6af1793, logical slots are invalidated if required rows are removed 2) wal_level on the primary server is reduced to below logical Uses the infrastructure introduced in the prior commit. FIXME: add commit reference. Change InvalidatePossiblyObsoleteSlot() to use a recovery conflict to interrupt use of a slot, if called in the startup process. The new recovery conflict is added to pg_stat_database_conflicts, as confl_active_logicalslot. See 6af1793 for an overall design of logical decoding on a standby. Bumps catversion for the addition of the pg_stat_database_conflicts column. Bumps PGSTAT_FILE_FORMAT_ID for the same reason. Author: "Drouvot, Bertrand" <bertranddrouvot.pg@gmail.com> Author: Andres Freund <andres@anarazel.de> Author: Amit Khandekar <amitdkhan.pg@gmail.com> (in an older version) Reviewed-by: "Drouvot, Bertrand" <bertranddrouvot.pg@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Fabrízio de Royes Mello <fabriziomello@gmail.com> Reviewed-by: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/20230407075009.igg7be27ha2htkbt@awork3.anarazel.de
1 parent be87200 commit 2666975

File tree

20 files changed

+95
-6
lines changed

20 files changed

+95
-6
lines changed

doc/src/sgml/monitoring.sgml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4742,6 +4742,17 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
47424742
deadlocks
47434743
</para></entry>
47444744
</row>
4745+
4746+
<row>
4747+
<entry role="catalog_table_entry"><para role="column_definition">
4748+
<structfield>confl_active_logicalslot</structfield> <type>bigint</type>
4749+
</para>
4750+
<para>
4751+
Number of uses of logical slots in this database that have been
4752+
canceled due to old snapshots or a too low <xref linkend="guc-wal-level"/>
4753+
on the primary
4754+
</para></entry>
4755+
</row>
47454756
</tbody>
47464757
</tgroup>
47474758
</table>

src/backend/access/gist/gistxlog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ gistRedoDeleteRecord(XLogReaderState *record)
197197
XLogRecGetBlockTag(record, 0, &rlocator, NULL, NULL);
198198

199199
ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
200+
xldata->isCatalogRel,
200201
rlocator);
201202
}
202203

@@ -390,6 +391,7 @@ gistRedoPageReuse(XLogReaderState *record)
390391
*/
391392
if (InHotStandby)
392393
ResolveRecoveryConflictWithSnapshotFullXid(xlrec->snapshotConflictHorizon,
394+
xlrec->isCatalogRel,
393395
xlrec->locator);
394396
}
395397

src/backend/access/hash/hash_xlog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,7 @@ hash_xlog_vacuum_one_page(XLogReaderState *record)
10031003

10041004
XLogRecGetBlockTag(record, 0, &rlocator, NULL, NULL);
10051005
ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
1006+
xldata->isCatalogRel,
10061007
rlocator);
10071008
}
10081009

src/backend/access/heap/heapam.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8769,6 +8769,7 @@ heap_xlog_prune(XLogReaderState *record)
87698769
*/
87708770
if (InHotStandby)
87718771
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
8772+
xlrec->isCatalogRel,
87728773
rlocator);
87738774

87748775
/*
@@ -8940,6 +8941,7 @@ heap_xlog_visible(XLogReaderState *record)
89408941
*/
89418942
if (InHotStandby)
89428943
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
8944+
xlrec->flags & VISIBILITYMAP_XLOG_CATALOG_REL,
89438945
rlocator);
89448946

89458947
/*
@@ -9061,6 +9063,7 @@ heap_xlog_freeze_page(XLogReaderState *record)
90619063

90629064
XLogRecGetBlockTag(record, 0, &rlocator, NULL, NULL);
90639065
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
9066+
xlrec->isCatalogRel,
90649067
rlocator);
90659068
}
90669069

src/backend/access/nbtree/nbtxlog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ btree_xlog_delete(XLogReaderState *record)
669669
XLogRecGetBlockTag(record, 0, &rlocator, NULL, NULL);
670670

671671
ResolveRecoveryConflictWithSnapshot(xlrec->snapshotConflictHorizon,
672+
xlrec->isCatalogRel,
672673
rlocator);
673674
}
674675

@@ -1007,6 +1008,7 @@ btree_xlog_reuse_page(XLogReaderState *record)
10071008

10081009
if (InHotStandby)
10091010
ResolveRecoveryConflictWithSnapshotFullXid(xlrec->snapshotConflictHorizon,
1011+
xlrec->isCatalogRel,
10101012
xlrec->locator);
10111013
}
10121014

src/backend/access/spgist/spgxlog.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,7 @@ spgRedoVacuumRedirect(XLogReaderState *record)
879879

880880
XLogRecGetBlockTag(record, 0, &locator, NULL, NULL);
881881
ResolveRecoveryConflictWithSnapshot(xldata->snapshotConflictHorizon,
882+
xldata->isCatalogRel,
882883
locator);
883884
}
884885

src/backend/access/transam/xlog.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7970,6 +7970,21 @@ xlog_redo(XLogReaderState *record)
79707970
/* Update our copy of the parameters in pg_control */
79717971
memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change));
79727972

7973+
/*
7974+
* Invalidate logical slots if we are in hot standby and the primary
7975+
* does not have a WAL level sufficient for logical decoding. No need
7976+
* to search for potentially conflicting logically slots if standby is
7977+
* running with wal_level lower than logical, because in that case, we
7978+
* would have either disallowed creation of logical slots or
7979+
* invalidated existing ones.
7980+
*/
7981+
if (InRecovery && InHotStandby &&
7982+
xlrec.wal_level < WAL_LEVEL_LOGICAL &&
7983+
wal_level >= WAL_LEVEL_LOGICAL)
7984+
InvalidateObsoleteReplicationSlots(RS_INVAL_WAL_LEVEL,
7985+
0, InvalidOid,
7986+
InvalidTransactionId);
7987+
79737988
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
79747989
ControlFile->MaxConnections = xlrec.MaxConnections;
79757990
ControlFile->max_worker_processes = xlrec.max_worker_processes;

src/backend/catalog/system_views.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,7 +1069,8 @@ CREATE VIEW pg_stat_database_conflicts AS
10691069
pg_stat_get_db_conflict_lock(D.oid) AS confl_lock,
10701070
pg_stat_get_db_conflict_snapshot(D.oid) AS confl_snapshot,
10711071
pg_stat_get_db_conflict_bufferpin(D.oid) AS confl_bufferpin,
1072-
pg_stat_get_db_conflict_startup_deadlock(D.oid) AS confl_deadlock
1072+
pg_stat_get_db_conflict_startup_deadlock(D.oid) AS confl_deadlock,
1073+
pg_stat_get_db_conflict_logicalslot(D.oid) AS confl_active_logicalslot
10731074
FROM pg_database D;
10741075

10751076
CREATE VIEW pg_stat_user_functions AS

src/backend/replication/slot.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,13 @@ InvalidatePossiblyObsoleteSlot(ReplicationSlotInvalidationCause cause,
14421442
slotname, restart_lsn,
14431443
oldestLSN, snapshotConflictHorizon);
14441444

1445-
(void) kill(active_pid, SIGTERM);
1445+
if (MyBackendType == B_STARTUP)
1446+
(void) SendProcSignal(active_pid,
1447+
PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT,
1448+
InvalidBackendId);
1449+
else
1450+
(void) kill(active_pid, SIGTERM);
1451+
14461452
last_signaled_pid = active_pid;
14471453
}
14481454

src/backend/storage/ipc/procsignal.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,6 +673,9 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
673673
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT))
674674
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);
675675

676+
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT))
677+
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT);
678+
676679
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK))
677680
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
678681

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy