hotstandby-serializable-3.patch
application/octet-stream
Filename: hotstandby-serializable-3.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/commands/variable.c | 6 | 0 |
| src/backend/storage/lmgr/predicate.c | 19 | 0 |
| src/backend/utils/init/postinit.c | 8 | 0 |
*** a/src/backend/commands/variable.c
--- b/src/backend/commands/variable.c
***************
*** 613,625 **** check_XactIsoLevel(char **newval, void **extra, GucSource source)
GUC_check_errmsg("SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction");
return false;
}
! /* Can't go to serializable mode while recovery is still active */
! if (newXactIsoLevel == XACT_SERIALIZABLE && RecoveryInProgress())
! {
! GUC_check_errmsg("cannot use serializable mode in a hot standby");
! GUC_check_errhint("You can use REPEATABLE READ instead.");
! return false;
! }
}
*extra = malloc(sizeof(int));
--- 613,624 ----
GUC_check_errmsg("SET TRANSACTION ISOLATION LEVEL must not be called in a subtransaction");
return false;
}
! /*
! * NOTE: We cannot check for an attempt to set SERIALIZABLE
! * transactions on a hot standby here, because when that is set as the
! * default, this would get called before shared memory is even set up.
! * Instead, this is checked when a serializable snapshot is requested.
! */
}
*extra = malloc(sizeof(int));
*** a/src/backend/storage/lmgr/predicate.c
--- b/src/backend/storage/lmgr/predicate.c
***************
*** 1572,1577 **** GetSerializableTransactionSnapshot(Snapshot snapshot)
--- 1572,1596 ----
Assert(IsolationIsSerializable());
/*
+ * Can't use serializable mode while recovery is still active, as it is,
+ * for example, on a hot standby.
+ */
+ if (RecoveryInProgress())
+ {
+ if (DefaultXactIsoLevel == XACT_SERIALIZABLE)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot use SERIALIZABLE mode in a hot standby"),
+ errdetail("\"default_transaction_isolation\" is set to \"serializable\"."),
+ errhint("You can use \"SET default_transaction_isolation = 'repeatable read'\" to change the default.")));
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot use SERIALIZABLE mode in a hot standby"),
+ errhint("You can use REPEATABLE READ instead.")));
+ }
+
+ /*
* A special optimization is available for SERIALIZABLE READ ONLY
* DEFERRABLE transactions -- we can wait for a suitable snapshot and
* thereby avoid all SSI overhead once it's running.
*** a/src/backend/utils/init/postinit.c
--- b/src/backend/utils/init/postinit.c
***************
*** 584,589 **** InitPostgres(const char *in_dbname, Oid dboid, const char *username,
--- 584,597 ----
/* statement_timestamp must be set for timeouts to work correctly */
SetCurrentStatementStartTimestamp();
StartTransactionCommand();
+
+ /*
+ * transaction_isolation will have been set to the default by the
+ * above. Connection to a hot standby will have a problem here if we
+ * are in 'serializable' mode, so force isolation to something safe.
+ */
+ SetConfigOption("transaction_isolation", "read committed",
+ PGC_SUSET, PGC_S_OVERRIDE);
(void) GetTransactionSnapshot();
}