#include "pgxc/pgxc.h"
#include "access/gtm.h"
#include "storage/ipc.h"
+#include "utils/guc.h"
/* PGXC_DATANODE */
#include "postmaster/autovacuum.h"
#endif
static void KnownAssignedXidsDisplay(int trace_level);
static void KnownAssignedXidsReset(void);
+#ifdef XCP
+int GlobalSnapshotSource;
+#endif
+
/*
* Report shared-memory space needed by CreateSharedProcArray.
*/
#ifdef PGXC /* PGXC_DATANODE */
/*
- * Obtain a global snapshot for a Postgres-XC session
- * if possible.
- */
- if (GetPGXCSnapshotData(snapshot))
- return snapshot;
- /*
- * We only make one exception for using local snapshot and that's the
- * initdb time. When IsPostmasterEnvironment is true, snapshots must either
- * be pushed down from the coordinator or directly obtained from the
- * GTM.
- *
- * !!TODO We don't seem to fully support Hot Standby. So why should we even
- * exempt RecoveryInProgress()?
- */
- if (IsPostmasterEnvironment && !useLocalXid)
- elog(ERROR, "Was unable to obtain a snapshot from GTM.");
+ * If the user has chosen to work with a coordinator-local snapshot, just
+ * compute snapshot locally. This can have adverse effects on the global
+ * consistency, in a multi-coordinator environment, but also in a
+ * single-coordinator setup because our recent changes to transaction
+ * management now allows datanodes to start global snapshots or more
+ * precisely attach current transaction to a global transaction. But users
+ * may still want to use this model for performance of their XL cluster, at
+ * the cost of reduced global consistency
+ */
+ if (GlobalSnapshotSource == GLOBAL_SNAPSHOT_SOURCE_GTM)
+ {
+ /*
+ * Obtain a global snapshot for a Postgres-XC session
+ * if possible.
+ */
+ if (GetPGXCSnapshotData(snapshot))
+ return snapshot;
+ /*
+ * We only make one exception for using local snapshot and that's the
+ * initdb time. When IsPostmasterEnvironment is true, snapshots must
+ * either be pushed down from the coordinator or directly obtained from
+ * the GTM.
+ *
+ * !!TODO We don't seem to fully support Hot Standby. So why should we
+ * even exempt RecoveryInProgress()?
+ */
+ if (IsPostmasterEnvironment && !useLocalXid)
+ elog(ERROR, "Was unable to obtain a snapshot from GTM.");
+ }
#endif
/*
globalSnapshot.snapshot_source == SNAPSHOT_DIRECT)
&& TransactionIdIsValid(globalSnapshot.gxmin))
{
- int index;
- ProcArrayStruct *arrayP = procArray;
TransactionId global_xmin;
snapshot->xmin = globalSnapshot.gxmin;
for (index = 0; index < arrayP->numProcs; index++)
{
int pgprocno = arrayP->pgprocnos[index];
- volatile PGPROC *proc = &allProcs[pgprocno];
volatile PGXACT *pgxact = &allPgXact[pgprocno];
TransactionId xid;
#include "pgxc/poolmgr.h"
#include "pgxc/nodemgr.h"
#include "pgxc/xc_maintenance_mode.h"
+#include "storage/procarray.h"
#endif
#ifdef XCP
#include "commands/sequence.h"
+#include "parser/parse_utilcmd.h"
#include "pgxc/nodemgr.h"
#include "pgxc/squeue.h"
#include "utils/snapmgr.h"
-#include "parser/parse_utilcmd.h"
#endif
#include "postmaster/autovacuum.h"
#include "postmaster/bgworker.h"
{NULL, 0, false}
};
+#ifdef XCP
+/*
+ * Set global-snapshot source. 'gtm' is default, but user can choose
+ * 'coordinator' for performance improvement at the cost of reduced consistency
+ */
+static const struct config_enum_entry global_snapshot_source_options[] = {
+ {"gtm", GLOBAL_SNAPSHOT_SOURCE_GTM, true},
+ {"coordinator", GLOBAL_SNAPSHOT_SOURCE_COORDINATOR, true},
+ {NULL, 0, false}
+};
+#endif
+
/*
* Options for enum values stored in other modules
*/
NULL, NULL, NULL
},
+#ifdef XCP
+ {
+ {"global_snapshot_source", PGC_USERSET, DEVELOPER_OPTIONS,
+ gettext_noop("Set preferred source of a snapshot."),
+ gettext_noop("When set to 'coordinator', a snapshot is taken at "
+ "the coordinator at the risk of reduced consistency. "
+ "Default is 'gtm'")
+ },
+ &GlobalSnapshotSource,
+ GLOBAL_SNAPSHOT_SOURCE_GTM, global_snapshot_source_options,
+ NULL, NULL, NULL
+ },
+#endif
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL