Hi all, When a standby replays a XLOG_PARAMETER_CHANGE record that lowers wal_level from logical, we invalidate all logical slots only when the standby is in hot standby mode:
if (InRecovery && InHotStandby && xlrec.wal_level < WAL_LEVEL_LOGICAL && wal_level >= WAL_LEVEL_LOGICAL) InvalidateObsoleteReplicationSlots(RS_INVAL_WAL_LEVEL, 0, InvalidOid, InvalidTransactionId); However, it's possible that this record is replayed when not in hot standby mode and the slot is used after the promotion. In this case, the following Assert in xlog_decode() fails: /* * This can occur only on a standby, as a primary would * not allow to restart after changing wal_level < logical * if there is pre-existing logical slot. */ Assert(RecoveryInProgress()); ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("logical decoding on standby requires \"wal_level\" >= \"logical\" on the primary"))); Here is brief steps to reproduce this issue: 1. setup the primary and the standby servers (with hot_standby=on). 2. create a logical slot on the standby. 3. on standby, set hot_standby=off and restart. 4. on primary, lower wal_level to replica and restart. 5. promote the standby and execute the logical decoding. I've attached a small patch to fix this issue. With the patch, we invalidate all logical slots even when not in hot standby, that is, the patch just removes InHotStandby from the condition. Thoughts? Regards, -- Masahiko Sawada Amazon Web Services: https://aws.amazon.com
fix_assertion.patch
Description: Binary data