summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier2012-06-02 20:29:06 +0000
committerMichael Paquier2012-06-02 20:29:06 +0000
commitdfee5379109a757e1bfaa9fe59830e6fb05f6688 (patch)
treeee33a2c0d5c76d94b742824e9d447bcd54659792
parentaf488de7241de630c68c2f8a7a5ec6efb68ad083 (diff)
Block node registration for slave nodes and perform register at a stable state
Performing node registration on GTM just after postmaster start is dangerous because the master/slave status of the node is unknown. So node registration is done once node has reached a stable state, meaning that Xlog process has confirmed to postmaster that recovery has been completed. Registration is also blocked for slave nodes. A standby node is created from a hot backup of its master so master and its slaves will share the same node name. Two nodes are not authorized to register to GTM with the same node name to avoid identification confusion in the cluster, so it looks normal to let the master and the master only identify itself. A a direct consequence, unregistration too is done only for master node. Synchronous and asynchronous node replication works correctly with this fix, as well as node promotion (Ex: "pg_ctl promote -D $DATA").
-rw-r--r--src/backend/postmaster/postmaster.c77
1 files changed, 51 insertions, 26 deletions
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index c143dac30c..9c65c512a7 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -345,6 +345,8 @@ int PGXCNodeId = -1;
* This will have minimal impact on performance
*/
uint32 PGXCNodeIdentifier = 0;
+
+static bool isNodeRegistered = false;
#endif
/*
@@ -1132,24 +1134,6 @@ PostmasterMain(int argc, char *argv[])
*/
whereToSendOutput = DestNone;
-#ifdef PGXC
- /* Register node on GTM during Postmaster Startup. */
- if (IS_PGXC_COORDINATOR)
- {
- if (RegisterGTM(GTM_NODE_COORDINATOR, PostPortNumber, userDoption) < 0)
- ereport(FATAL,
- (errcode(ERRCODE_IO_ERROR),
- errmsg("Can not register Coordinator on GTM")));
- }
- if (IS_PGXC_DATANODE)
- {
- if (RegisterGTM(GTM_NODE_DATANODE, PostPortNumber, userDoption) < 0)
- ereport(FATAL,
- (errcode(ERRCODE_IO_ERROR),
- errmsg("Can not register Datanode on GTM")));
- }
-#endif
-
/*
* Initialize stats collection subsystem (this does NOT start the
* collector process!)
@@ -2320,10 +2304,13 @@ pmdie(SIGNAL_ARGS)
signal_child(PgPoolerPID, SIGTERM);
/* Unregister Node on GTM */
- if (IS_PGXC_COORDINATOR)
- UnregisterGTM(GTM_NODE_COORDINATOR);
- else if (IS_PGXC_DATANODE)
- UnregisterGTM(GTM_NODE_DATANODE);
+ if (isNodeRegistered)
+ {
+ if (IS_PGXC_COORDINATOR)
+ UnregisterGTM(GTM_NODE_COORDINATOR);
+ else if (IS_PGXC_DATANODE)
+ UnregisterGTM(GTM_NODE_DATANODE);
+ }
#endif
/*
@@ -2393,10 +2380,13 @@ pmdie(SIGNAL_ARGS)
signal_child(PgPoolerPID, SIGTERM);
/* Unregister Node on GTM */
- if (IS_PGXC_COORDINATOR)
- UnregisterGTM(GTM_NODE_COORDINATOR);
- else if (IS_PGXC_DATANODE)
- UnregisterGTM(GTM_NODE_DATANODE);
+ if (isNodeRegistered)
+ {
+ if (IS_PGXC_COORDINATOR)
+ UnregisterGTM(GTM_NODE_COORDINATOR);
+ else if (IS_PGXC_DATANODE)
+ UnregisterGTM(GTM_NODE_DATANODE);
+ }
#endif
pmState = PM_WAIT_BACKENDS;
}
@@ -4417,6 +4407,41 @@ sigusr1_handler(SIGNAL_ARGS)
pmState = PM_HOT_STANDBY;
}
+#ifdef PGXC
+ /*
+ * Register node to GTM.
+ * A node can only be registered if it has reached a stable recovery state
+ * and if is a master node.
+ * A standby node is created from a hot backup of master so master and slave
+ * nodes will normally share the same node name. Having master and slave share
+ * the same node name is convenient for slave promotion, and this makes master
+ * and slave nodes being seen as equal by GTM in cluster. As two nodes cannot
+ * register on GTM with the same name, it looks normal to let only master
+ * register and have slave nodes bypass this process.
+ */
+ if (pmState == PM_RUN &&
+ !isNodeRegistered)
+ {
+ isNodeRegistered = true;
+
+ /* Register node on GTM during Postmaster Startup. */
+ if (IS_PGXC_COORDINATOR)
+ {
+ if (RegisterGTM(GTM_NODE_COORDINATOR, PostPortNumber, data_directory) < 0)
+ ereport(FATAL,
+ (errcode(ERRCODE_IO_ERROR),
+ errmsg("Can not register Coordinator on GTM")));
+ }
+ if (IS_PGXC_DATANODE)
+ {
+ if (RegisterGTM(GTM_NODE_DATANODE, PostPortNumber, data_directory) < 0)
+ ereport(FATAL,
+ (errcode(ERRCODE_IO_ERROR),
+ errmsg("Can not register Datanode on GTM")));
+ }
+ }
+#endif
+
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER) &&
PgArchPID != 0)
{