diff options
author | Michael Paquier | 2012-06-02 20:29:06 +0000 |
---|---|---|
committer | Michael Paquier | 2012-06-02 20:29:06 +0000 |
commit | dfee5379109a757e1bfaa9fe59830e6fb05f6688 (patch) | |
tree | ee33a2c0d5c76d94b742824e9d447bcd54659792 | |
parent | af488de7241de630c68c2f8a7a5ec6efb68ad083 (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.c | 77 |
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) { |