1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-24 09:27:52 +03:00

Don't use on-disk snapshots for exported logical decoding snapshot.

Logical decoding stores historical snapshots on disk, so that logical
decoding can restart without having to reconstruct a snapshot from
scratch (for which the resources are not guaranteed to be present
anymore).  These serialized snapshots were also used when creating a
new slot via the walsender interface, which can export a "full"
snapshot (i.e. one that can read all tables, not just catalog ones).

The problem is that the serialized snapshots are only useful for
catalogs and not for normal user tables.  Thus the use of such a
serialized snapshot could result in an inconsistent snapshot being
exported, which could lead to queries returning wrong data.  This
would only happen if logical slots are created while another logical
slot already exists.

Author: Petr Jelinek
Reviewed-By: Andres Freund
Discussion: https://postgr.es/m/f37e975c-908f-858e-707f-058d3b1eb214@2ndquadrant.com
Backport: 9.4, where logical decoding was introduced.
This commit is contained in:
Andres Freund
2017-04-27 15:28:24 -07:00
parent 47f896b5c2
commit 54270d7ebc
3 changed files with 22 additions and 9 deletions

View File

@@ -111,6 +111,7 @@ static LogicalDecodingContext *
StartupDecodingContext(List *output_plugin_options,
XLogRecPtr start_lsn,
TransactionId xmin_horizon,
bool need_full_snapshot,
XLogPageReadCB read_page,
LogicalOutputPluginWriterPrepareWrite prepare_write,
LogicalOutputPluginWriterWrite do_write)
@@ -170,7 +171,8 @@ StartupDecodingContext(List *output_plugin_options,
ctx->reorder = ReorderBufferAllocate();
ctx->snapshot_builder =
AllocateSnapshotBuilder(ctx->reorder, xmin_horizon, start_lsn);
AllocateSnapshotBuilder(ctx->reorder, xmin_horizon, start_lsn,
need_full_snapshot);
ctx->reorder->private_data = ctx;
@@ -340,7 +342,8 @@ CreateInitDecodingContext(char *plugin,
ReplicationSlotSave();
ctx = StartupDecodingContext(NIL, InvalidXLogRecPtr, xmin_horizon,
read_page, prepare_write, do_write);
need_full_snapshot, read_page, prepare_write,
do_write);
/* call output plugin initialization callback */
old_context = MemoryContextSwitchTo(ctx->context);
@@ -421,7 +424,7 @@ CreateDecodingContext(XLogRecPtr start_lsn,
}
ctx = StartupDecodingContext(output_plugin_options,
start_lsn, InvalidTransactionId,
start_lsn, InvalidTransactionId, false,
read_page, prepare_write, do_write);
/* call output plugin initialization callback */