summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc-xc/src/sgml/config.sgmlin15
-rw-r--r--doc-xc/src/sgml/ref/prepare_transaction.sgmlin6
-rw-r--r--src/backend/access/transam/xact.c14
-rw-r--r--src/backend/pgxc/Makefile2
-rw-r--r--src/backend/pgxc/xc_maintenance_mode/Makefile19
-rw-r--r--src/backend/pgxc/xc_maintenance_mode/xc_maintenance_mode.c5
-rw-r--r--src/backend/tcop/utility.c13
-rw-r--r--src/backend/utils/misc/guc.c74
-rw-r--r--src/include/access/xact.h1
-rw-r--r--src/include/pgxc/xc_maintenance_mode.h12
-rw-r--r--src/include/utils/guc_tables.h7
11 files changed, 166 insertions, 2 deletions
diff --git a/doc-xc/src/sgml/config.sgmlin b/doc-xc/src/sgml/config.sgmlin
index 23bf4a3385..bf6b738548 100644
--- a/doc-xc/src/sgml/config.sgmlin
+++ b/doc-xc/src/sgml/config.sgmlin
@@ -6932,6 +6932,21 @@ LOG: CleanUpLock: deleting: lock(0xb7acd844) id(24688,24696,0,0,0,1)
</listitem>
</varlistentry>
+ <varlistentry id="guc-xc-maintenance-ode" xreflabel="xc_maintenance_mode">
+ <term><varname>xc_maintenance_mode</varname> (<type>bool</type>)</term>
+ <indexterm>
+ <primary><varname>xc_maintenance_mode</> configuration parameter</primary>
+ </indexterm>
+ <listitem>
+ <para>
+ Specify to enter into maintenance mode. Turning this on will change behavior of several statements.
+ </para>
+ <para>
+ This parameter can only be set by superuser with <literal>SET</literal> command. Otherwise, the setting will be ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</sect1>
diff --git a/doc-xc/src/sgml/ref/prepare_transaction.sgmlin b/doc-xc/src/sgml/ref/prepare_transaction.sgmlin
index fca68de0ea..bf62e19741 100644
--- a/doc-xc/src/sgml/ref/prepare_transaction.sgmlin
+++ b/doc-xc/src/sgml/ref/prepare_transaction.sgmlin
@@ -130,6 +130,12 @@ PREPARE TRANSACTION <replaceable class="PARAMETER">transaction_id</replaceable>
coordinator, <command>COMMIT PREPARED</> will be propagated to
these nodes.
</para>
+
+&xconly;
+ <para>
+ Transaction id beginning with <literal>_$XC$</literal> is reserved by COORDINATOR for
+ internal use. You cannot use this form of transaction_id externaly.
+ </para>
<!## end>
&common;
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 89615ee0ec..c831660b23 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -5459,4 +5459,18 @@ IsTransactionLocalNode(bool write)
else
return false;
}
+
+/*
+ * Check if the given xid is form implicit 2PC
+ */
+bool
+IsXidImplicit(const char *xid)
+{
+#define implicit2PC_head "_$XC$"
+ static size_t implicit2PC_head_len = strlen(implicit2PC_head);
+
+ if (strncmp(xid, implicit2PC_head, implicit2PC_head_len))
+ return false;
+ return true;
+}
#endif
diff --git a/src/backend/pgxc/Makefile b/src/backend/pgxc/Makefile
index 14f9b968d3..312b4d330c 100644
--- a/src/backend/pgxc/Makefile
+++ b/src/backend/pgxc/Makefile
@@ -11,6 +11,6 @@ subdir = src/backend/pgxc
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-SUBDIRS = locator plan pool barrier nodemgr
+SUBDIRS = locator plan pool barrier nodemgr xc_maintenance_mode
include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/pgxc/xc_maintenance_mode/Makefile b/src/backend/pgxc/xc_maintenance_mode/Makefile
new file mode 100644
index 0000000000..940cb52ec2
--- /dev/null
+++ b/src/backend/pgxc/xc_maintenance_mode/Makefile
@@ -0,0 +1,19 @@
+#-------------------------------------------------------------------------
+#
+# Makefile--
+# Makefile for barrier
+#
+# Portions Copyright (c) 2010-2011 Nippon Telegraph and Telephone Corporation
+#
+# IDENTIFICATION
+# $PostgreSQL$
+#
+#-------------------------------------------------------------------------
+
+subdir = src/backend/pgxc/xc_maintenance_mode
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+
+OBJS = xc_maintenance_mode.o
+
+include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/pgxc/xc_maintenance_mode/xc_maintenance_mode.c b/src/backend/pgxc/xc_maintenance_mode/xc_maintenance_mode.c
new file mode 100644
index 0000000000..7296b6e8d7
--- /dev/null
+++ b/src/backend/pgxc/xc_maintenance_mode/xc_maintenance_mode.c
@@ -0,0 +1,5 @@
+#include "pgxc/xc_maintenance_mode.h"
+
+bool xc_maintenance_mode;
+GucContext currentGucContext;
+
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 97b75ca249..b29e2b47c8 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -73,6 +73,7 @@
#include "pgxc/nodemgr.h"
#include "pgxc/groupmgr.h"
#include "utils/lsyscache.h"
+#include "pgxc/xc_maintenance_mode.h"
static void ExecUtilityStmtOnNodes(const char *queryString, ExecNodes *nodes,
bool force_autocommit, RemoteQueryExecType exec_type,
@@ -436,6 +437,18 @@ standard_ProcessUtility(Node *parsetree,
case TRANS_STMT_PREPARE:
PreventCommandDuringRecovery("PREPARE TRANSACTION");
+#ifdef PGXC
+ /* Add check if xid is valid */
+ if (IS_PGXC_COORDINATOR && !IsConnFromCoord() && !xc_maintenance_mode)
+ {
+ if (IsXidImplicit((const char *)stmt->gid))
+ {
+ elog(ERROR, "Invalid transaciton_id to prepare.");
+ break;
+ }
+ }
+#endif
+
if (!PrepareTransactionBlock(stmt->gid))
{
/* report unsuccessful commit in completionTag */
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 005fceeb99..d71aef982e 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -62,6 +62,7 @@
#include "nodes/nodes.h"
#include "pgxc/poolmgr.h"
#include "pgxc/nodemgr.h"
+#include "pgxc/xc_maintenance_mode.h"
#endif
#include "postmaster/autovacuum.h"
#include "postmaster/bgwriter.h"
@@ -197,6 +198,9 @@ static bool check_bonjour(bool *newval, void **extra, GucSource source);
static bool check_ssl(bool *newval, void **extra, GucSource source);
static bool check_stage_log_stats(bool *newval, void **extra, GucSource source);
static bool check_log_stats(bool *newval, void **extra, GucSource source);
+#ifdef PGXC
+static bool check_pgxc_maintenance_mode(bool *newval, void **extra, GucSource source);
+#endif
static bool check_canonical_path(char **newval, void **extra, GucSource source);
static bool check_timezone_abbreviations(char **newval, void **extra, GucSource source);
static void assign_timezone_abbreviations(const char *newval, void *extra);
@@ -636,6 +640,10 @@ const char *const config_group_names[] =
gettext_noop("Datanodes and Connection Pooling"),
/* GTM */
gettext_noop("GTM Connection"),
+ /* COORDINATORS */
+ gettext_noop("Coordinator Options"),
+ /* XC_HOUSEKEEPING_OPTIONS */
+ gettext_noop("XC Housekeeping Options"),
#endif
/* help_config wants this array to be null-terminated */
NULL
@@ -1489,6 +1497,15 @@ static struct config_bool ConfigureNamesBool[] =
true,
NULL, NULL, NULL
},
+ {
+ {"xc_maintenance_mode", PGC_SUSET, XC_HOUSEKEEPING_OPTIONS,
+ gettext_noop("Turn on XC maintenance mode."),
+ gettext_noop("Can set ON by SET command by superuser.")
+ },
+ &xc_maintenance_mode,
+ false,
+ check_pgxc_maintenance_mode, NULL, NULL
+ },
#endif
{
@@ -5257,6 +5274,14 @@ set_config_option(const char *name, const char *value,
bool prohibitValueChange = false;
bool makeDefault;
+#ifdef PGXC
+ /*
+ * Current GucContest value is needed to check if xc_maintenance_mode parameter
+ * is specified in valid contests. It is allowed only by SET command or
+ * libpq connect parameters so that setting this ON is just temporary.
+ */
+ currentGucContext = context;
+#endif
if (context == PGC_SIGHUP || source == PGC_S_DEFAULT)
{
/*
@@ -8587,6 +8612,55 @@ check_log_stats(bool *newval, void **extra, GucSource source)
return true;
}
+#ifdef PGXC
+/*
+ * K.Suzuki, March, 2012.
+ *
+ * Here, only a warning will be printed to log. Returning false will cause FATAL error and it
+ * will not be good.
+ */
+static bool
+check_pgxc_maintenance_mode(bool *newval, void **extra, GucSource source)
+{
+
+ switch(source)
+ {
+ case PGC_S_DYNAMIC_DEFAULT:
+ case PGC_S_ENV_VAR:
+ case PGC_S_ARGV:
+ GUC_check_errmsg("pgxc_maintenance_mode is not allowed here.");
+ return false;
+ case PGC_S_FILE:
+ switch (currentGucContext)
+ {
+ case PGC_SIGHUP:
+ elog(WARNING, "pgxc_maintenance_mode is not allowed in postgresql.conf. Set to default (false).");
+ *newval = false;
+ return true;
+ default:
+ GUC_check_errmsg("pgxc_maintenance_mode is not allowed in postgresql.conf.");
+ return false;
+ }
+ return false; /* Should not come here */
+ case PGC_S_DATABASE:
+ case PGC_S_USER:
+ case PGC_S_DATABASE_USER:
+ case PGC_S_INTERACTIVE:
+ case PGC_S_TEST:
+ elog(WARNING, "pgxc_maintenance_mode is not allowed here. Set to default (false).");
+ *newval = false;
+ return true;
+ case PGC_S_DEFAULT:
+ case PGC_S_CLIENT:
+ case PGC_S_SESSION:
+ return true;
+ default:
+ GUC_check_errmsg("Unknown source");
+ return false;
+ }
+}
+#endif
+
static bool
check_canonical_path(char **newval, void **extra, GucSource source)
{
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index 67dbce2d9b..58c09a43e7 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -273,6 +273,7 @@ extern void ForgetTransactionNodes(void);
extern void RegisterTransactionLocalNode(bool write);
extern bool IsTransactionLocalNode(bool write);
extern void ForgetTransactionLocalNode(void);
+extern bool IsXidImplicit(const char *xid);
#endif
extern int xactGetCommittedChildren(TransactionId **ptr);
diff --git a/src/include/pgxc/xc_maintenance_mode.h b/src/include/pgxc/xc_maintenance_mode.h
new file mode 100644
index 0000000000..a96148c385
--- /dev/null
+++ b/src/include/pgxc/xc_maintenance_mode.h
@@ -0,0 +1,12 @@
+#ifndef XC_MAINTENANCE_MODE_H
+#define XC_MAINTENANCE_MODE_H
+
+#include <unistd.h>
+#include "c.h"
+#include "postgres.h"
+#include "utils/guc.h"
+
+extern bool xc_maintenance_mode;
+extern GucContext currentGucContext;
+
+#endif /* XC_MAINTENANCE_MODE_H */
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index 645599b2ab..82fa92c5fd 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -93,10 +93,15 @@ enum config_group
ERROR_HANDLING_OPTIONS,
PRESET_OPTIONS,
CUSTOM_OPTIONS,
+#ifdef PGXC
DEVELOPER_OPTIONS,
DATA_NODES,
GTM,
- COORDINATORS
+ COORDINATORS,
+ XC_HOUSEKEEPING_OPTIONS
+#else
+ DEVELOPER_OPTIONS
+#endif
};
/*