mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Correct logical decoding status at end of recovery with minimal WAL level.
Crash recovery running with wal_level='minimal' can replay an
XLOG_LOGICAL_DECODING_STATUS_CHANGE record that activates logical
decoding, if the server previously ran with a higher wal_level and
crashed after the last logical slot was dropped but before the
checkpointer deactivated logical decoding. Replaying such a record is
correct since it reflects the status at the time it was
written. However, UpdateLogicalDecodingStatusEndOfRecovery() asserted
that logical decoding is never active with wal_level='minimal',
causing an assertion failure at the end of recovery. In production
builds, logical decoding would remain active while running with
wal_level='minimal'.
Instead of special-casing wal_level='minimal', recompute the status at
the end of recovery as usual: no logical slot can exist with
wal_level='minimal' as RestoreSlotFromDisk() would have rejected it,
so the recomputation always deactivates logical decoding in this case,
also writing the corresponding status change record.
Oversight in 67c20979ce.
Reviewed-by: Guoqing Yang <yanggq1988@126.com>
Reviewed-by: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Discussion: https://postgr.es/m/CAD21AoAnPAugUnDic+ESvrfXjXHk2bss9eHAD7zP0-Chy2UabA@mail.gmail.com
Backpatch-through: 19
This commit is contained in:
@@ -561,19 +561,17 @@ UpdateLogicalDecodingStatusEndOfRecovery(void)
|
||||
|
||||
Assert(RecoveryInProgress());
|
||||
|
||||
/*
|
||||
* With 'minimal' WAL level, there are no logical replication slots during
|
||||
* recovery. Logical decoding is always disabled, so there is no need to
|
||||
* synchronize XLogLogicalInfo.
|
||||
*/
|
||||
if (wal_level == WAL_LEVEL_MINIMAL)
|
||||
{
|
||||
Assert(!IsXLogLogicalInfoEnabled() && !IsLogicalDecodingEnabled());
|
||||
return;
|
||||
}
|
||||
|
||||
LWLockAcquire(LogicalDecodingControlLock, LW_EXCLUSIVE);
|
||||
|
||||
/*
|
||||
* With 'minimal' WAL level, no logical replication slot can exist (see
|
||||
* RestoreSlotFromDisk()), so the new status is always false. However,
|
||||
* logical decoding could have been enabled during recovery by replaying
|
||||
* an XLOG_LOGICAL_DECODING_STATUS_CHANGE record from WAL generated with a
|
||||
* higher wal_level, e.g. if the server crashed right after the last
|
||||
* logical slot was dropped and then restarted with wal_level='minimal'.
|
||||
* The code below disables logical decoding in that case.
|
||||
*/
|
||||
if (wal_level == WAL_LEVEL_LOGICAL || CheckLogicalSlotExists())
|
||||
new_status = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user