diff options
| -rw-r--r-- | doc-xc/src/sgml/config.sgmlin | 15 | ||||
| -rw-r--r-- | doc-xc/src/sgml/ref/prepare_transaction.sgmlin | 6 | ||||
| -rw-r--r-- | src/backend/access/transam/xact.c | 14 | ||||
| -rw-r--r-- | src/backend/pgxc/Makefile | 2 | ||||
| -rw-r--r-- | src/backend/pgxc/xc_maintenance_mode/Makefile | 19 | ||||
| -rw-r--r-- | src/backend/pgxc/xc_maintenance_mode/xc_maintenance_mode.c | 5 | ||||
| -rw-r--r-- | src/backend/tcop/utility.c | 13 | ||||
| -rw-r--r-- | src/backend/utils/misc/guc.c | 74 | ||||
| -rw-r--r-- | src/include/access/xact.h | 1 | ||||
| -rw-r--r-- | src/include/pgxc/xc_maintenance_mode.h | 12 | ||||
| -rw-r--r-- | src/include/utils/guc_tables.h | 7 |
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 }; /* |
