From b171eb533f4dd14f9f5082b469e5218c1bf13682 Mon Sep 17 00:00:00 2001 From: Petr Jelinek Date: Tue, 21 Feb 2017 20:14:44 +0100 Subject: [PATCH 2/5] Don't use on disk snapshots for snapshot export in logical decoding We store historical snapshots on disk to enable continuation of logical decoding after restart. These snapshots were also used bu slot initialiation code for initial snapshot that the slot exports to aid synchronization of data copy and the stream consumption. However these snapshots are only useful for catalogs and not for normal user tables. So when we exported such snapshots for user to read data from tables that is consistent with a specific LSN of slot creation, user would instead read wrong data. This patch changes the code so that stored snapshots are only used for logical decoding restart but not for initial slot snapshot. --- src/backend/replication/logical/snapbuild.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 6f19cdc..4b0c1e0 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -1214,7 +1214,7 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn * * a) There were no running transactions when the xl_running_xacts record * was inserted, jump to CONSISTENT immediately. We might find such a - * state we were waiting for b) and c). + * state we were waiting for b) or c). * * b) Wait for all toplevel transactions that were running to end. We * simply track the number of in-progress toplevel transactions and @@ -1229,7 +1229,9 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn * at all. * * c) This (in a previous run) or another decoding slot serialized a - * snapshot to disk that we can use. + * snapshot to disk that we can use. We can't use this method for the + * initial snapshot when slot is being created as that snapshot may be + * exported and used for reading user data. * --- */ @@ -1284,13 +1286,13 @@ SnapBuildFindSnapshot(SnapBuild *builder, XLogRecPtr lsn, xl_running_xacts *runn return false; } - /* c) valid on disk state */ - else if (SnapBuildRestore(builder, lsn)) + /* c) valid on disk state and not exported snapshot */ + else if (!TransactionIdIsNormal(builder->initial_xmin_horizon) && + SnapBuildRestore(builder, lsn)) { /* there won't be any state to cleanup */ return false; } - /* * b) first encounter of a useable xl_running_xacts record. If we had * found one earlier we would either track running transactions (i.e. -- 2.7.4