aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/procarray.c
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2017-04-23 20:41:29 -0700
committerAndres Freund <andres@anarazel.de>2017-04-27 13:13:36 -0700
commit28afff347a5db51a02b269fa13677d6924a88e78 (patch)
tree0640f822e9722054c967eb8036c753348a3bf11a /src/backend/storage/ipc/procarray.c
parent866452cd8b52b0231e159eab4201d86d9164ab69 (diff)
downloadpostgresql-28afff347a5db51a02b269fa13677d6924a88e78.tar.gz
postgresql-28afff347a5db51a02b269fa13677d6924a88e78.zip
Preserve required !catalog tuples while computing initial decoding snapshot.
The logical decoding machinery already preserved all the required catalog tuples, which is sufficient in the course of normal logical decoding, but did not guarantee that non-catalog tuples were preserved during computation of the initial snapshot when creating a slot over the replication protocol. This could cause a corrupted initial snapshot being exported. The time window for issues is usually not terribly large, but on a busy server it's perfectly possible to it hit it. Ongoing decoding is not affected by this bug. To avoid increased overhead for the SQL API, only retain additional tuples when a logical slot is being created over the replication protocol. To do so this commit changes the signature of CreateInitDecodingContext(), but it seems unlikely that it's being used in an extension, so that's probably ok. In a drive-by fix, fix handling of ReplicationSlotsComputeRequiredXmin's already_locked argument, which should only apply to ProcArrayLock, not ReplicationSlotControlLock. Reported-By: Erik Rijkers Analyzed-By: Petr Jelinek Author: Petr Jelinek, heavily editorialized by Andres Freund Reviewed-By: Andres Freund Discussion: https://postgr.es/m/9a897b86-46e1-9915-ee4c-da02e4ff6a95@2ndquadrant.com Backport: 9.4, where logical decoding was introduced.
Diffstat (limited to 'src/backend/storage/ipc/procarray.c')
-rw-r--r--src/backend/storage/ipc/procarray.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 651c561dfd5..a3a0207872d 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2153,7 +2153,7 @@ GetOldestActiveTransactionId(void)
* that the caller will immediately use the xid to peg the xmin horizon.
*/
TransactionId
-GetOldestSafeDecodingTransactionId(void)
+GetOldestSafeDecodingTransactionId(bool catalogOnly)
{
ProcArrayStruct *arrayP = procArray;
TransactionId oldestSafeXid;
@@ -2176,9 +2176,17 @@ GetOldestSafeDecodingTransactionId(void)
/*
* If there's already a slot pegging the xmin horizon, we can start with
* that value, it's guaranteed to be safe since it's computed by this
- * routine initially and has been enforced since.
+ * routine initially and has been enforced since. We can always use the
+ * slot's general xmin horizon, but the catalog horizon is only usable
+ * when we only catalog data is going to be looked at.
*/
- if (TransactionIdIsValid(procArray->replication_slot_catalog_xmin) &&
+ if (TransactionIdIsValid(procArray->replication_slot_xmin) &&
+ TransactionIdPrecedes(procArray->replication_slot_xmin,
+ oldestSafeXid))
+ oldestSafeXid = procArray->replication_slot_xmin;
+
+ if (catalogOnly &&
+ TransactionIdIsValid(procArray->replication_slot_catalog_xmin) &&
TransactionIdPrecedes(procArray->replication_slot_catalog_xmin,
oldestSafeXid))
oldestSafeXid = procArray->replication_slot_catalog_xmin;