8000 Handle logical slot conflicts on standby · postgrespro/postgres@2666975 · GitHub
[go: up one dir, main page]

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
10000 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)
0