diff options
author | Pavan Deolasee | 2016-02-07 12:55:01 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-18 09:48:14 +0000 |
commit | b7f660d98c6b5a6e5d15daaeaec5b0b7e92b9a40 (patch) | |
tree | 706d171b954ebea7621bdc5791926e8fa02e8921 | |
parent | b8b5cc1a9e22915cb006f0172dbb137a772795e8 (diff) |
Add a mechanism to start with an empty pgxc_ctl configuration file and build
the cluster one at a time.
A new option "prepare config empty" is now supported which sets up an almost
empty conf file and all components, including GTM, can be added one at a time
-rw-r--r-- | contrib/pgxc_ctl/Makefile | 2 | ||||
-rw-r--r-- | contrib/pgxc_ctl/config.c | 11 | ||||
-rw-r--r-- | contrib/pgxc_ctl/coord_cmd.c | 17 | ||||
-rw-r--r-- | contrib/pgxc_ctl/datanode_cmd.c | 181 | ||||
-rw-r--r-- | contrib/pgxc_ctl/datanode_cmd.h | 3 | ||||
-rw-r--r-- | contrib/pgxc_ctl/do_command.c | 177 | ||||
-rw-r--r-- | contrib/pgxc_ctl/do_command.h | 1 | ||||
-rw-r--r-- | contrib/pgxc_ctl/gtm_cmd.c | 127 | ||||
-rw-r--r-- | contrib/pgxc_ctl/gtm_cmd.h | 6 | ||||
-rwxr-xr-x | contrib/pgxc_ctl/make_signature | 31 | ||||
-rw-r--r-- | contrib/pgxc_ctl/monitor.c | 5 | ||||
-rw-r--r-- | contrib/pgxc_ctl/pgxc_ctl_conf_part_empty | 267 | ||||
-rw-r--r-- | contrib/pgxc_ctl/variables.h | 2 |
13 files changed, 683 insertions, 147 deletions
diff --git a/contrib/pgxc_ctl/Makefile b/contrib/pgxc_ctl/Makefile index e94d72f144..25ff6ccf0f 100644 --- a/contrib/pgxc_ctl/Makefile +++ b/contrib/pgxc_ctl/Makefile @@ -36,7 +36,7 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif -pgxc_ctl_bash.c: pgxc_ctl_conf_part_full pgxc_ctl_conf_part_minimal pgxc_ctl_bash_2 +pgxc_ctl_bash.c: pgxc_ctl_conf_part_full pgxc_ctl_conf_part_minimal pgxc_ctl_conf_part_empty pgxc_ctl_bash_2 ./make_signature clean: clean-script diff --git a/contrib/pgxc_ctl/config.c b/contrib/pgxc_ctl/config.c index 7b8cc28989..2098fd786d 100644 --- a/contrib/pgxc_ctl/config.c +++ b/contrib/pgxc_ctl/config.c @@ -141,7 +141,7 @@ static void parse_line(char *line) reset_value(newv); while((line = get_word(line, &val))) { - if (val) + if (val && (strcmp(val, "") != 0)) { add_val(newv, val); } @@ -502,7 +502,8 @@ static int anyConfigErrors = FALSE; static void checkIfVarIsConfigured(char *name) { - if (!find_var(name) || !sval(name)) + /* var could be just defined without valid contents */ + if (!find_var(name)) { anyConfigErrors = TRUE; reportMissingVar(name); @@ -589,7 +590,8 @@ int checkPortConflict(char *host, int port) int ii; /* GTM Master */ - if ((strcasecmp(host, sval(VAR_gtmMasterServer)) == 0) && (atoi(sval(VAR_gtmMasterPort)) == port)) + if (doesExist(VAR_gtmMasterServer, 0) && doesExist(VAR_gtmMasterPort, 0) && + (strcasecmp(host, sval(VAR_gtmMasterServer)) == 0) && (atoi(sval(VAR_gtmMasterPort)) == port)) return 1; /* GTM Slave */ if (isVarYes(VAR_gtmSlave) && (strcasecmp(host, sval(VAR_gtmSlaveServer)) == 0) && (atoi(sval(VAR_gtmSlavePort)) == port)) @@ -631,7 +633,8 @@ int checkDirConflict(char *host, char *dir) if (strcasecmp(dir, "none") == 0) return 0; /* GTM Master */ - if ((strcasecmp(host, sval(VAR_gtmMasterServer)) == 0) && (strcmp(dir, sval(VAR_gtmMasterDir)) == 0)) + if (doesExist(VAR_gtmMasterServer, 0) && doesExist(VAR_gtmMasterDir, 0) && + (strcasecmp(host, sval(VAR_gtmMasterServer)) == 0) && (strcmp(dir, sval(VAR_gtmMasterDir)) == 0)) return 1; /* GTM Slave */ if (isVarYes(VAR_gtmSlave) && (strcasecmp(host, sval(VAR_gtmSlaveServer)) == 0) && (strcmp(dir, sval(VAR_gtmSlaveDir)) == 0)) diff --git a/contrib/pgxc_ctl/coord_cmd.c b/contrib/pgxc_ctl/coord_cmd.c index 5d8bbbae84..78af7fb3cf 100644 --- a/contrib/pgxc_ctl/coord_cmd.c +++ b/contrib/pgxc_ctl/coord_cmd.c @@ -1138,7 +1138,20 @@ int add_coordinatorMaster(char *name, char *host, int port, int pooler, /* find any available coordinator */ connCordIndx = get_any_available_coord(-1); if (connCordIndx == -1) - return 1; + { + /* + * This is the FIRST coordinator being added into + * the cluster. Just start it and be done with it. + * + * Start the new coordinator with --coordinator option + */ + AddMember(nodelist, name); + start_coordinator_master(nodelist); + CleanArray(nodelist); + + /* ALTER our own definition appropriately */ + goto selfadd; + } /* Lock ddl */ if ((lockf = pgxc_popen_wRaw("psql -h %s -p %s %s", @@ -1214,6 +1227,8 @@ int add_coordinatorMaster(char *name, char *host, int port, int pooler, /* Quit DDL lokkup session */ fprintf(lockf, "\\q\n"); pclose(lockf); + +selfadd: if ((f = pgxc_popen_wRaw("psql -h %s -p %d %s", host, port, sval(VAR_defaultDatabase))) == NULL) elog(ERROR, "ERROR: cannot connect to the coordinator master %s.\n", name); else diff --git a/contrib/pgxc_ctl/datanode_cmd.c b/contrib/pgxc_ctl/datanode_cmd.c index a70506037d..a60f53c68a 100644 --- a/contrib/pgxc_ctl/datanode_cmd.c +++ b/contrib/pgxc_ctl/datanode_cmd.c @@ -939,8 +939,7 @@ static int failover_oneDatanode(int datanodeIdx) * *-----------------------------------------------------------------------*/ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, - char *waldir, char *restore_dname, char *extraConf, - char *extraPgHbaConf) + char *waldir, char *extraConf, char *extraPgHbaConf) { FILE *f, *lockf; int size, idx; @@ -952,10 +951,9 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, char *gtmPort; char pgdumpall_out[MAXPATH+1]; char **nodelist = NULL; - int ii, jj, restore_dnode_idx; + int ii, jj, restore_dnode_idx, restore_coord_idx = -1; char **confFiles = NULL; char **pgHbaConfFiles = NULL; - char *only_globals = "-g"; bool wal; if (waldir && (strcasecmp(waldir, "none") != 0)) @@ -1007,6 +1005,17 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, return 1; } + /* find any available datanode */ + restore_dnode_idx = get_any_available_datanode(-1); + if (restore_dnode_idx == -1) + restore_coord_idx = get_any_available_coord(-1); + + if (restore_dnode_idx == -1 && restore_coord_idx == -1) + { + elog(ERROR, "ERROR: no valid datanode or coordinator configuration!"); + return 1; + } + if ((extendVar(VAR_datanodeNames, idx + 1, "none") != 0) || (extendVar(VAR_datanodeMasterServers, idx + 1, "none") != 0) || (extendVar(VAR_datanodePorts, idx + 1, "none") != 0) || @@ -1014,11 +1023,6 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, (extendVar(VAR_datanodeMasterDirs, idx + 1, "none") != 0) || (extendVar(VAR_datanodeMasterWALDirs, idx + 1, "none") != 0) || (extendVar(VAR_datanodeMaxWALSenders, idx + 1, "none") != 0) || - (extendVar(VAR_datanodeSlaveServers, idx + 1, "none") != 0) || - (extendVar(VAR_datanodeSlavePorts, idx + 1, "none") != 0) || - (extendVar(VAR_datanodeSlavePoolerPorts, idx + 1, "none") != 0) || - (extendVar(VAR_datanodeSlaveDirs, idx + 1, "none") != 0) || - (extendVar(VAR_datanodeArchLogDirs, idx + 1, "none") != 0) || (extendVar(VAR_datanodeSpecificExtraConfig, idx + 1, "none") != 0) || (extendVar(VAR_datanodeSpecificExtraPgHba, idx + 1, "none") != 0)) { @@ -1026,6 +1030,19 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, return 1; } + if (isVarYes(VAR_datanodeSlave)) + { + if ((extendVar(VAR_datanodeSlaveServers, idx + 1, "none") != 0) || + (extendVar(VAR_datanodeSlavePorts, idx + 1, "none") != 0) || + (extendVar(VAR_datanodeSlavePoolerPorts, idx + 1, "none") != 0) || + (extendVar(VAR_datanodeSlaveDirs, idx + 1, "none") != 0) || + (extendVar(VAR_datanodeSlaveWALDirs, idx + 1, "none") != 0) || + (extendVar(VAR_datanodeArchLogDirs, idx + 1, "none") != 0)) + { + elog(PANIC, "PANIC: Internal error, inconsistent datanode slave information\n"); + return 1; + } + } /* * Now reconfigure @@ -1042,11 +1059,15 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, assign_arrayEl(VAR_datanodeMasterDirs, idx, dir, NULL); assign_arrayEl(VAR_datanodeMasterWALDirs, idx, waldir, NULL); assign_arrayEl(VAR_datanodeMaxWALSenders, idx, aval(VAR_datanodeMaxWALSenders)[0], NULL); /* Could be vulnerable */ - assign_arrayEl(VAR_datanodeSlaveServers, idx, "none", NULL); - assign_arrayEl(VAR_datanodeSlavePorts, idx, "-1", NULL); - assign_arrayEl(VAR_datanodeSlavePoolerPorts, idx, "-1", NULL); - assign_arrayEl(VAR_datanodeSlaveDirs, idx, "none", NULL); - assign_arrayEl(VAR_datanodeArchLogDirs, idx, "none", NULL); + if (isVarYes(VAR_datanodeSlave)) + { + assign_arrayEl(VAR_datanodeSlaveServers, idx, "none", NULL); + assign_arrayEl(VAR_datanodeSlavePorts, idx, "-1", NULL); + assign_arrayEl(VAR_datanodeSlavePoolerPorts, idx, "-1", NULL); + assign_arrayEl(VAR_datanodeSlaveDirs, idx, "none", NULL); + assign_arrayEl(VAR_datanodeSlaveWALDirs, idx, "none", NULL); + assign_arrayEl(VAR_datanodeArchLogDirs, idx, "none", NULL); + } assign_arrayEl(VAR_datanodeSpecificExtraConfig, idx, extraConf, NULL); assign_arrayEl(VAR_datanodeSpecificExtraPgHba, idx, extraPgHbaConf, NULL); /* @@ -1088,11 +1109,15 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, fprintAval(f, VAR_datanodeMasterDirs); fprintAval(f, VAR_datanodeMasterWALDirs); fprintAval(f, VAR_datanodeMaxWALSenders); - fprintAval(f, VAR_datanodeSlaveServers); - fprintAval(f, VAR_datanodeSlavePorts); - fprintAval(f, VAR_datanodeSlavePoolerPorts); - fprintAval(f, VAR_datanodeSlaveDirs); - fprintAval(f, VAR_datanodeArchLogDirs); + if (isVarYes(VAR_datanodeSlave)) + { + fprintAval(f, VAR_datanodeSlaveServers); + fprintAval(f, VAR_datanodeSlavePorts); + fprintAval(f, VAR_datanodeSlavePoolerPorts); + fprintAval(f, VAR_datanodeSlaveDirs); + fprintAval(f, VAR_datanodeSlaveWALDirs); + fprintAval(f, VAR_datanodeArchLogDirs); + } fprintAval(f, VAR_datanodeSpecificExtraConfig); fprintAval(f, VAR_datanodeSpecificExtraPgHba); fprintf(f, "%s", "#----End of reconfiguration -------------------------\n"); @@ -1149,45 +1174,49 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, pclose(f); } - restore_dnode_idx = -1; - for (ii = 0; aval(VAR_datanodeNames)[ii]; ii++) - { - if (!is_none(aval(VAR_datanodeNames)[ii])) - { - if (strcmp(aval(VAR_datanodeNames)[ii], restore_dname) == 0) - restore_dnode_idx = ii; - } - } - if (strcmp("none", restore_dname) != 0 && restore_dnode_idx == -1) - { - elog(ERROR, "ERROR: improper datanode specified to restore from, %s\n", restore_dname); - return 1; - } - - if (restore_dnode_idx == -1) - { - restore_dnode_idx = 0; - } - else - only_globals= " "; - - - /* Lock ddl */ - if ((lockf = pgxc_popen_wRaw("psql -h %s -p %d %s", aval(VAR_datanodeMasterServers)[restore_dnode_idx], atoi(aval(VAR_datanodePorts)[restore_dnode_idx]), sval(VAR_defaultDatabase))) == NULL) - { - elog(ERROR, "ERROR: could not open psql command, %s\n", strerror(errno)); - return 1; - } + /* Lock ddl */ + if (restore_dnode_idx != -1) + { + if ((lockf = pgxc_popen_wRaw("psql -h %s -p %d %s", aval(VAR_datanodeMasterServers)[restore_dnode_idx], atoi(aval(VAR_datanodePorts)[restore_dnode_idx]), sval(VAR_defaultDatabase))) == NULL) + { + elog(ERROR, "ERROR: could not open datanode psql command, %s\n", strerror(errno)); + return 1; + } + } + else if (restore_coord_idx != -1) + { + if ((lockf = pgxc_popen_wRaw("psql -h %s -p %d %s", aval(VAR_coordMasterServers)[restore_coord_idx], atoi(aval(VAR_coordPorts)[restore_coord_idx]), sval(VAR_defaultDatabase))) == NULL) + { + elog(ERROR, "ERROR: could not open coordinator psql command, %s\n", strerror(errno)); + return 1; + } + } + else + { + elog(ERROR, "ERROR: no valid datanode or coordinator configuration!"); + return 1; + } + fprintf(lockf, "select pgxc_lock_for_backup();\n"); /* Keep open until the end of the addition. */ fflush(lockf); /* pg_dumpall */ createLocalFileName(GENERAL, pgdumpall_out, MAXPATH); - doImmediateRaw("pg_dumpall -p %s -h %s -s --include-nodes --dump-nodes %s >%s", + if (restore_dnode_idx != -1) + doImmediateRaw("pg_dumpall -p %s -h %s -s --include-nodes --dump-nodes >%s", aval(VAR_datanodePorts)[restore_dnode_idx], aval(VAR_datanodeMasterServers)[restore_dnode_idx], - only_globals, pgdumpall_out); + else if (restore_coord_idx != -1) + doImmediateRaw("pg_dumpall -p %s -h %s -s --include-nodes --dump-nodes >%s", + aval(VAR_coordPorts)[restore_coord_idx], + aval(VAR_coordMasterServers)[restore_coord_idx], + pgdumpall_out); + else + { + elog(ERROR, "ERROR: no valid datanode or coordinator configuration!"); + return 1; + } /* Start the new datanode */ doImmediate(host, NULL, "pg_ctl start -w -Z restoremode -D %s -o -i", dir); @@ -1214,7 +1243,7 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, { if ((f = pgxc_popen_wRaw("psql -h %s -p %s %s", aval(VAR_coordMasterServers)[ii], aval(VAR_coordPorts)[ii], sval(VAR_defaultDatabase))) == NULL) { - elog(ERROR, "ERROR: cannot connect to the datanode master %s.\n", aval(VAR_coordNames)[ii]); + elog(ERROR, "ERROR: cannot connect to the coordinator master %s.\n", aval(VAR_coordNames)[ii]); continue; } fprintf(f, "CREATE NODE %s WITH (TYPE = 'datanode', host='%s', PORT=%d);\n", name, host, port); @@ -1224,8 +1253,10 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, } } - /* find any available coordinator */ - connCordIdx = get_any_available_coord(-1); + if (restore_coord_idx == -1) + connCordIdx = get_any_available_coord(-1); + else + connCordIdx = restore_coord_idx; if (connCordIdx == -1) return 1; @@ -1256,10 +1287,8 @@ int add_datanodeMaster(char *name, char *host, int port, int pooler, char *dir, fprintf(lockf, "\\q\n"); pclose(lockf); return 0; - } - int add_datanodeSlave(char *name, char *host, int port, int pooler, char *dir, char *walDir, char *archDir) { @@ -1537,7 +1566,7 @@ int remove_datanodeMaster(char *name, int clean_opt) /* Check if the datanode is configured */ if ((idx = datanodeIdx(name)) < 0) { - elog(ERROR, "ERROR: Coordinator %s is not configured.\n", name); + elog(ERROR, "ERROR: Datanode %s is not configured.\n", name); return 1; } /* Check if all the other datanodes are running */ @@ -1619,17 +1648,25 @@ int remove_datanodeMaster(char *name, int clean_opt) doImmediate(aval(VAR_datanodeMasterServers)[idx], NULL, "rm -rf %s", aval(VAR_datanodeMasterDirs)[idx]); /* Update configuration and backup --> should cleanup "none" entries here */ replace_arrayEl(VAR_datanodeNames, idx, "none", NULL); - replace_arrayEl(VAR_datanodeMasterDirs, idx, "none", NULL); - replace_arrayEl(VAR_datanodeMasterWALDirs, idx, "none", NULL); + replace_arrayEl(VAR_datanodeMasterServers, idx, "none", NULL); replace_arrayEl(VAR_datanodePorts, idx, "-1", "-1"); replace_arrayEl(VAR_datanodePoolerPorts, idx, "-1", "-1"); - replace_arrayEl(VAR_datanodeMasterServers, idx, "none", NULL); + replace_arrayEl(VAR_datanodeMasterDirs, idx, "none", NULL); + replace_arrayEl(VAR_datanodeMasterWALDirs, idx, "none", NULL); replace_arrayEl(VAR_datanodeMaxWALSenders, idx, "0", "0"); - replace_arrayEl(VAR_datanodeSlaveServers, idx, "none", NULL); - replace_arrayEl(VAR_datanodeSlaveDirs, idx, "none", NULL); - replace_arrayEl(VAR_datanodeSlaveWALDirs, idx, "none", NULL); - replace_arrayEl(VAR_datanodeArchLogDirs, idx, "none", NULL); - replace_arrayEl(VAR_datanodeSpecificExtraConfig, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSpecificExtraConfig, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSpecificExtraPgHba, idx, "none", NULL); + + if (isVarYes(VAR_datanodeSlave)) + { + replace_arrayEl(VAR_datanodeSlaveServers, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSlavePorts, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSlavePoolerPorts, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSlaveDirs, idx, "none", NULL); + replace_arrayEl(VAR_datanodeSlaveWALDirs, idx, "none", NULL); + replace_arrayEl(VAR_datanodeArchLogDirs, idx, "none", NULL); + } + handle_no_slaves(); /* * Write config files @@ -1642,7 +1679,7 @@ int remove_datanodeMaster(char *name, int clean_opt) } fprintf(f, "#================================================================\n" - "# pgxc configuration file updated due to coodinator master removal\n" + "# pgxc configuration file updated due to datanode master removal\n" "# %s\n", timeStampString(date, MAXTOKEN+1)); fprintSval(f, VAR_datanodeSlave); @@ -1653,12 +1690,16 @@ int remove_datanodeMaster(char *name, int clean_opt) fprintAval(f, VAR_datanodePoolerPorts); fprintAval(f, VAR_datanodeMasterServers); fprintAval(f, VAR_datanodeMaxWALSenders); - fprintAval(f, VAR_datanodeSlaveServers); - fprintAval(f, VAR_datanodeSlavePorts); - fprintAval(f, VAR_datanodeSlaveDirs); - fprintAval(f, VAR_datanodeSlaveWALDirs); - fprintAval(f, VAR_datanodeArchLogDirs); + if (isVarYes(VAR_datanodeSlave)) + { + fprintAval(f, VAR_datanodeSlaveServers); + fprintAval(f, VAR_datanodeSlavePorts); + fprintAval(f, VAR_datanodeSlaveDirs); + fprintAval(f, VAR_datanodeSlaveWALDirs); + fprintAval(f, VAR_datanodeArchLogDirs); + } fprintAval(f, VAR_datanodeSpecificExtraConfig); + fprintAval(f, VAR_datanodeSpecificExtraPgHba); fclose(f); backup_configuration(); return 0; diff --git a/contrib/pgxc_ctl/datanode_cmd.h b/contrib/pgxc_ctl/datanode_cmd.h index 5eee9b6a53..9a8eca58df 100644 --- a/contrib/pgxc_ctl/datanode_cmd.h +++ b/contrib/pgxc_ctl/datanode_cmd.h @@ -53,8 +53,7 @@ extern cmd_t *prepare_cleanDatanodeSlave(char *nodeName); #ifdef XCP extern int add_datanodeMaster(char *name, char *host, int port, int pooler, - char *dir, char *walDir, char *restore_dname, char *extraConf, - char *extraPgHbaConf); + char *dir, char *walDir, char *extraConf, char *extraPgHbaConf); #else extern int add_datanodeMaster(char *name, char *host, int port, char *dir, char *restore_dname, char *extraConf, char *extraPgHbaConf); diff --git a/contrib/pgxc_ctl/do_command.c b/contrib/pgxc_ctl/do_command.c index c6d0cae903..035400d320 100644 --- a/contrib/pgxc_ctl/do_command.c +++ b/contrib/pgxc_ctl/do_command.c @@ -40,6 +40,7 @@ extern char *pgxc_ctl_conf_prototype[]; extern char *pgxc_ctl_conf_prototype_minimal[]; +extern char *pgxc_ctl_conf_prototype_empty[]; int forceInit = false; @@ -67,6 +68,7 @@ static void do_show_help(char *line); typedef enum ConfigType { + CONFIG_EMPTY, CONFIG_MINIMAL, CONFIG_COMPLETE } ConfigType; @@ -102,7 +104,9 @@ static void do_prepareConfFile(char *Path, ConfigType config_type) return; } - if (config_type == CONFIG_MINIMAL) + if (config_type == CONFIG_EMPTY) + my_pgxc_conf_prototype = pgxc_ctl_conf_prototype_empty; + else if (config_type == CONFIG_MINIMAL) my_pgxc_conf_prototype = pgxc_ctl_conf_prototype_minimal; else my_pgxc_conf_prototype = pgxc_ctl_conf_prototype; @@ -517,7 +521,7 @@ static void do_kill_command(char *line) static void init_all(void) { - init_gtm_master(); + init_gtm_master(true); start_gtm_master(); if (isVarYes(VAR_gtmSlave)) { @@ -574,12 +578,12 @@ static void do_init_command(char *line) { if (!GetToken() || (TestToken("all"))) { - init_gtm_master(); + init_gtm_master(true); if (isVarYes(VAR_gtmSlave)) init_gtm_slave(); } else if (TestToken("master")) - init_gtm_master(); + init_gtm_master(true); else if (TestToken("slave")) init_gtm_slave(); else @@ -868,7 +872,6 @@ static void do_add_command(char *line) char *dir; char *walDir; char *archDir; - char *dnode; char *extraConf; char *extraPgHbaConf; @@ -880,7 +883,7 @@ static void do_add_command(char *line) if (TestToken("gtm")) { /* - * add gtm slave name host port dir + * add gtm master name host port dir */ if (!GetToken()) @@ -888,16 +891,27 @@ static void do_add_command(char *line) elog(ERROR, "ERROR: Specify option for add gtm command.\n"); return; } - if (!TestToken("slave")) - { - elog(ERROR, "ERROR: you can specify only slave to add gtm command. %s is invalid.\n", token); - return; - } - GetAndSet(name, "ERROR: please specify the name of gtm slave\n"); - GetAndSet(host, "ERROR: please specify the host name for gtm slave\n"); - GetAndSet(port, "ERROR: please specify the port number for gtm slave\n"); - GetAndSet(dir, "ERROR: please specify the working director for gtm slave\n"); - add_gtmSlave(name, host, atoi(port), dir); + if (TestToken("master")) + { + GetAndSet(name, "ERROR: please specify the name of gtm master\n"); + GetAndSet(host, "ERROR: please specify the host name for gtm master\n"); + GetAndSet(port, "ERROR: please specify the port number for gtm master\n"); + GetAndSet(dir, "ERROR: please specify the working director for gtm master\n"); + add_gtmMaster(name, host, atoi(port), dir); + } + else if (TestToken("slave")) + { + GetAndSet(name, "ERROR: please specify the name of gtm slave\n"); + GetAndSet(host, "ERROR: please specify the host name for gtm slave\n"); + GetAndSet(port, "ERROR: please specify the port number for gtm slave\n"); + GetAndSet(dir, "ERROR: please specify the working director for gtm slave\n"); + add_gtmSlave(name, host, atoi(port), dir); + } + else + { + elog(ERROR, "ERROR: you can specify only master/slave to add gtm command. %s is invalid.\n", token); + return; + } freeAndReset(name); freeAndReset(host); freeAndReset(port); @@ -935,9 +949,9 @@ static void do_add_command(char *line) GetAndSet(host, "ERROR: please specify the host for the coordinator masetr\n"); GetAndSet(port, "ERROR: please specify the port number for the coordinator master\n"); GetAndSet(pooler, "ERROR: please specify the pooler port number for the coordinator master.\n"); - GetAndSet(dir, "ERROR: please specify the working director for the coordinator master\n"); - GetAndSet(extraConf, "ERROR: please specify file to read extra configuration. Specify 'none' if nothig extra to be added.\n"); - GetAndSet(extraPgHbaConf, "ERROR: please specify file to read extra pg_hba configuration. Specify 'none' if nothig extra to be added.\n"); + GetAndSet(dir, "ERROR: please specify the working directory for the coordinator master\n"); + GetAndSet(extraConf, "ERROR: please specify file to read extra configuration. Specify 'none' if nothing extra to be added.\n"); + GetAndSet(extraPgHbaConf, "ERROR: please specify file to read extra pg_hba configuration. Specify 'none' if nothing extra to be added.\n"); add_coordinatorMaster(name, host, atoi(port), atoi(pooler), dir, extraConf, extraPgHbaConf); freeAndReset(name); @@ -975,11 +989,10 @@ static void do_add_command(char *line) GetAndSet(pooler, "ERROR: please specify the pooler port number for the datanode master.\n"); GetAndSet(dir, "ERROR: please specify the working director for the datanode master\n"); GetAndSet(walDir, "ERROR: please specify the WAL directory for the datanode master WAL. Specify 'none' for default\n"); - GetAndSet(dnode, "ERROR: please specify name of existing datanode of which this will be a copy of. Specify 'none' for a bare datanode\n"); GetAndSet(extraConf, "ERROR: please specify file to read extra configuration. Specify 'none' if nothig extra to be added.\n"); GetAndSet(extraPgHbaConf, "ERROR: please specify file to read extra pg_hba configuration. Specify 'none' if nothig extra to be added.\n"); add_datanodeMaster(name, host, atoi(port), atoi(pooler), dir, - walDir, dnode, extraConf, extraPgHbaConf); + walDir, extraConf, extraPgHbaConf); freeAndReset(name); freeAndReset(host); freeAndReset(port); @@ -1023,24 +1036,34 @@ static void do_remove_command(char *line) } if (TestToken("gtm")) { - if (!GetToken() || !TestToken("slave")) + if (!GetToken()) { - elog(ERROR, "ERROR: Please speciy slave to add gtm command\n"); + elog(ERROR, "ERROR: Specify option to remove gtm command\n"); + return; + } + if (TestToken("master")) + { + if (GetToken() && TestToken("clean")) + clean_opt = TRUE; + remove_gtmMaster(clean_opt); + } + else if (TestToken("slave")) + { + if (GetToken() && TestToken("clean")) + clean_opt = TRUE; + remove_gtmSlave(clean_opt); + } + else + { + elog(ERROR, "ERROR: you can specify only master/slave to remove gtm command. %s is invalid.\n", token); return; } - if (GetToken() && TestToken("clean")) - clean_opt = TRUE; - remove_gtmSlave(clean_opt); } else if (TestToken("gtm_proxy")) { GetAndSet(name, "ERROR: please specify gtm proxy name to remove.\n"); - if (TestToken("clean")) - { + if (GetToken() && TestToken("clean")) clean_opt = TRUE; - freeAndReset(name); - GetAndSet(name, "ERROR: please specify gtm proxy name to remove.\n"); - } remove_gtmProxy(name, clean_opt ); freeAndReset(name); } @@ -1054,24 +1077,16 @@ static void do_remove_command(char *line) if (TestToken("master")) { GetAndSet(name, "ERROR: please specify the name of the coordinator master\n"); - if (TestToken("clean")) - { + if (GetToken() && TestToken("clean")) clean_opt = TRUE; - freeAndReset(name); - GetAndSet(name, "ERROR: please specify the name of the coordinator master\n"); - } remove_coordinatorMaster(name, clean_opt); freeAndReset(name); } else { GetAndSet(name, "ERROR: please specify the name of the coordinator slave\n"); - if (TestToken("clean")) - { + if (GetToken() && TestToken("clean")) clean_opt = TRUE; - freeAndReset(name); - GetAndSet(name, "ERROR: please specify the name of the coordinator master\n"); - } remove_coordinatorSlave(name, clean_opt); freeAndReset(name); } @@ -1086,24 +1101,16 @@ static void do_remove_command(char *line) if (TestToken("master")) { GetAndSet(name, "ERROR: please specify the name of the datanode master\n"); - if (TestToken("clean")) - { + if (GetToken() && TestToken("clean")) clean_opt = TRUE; - freeAndReset(name); - GetAndSet(name, "ERROR: please specify the name of the coordinator master\n"); - } remove_datanodeMaster(name, clean_opt); freeAndReset(name); } else { GetAndSet(name, "ERROR: please specify the name of the datanode slave\n"); - if (TestToken("clean")) - { + if (GetToken() && TestToken("clean")) clean_opt = TRUE; - freeAndReset(name); - GetAndSet(name, "ERROR: please specify the name of the coordinator master\n"); - } remove_datanodeSlave(name, clean_opt); freeAndReset(name); } @@ -1113,13 +1120,6 @@ static void do_remove_command(char *line) return; } - - - - - - - static char *m_Option; static char *handle_m_option(char *line, char **m_option) @@ -2336,7 +2336,9 @@ int do_singleLine(char *buf, char *wkline) if (TestToken("config")) GetToken(); - if (TestToken("minimal")) + if (TestToken("empty")) + config_type = CONFIG_EMPTY; + else if (TestToken("minimal")) config_type = CONFIG_MINIMAL; else if (TestToken("complete")) config_type = CONFIG_COMPLETE; @@ -2974,11 +2976,64 @@ get_any_available_coord(int except) if (!is_none(aval(VAR_coordMasterServers)[ii])) { if (pingNode(aval(VAR_coordMasterServers)[ii], - aval(VAR_coordPorts)[ii]) == 0) + aval(VAR_coordPorts)[ii]) == 0) + return ii; + } + } + + /* + * this could be the first coordinator that is being added. + * This call would happen *after* expanding the array to + * accomodate the new coordinator. Hence we check for size + * being more than 1 + */ + if (arraySizeName(VAR_coordNames) > 1) + { + for (ii = 0; aval(VAR_coordNames)[ii]; ii++) + { + if (!is_none(aval(VAR_coordNames)[ii])) + { + elog(ERROR, "ERROR: failed to find any running coordinator"); + return -1; + } + } + } + return -1; +} + +int +get_any_available_datanode(int except) +{ + int ii; + for (ii = 0; aval(VAR_datanodeMasterServers)[ii]; ii++) + { + if (ii == except) + continue; + + if (!is_none(aval(VAR_datanodeMasterServers)[ii])) + { + if (pingNode(aval(VAR_datanodeMasterServers)[ii], + aval(VAR_datanodePorts)[ii]) == 0) return ii; } } - elog(ERROR, "ERROR: failed to find any running coordinator"); + /* + * this could be the first datanode that is being added. + * This call would happen *after* expanding the array to + * accomodate the new datanode. Hence we check for size + * being more than 1 + */ + if (arraySizeName(VAR_datanodeNames) > 1) + { + for (ii = 0; aval(VAR_datanodeNames)[ii]; ii++) + { + if (!is_none(aval(VAR_datanodeNames)[ii])) + { + elog(ERROR, "ERROR: failed to find any running datanode"); + return -1; + } + } + } return -1; } diff --git a/contrib/pgxc_ctl/do_command.h b/contrib/pgxc_ctl/do_command.h index b24d64a8ef..b39a272516 100644 --- a/contrib/pgxc_ctl/do_command.h +++ b/contrib/pgxc_ctl/do_command.h @@ -15,4 +15,5 @@ extern int forceInit; extern void do_command(FILE *inf, FILE *outf); extern int do_singleLine(char *buf, char *wkline); extern int get_any_available_coord(int except); +extern int get_any_available_datanode(int except); #endif /* DO_COMMAND_H */ diff --git a/contrib/pgxc_ctl/gtm_cmd.c b/contrib/pgxc_ctl/gtm_cmd.c index 69faf037a6..5f92fb7965 100644 --- a/contrib/pgxc_ctl/gtm_cmd.c +++ b/contrib/pgxc_ctl/gtm_cmd.c @@ -47,13 +47,12 @@ static char date[MAXTOKEN+1]; /* * Init gtm master ----------------------------------------------------------------- */ -cmd_t *prepare_initGtmMaster(void) +cmd_t *prepare_initGtmMaster(bool stop) { cmd_t *cmdInitGtmMaster, *cmdGtmConf, *cmdGxid; char date[MAXTOKEN+1]; FILE *f; char **fileList = NULL; - int result; char remoteDirCheck[MAXPATH * 2 + 128]; remoteDirCheck[0] = '\0'; @@ -111,13 +110,19 @@ cmd_t *prepare_initGtmMaster(void) /* Setup GTM with appropriate GXID value */ appendCmdEl(cmdGtmConf, (cmdGxid = initCmd(sval(VAR_gtmMasterServer)))); - snprintf(newCommand(cmdGxid), MAXLINE, + if (stop) + snprintf(newCommand(cmdGxid), MAXLINE, "(gtm -x 2000 -D %s &); sleep 1; gtm_ctl stop -Z gtm -D %s", sval(VAR_gtmMasterDir), sval(VAR_gtmMasterDir)); + else + snprintf(newCommand(cmdGxid), MAXLINE, + "(gtm -x 2000 -D %s &); sleep 1;", + sval(VAR_gtmMasterDir)); return cmdInitGtmMaster; } -int init_gtm_master(void) + +int init_gtm_master(bool stop) { int rc; cmdList_t *cmdList; @@ -128,7 +133,7 @@ int init_gtm_master(void) /* Kill current gtm, build work directory and run initgtm */ - if ((cmd = prepare_initGtmMaster())) + if ((cmd = prepare_initGtmMaster(stop))) addCmd(cmdList, cmd); rc = doCmdList(cmdList); @@ -138,6 +143,67 @@ int init_gtm_master(void) } /* + * Add gtm master + * + */ +int add_gtmMaster(char *name, char *host, int port, char *dir) +{ + char port_s[MAXTOKEN+1]; + char date[MAXTOKEN+1]; + FILE *f; + int rc; + + if (is_none(name)) + { + elog(ERROR, "ERROR: Cannot add gtm master with the name \"none\".\n"); + return 1; + } + if (is_none(host)) + { + elog(ERROR, "ERROR: Cannot add gtm master with the name \"none\".\n"); + return 1; + } + if (is_none(dir)) + { + elog(ERROR, "ERROR: Cannot add gtm master with the directory \"none\".\n"); + return 1; + } + if (checkSpecificResourceConflict(name, host, port, dir, TRUE)) + { + elog(ERROR, "ERROR: New specified name:%s, host:%s, port:%d and dir:\"%s\" conflicts with existing node.\n", + name, host, port, dir); + return 1; + } + assign_sval(VAR_gtmName, Strdup(name)); + assign_sval(VAR_gtmMasterServer, Strdup(host)); + snprintf(port_s, MAXTOKEN, "%d", port); + assign_sval(VAR_gtmMasterPort, Strdup(port_s)); + assign_sval(VAR_gtmMasterDir, Strdup(dir)); + makeServerList(); + if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) + { + /* Should it be panic? */ + elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); + return 1; + } + fprintf(f, + "#===================================================\n" + "# pgxc configuration file updated due to GTM master addition\n" + "# %s\n", + timeStampString(date, MAXTOKEN+1)); + fprintSval(f, VAR_gtmName); + fprintSval(f, VAR_gtmMasterServer); + fprintSval(f, VAR_gtmMasterPort); + fprintSval(f, VAR_gtmMasterDir); + fprintf(f, "%s","#----End of reconfiguration -------------------------\n"); + fclose(f); + backup_configuration(); + if ((rc = init_gtm_master(false)) != 0) + return rc; + return(start_gtm_master()); +} + +/* * Add gtm slave: to be used after all the configuration is done. * * This function only maintains internal configuration, updte configuration file, @@ -208,6 +274,57 @@ int add_gtmSlave(char *name, char *host, int port, char *dir) return(start_gtm_slave()); } +int remove_gtmMaster(bool clean_opt) +{ + FILE *f; + + /* Check if gtm_slave is configured */ + if (!sval(VAR_gtmMasterServer) || is_none(sval(VAR_gtmMasterServer))) + { + elog(ERROR, "ERROR: GTM master is not configured.\n"); + return 1; + } + + /* Check if gtm_master is running and stop if yes */ + if (do_gtm_ping(sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))) == 0) + stop_gtm_master(); + + elog(NOTICE, "Removing gtm master.\n"); + /* Clean */ + if (clean_opt) + clean_gtm_master(); + /* Reconfigure */ + reset_var(VAR_gtmName); + assign_sval(VAR_gtmName, Strdup("none")); + reset_var(VAR_gtmMasterServer); + assign_sval(VAR_gtmMasterServer, Strdup("none")); + reset_var(VAR_gtmMasterPort); + assign_sval(VAR_gtmMasterPort, Strdup("-1")); + reset_var(VAR_gtmMasterDir); + assign_sval(VAR_gtmMasterDir, Strdup("none")); + /* Write the configuration file and bakup it */ + if ((f = fopen(pgxc_ctl_config_path, "a")) == NULL) + { + /* Should it be panic? */ + elog(ERROR, "ERROR: cannot open configuration file \"%s\", %s\n", pgxc_ctl_config_path, strerror(errno)); + return 1; + } + fprintf(f, + "#===================================================\n" + "# pgxc configuration file updated due to GTM master removal\n" + "# %s\n", + timeStampString(date, MAXTOKEN+1)); + fprintSval(f, VAR_gtmName); + fprintSval(f, VAR_gtmMasterServer); + fprintSval(f, VAR_gtmMasterPort); + fprintSval(f, VAR_gtmMasterDir); + fprintf(f, "%s", "#----End of reconfiguration -------------------------\n"); + fclose(f); + backup_configuration(); + elog(NOTICE, "Done.\n"); + return 0; +} + int remove_gtmSlave(bool clean_opt) { FILE *f; diff --git a/contrib/pgxc_ctl/gtm_cmd.h b/contrib/pgxc_ctl/gtm_cmd.h index 79d0f06290..07f7f8dea9 100644 --- a/contrib/pgxc_ctl/gtm_cmd.h +++ b/contrib/pgxc_ctl/gtm_cmd.h @@ -14,16 +14,18 @@ #include "gtm/gtm_c.h" #include "utils.h" -extern int init_gtm_master(void); +extern int init_gtm_master(bool stop); extern int init_gtm_slave(void); extern int init_gtm_proxy(char **nodeList); extern int init_gtm_proxy_all(void); -extern cmd_t *prepare_initGtmMaster(void); +extern cmd_t *prepare_initGtmMaster(bool stop); extern cmd_t *prepare_initGtmSlave(void); extern cmd_t *prepare_initGtmProxy(char *nodeName); +extern int add_gtmMaster(char *name, char *host, int port, char *dir); extern int add_gtmSlave(char *name, char *host, int port, char *dir); extern int add_gtmProxy(char *name, char *host, int port, char *dir); +extern int remove_gtmMaster(bool clean_opt); extern int remove_gtmSlave(bool clean_opt); extern int remove_gtmProxy(char *name, bool clean_opt); diff --git a/contrib/pgxc_ctl/make_signature b/contrib/pgxc_ctl/make_signature index 713cd61897..09990714a9 100755 --- a/contrib/pgxc_ctl/make_signature +++ b/contrib/pgxc_ctl/make_signature @@ -169,3 +169,34 @@ NULL EOF rm pgxc_ctl_conf_part.wk + +cp pgxc_ctl_conf_part_empty pgxc_ctl_conf_empty.wk + +ex pgxc_ctl_conf_empty.wk <<EOF +%s/"/\\\"/ge +w +%s/^\(.*\)$/"\1",/e +%s/^"#ifdef XCP",$/#ifdef XCP/e +%s/^"#endif",$/#endif/e +wq +EOF + +cat >> pgxc_ctl_bash.c <<EOF +/* + * Prototype of pgxc_ctl configuration file. + * + * It should be self descripting. Can be extracted to your pgxc_ctl + * work directory with 'prepare empty' command. + */ + +char *pgxc_ctl_conf_prototype_empty[] = { +EOF + +cat pgxc_ctl_conf_empty.wk >> pgxc_ctl_bash.c + +cat >> pgxc_ctl_bash.c <<EOF +NULL +}; +EOF + +rm pgxc_ctl_conf_empty.wk diff --git a/contrib/pgxc_ctl/monitor.c b/contrib/pgxc_ctl/monitor.c index bc7608ad5c..1483504269 100644 --- a/contrib/pgxc_ctl/monitor.c +++ b/contrib/pgxc_ctl/monitor.c @@ -59,7 +59,10 @@ static void printResult(int res, char *what, char *name) static void monitor_gtm_master(void) { - return(printResult(do_gtm_ping(sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))), "gtm master", NULL)); + if (doesExist(VAR_gtmMasterServer, 0) && doesExist(VAR_gtmMasterPort, 0)) + return(printResult(do_gtm_ping(sval(VAR_gtmMasterServer), atoi(sval(VAR_gtmMasterPort))), "gtm master", NULL)); + else + elog(NOTICE, "GTM master not running\n"); } static void monitor_gtm_slave(void) diff --git a/contrib/pgxc_ctl/pgxc_ctl_conf_part_empty b/contrib/pgxc_ctl/pgxc_ctl_conf_part_empty new file mode 100644 index 0000000000..dcc9ccb6be --- /dev/null +++ b/contrib/pgxc_ctl/pgxc_ctl_conf_part_empty @@ -0,0 +1,267 @@ +#!/usr/bin/env bash +# +# Postgres-XC Configuration file for pgxc_ctl utility. +# +# Configuration file can be specified as -c option from pgxc_ctl command. Default is +# $PGXC_CTL_HOME/pgxc_ctl.org. +# +# This is bash script so you can make any addition for your convenience to configure +# your Postgres-XC cluster. +# +# Please understand that pgxc_ctl provides only a subset of configuration which pgxc_ctl +# provide. Here's several several assumptions/restrictions pgxc_ctl depends on. +# +# 1) All the resources of pgxc nodes has to be owned by the same user. Same user means +# user with the same user name. User ID may be different from server to server. +# This must be specified as a variable $pgxcOwner. +# +# 2) All the servers must be reacheable via ssh without password. It is highly recommended +# to setup key-based authentication among all the servers. +# +# 3) All the databases in coordinator/datanode has at least one same superuser. Pgxc_ctl +# uses this user to connect to coordinators and datanodes. Again, no password should +# be used to connect. You have many options to do this, pg_hba.conf, pg_ident.conf and +# others. Pgxc_ctl provides a way to configure pg_hba.conf but not pg_ident.conf. This +# will be implemented in the later releases. +# +# 4) Gtm master and slave can have different port to listen, while coordinator and datanode +# slave should be assigned the same port number as master. +# +# 5) Port nuber of a coordinator slave must be the same as its master. +# +# 6) Master and slave are connected using synchronous replication. Asynchronous replication +# have slight (almost none) chance to bring total cluster into inconsistent state. +# This chance is very low and may be negligible. Support of asynchronous replication +# may be supported in the later release. +# +# 7) Each coordinator and datanode can have only one slave each. Cascaded replication and +# multiple slave are not supported in the current pgxc_ctl. +# +# 8) Killing nodes may end up with IPC resource leak, such as semafor and shared memory. +# Only listening port (socket) will be cleaned with clean command. +# +# 9) Backup and restore are not supported in pgxc_ctl at present. This is a big task and +# may need considerable resource. +# +#======================================================================================== +# +# +# pgxcInstallDir variable is needed if you invoke "deploy" command from pgxc_ctl utility. +# If don't you don't need this variable. +pgxcInstallDir=$HOME/pgxc +#---- OVERALL ----------------------------------------------------------------------------- +# +pgxcOwner=$USER # owner of the Postgres-XC databaseo cluster. Here, we use this + # both as linus user and database user. This must be + # the super user of each coordinator and datanode. +pgxcUser=$pgxcOwner # OS user of Postgres-XC owner + +tmpDir=/tmp # temporary dir used in XC servers +localTmpDir=$tmpDir # temporary dir used here locally + +configBackup=n # If you want config file backup, specify y to this value. +configBackupHost=pgxc-linker # host to backup config file +configBackupDir=$HOME/pgxc # Backup directory +configBackupFile=pgxc_ctl.bak # Backup file name --> Need to synchronize when original changed. + +dataDirRoot=$HOME/DATA/pgxl/nodes + +#---- GTM ------------------------------------------------------------------------------------ + +# GTM is mandatory. You must have at least (and only) one GTM master in your Postgres-XC cluster. +# If GTM crashes and you need to reconfigure it, you can do it by pgxc_update_gtm command to update +# GTM master with others. Of course, we provide pgxc_remove_gtm command to remove it. This command +# will not stop the current GTM. It is up to the operator. + +#---- Overall ------- +gtmName=() + +#---- GTM Master ----------------------------------------------- + +#---- Overall ---- +gtmMasterServer=() +gtmMasterPort=() +gtmMasterDir=() + +#---- Configuration --- +gtmExtraConfig=() # Will be added gtm.conf for both Master and Slave (done at initilization only) +gtmMasterSpecificExtraConfig=() # Will be added to Master's gtm.conf (done at initialization only) + +#---- GTM Slave ----------------------------------------------- + +# Because GTM is a key component to maintain database consistency, you may want to configure GTM slave +# for backup. + +#---- Overall ------ +gtmSlave=n # Specify y if you configure GTM Slave. Otherwise, GTM slave will not be configured and + # all the following variables will be reset. +gtmSlaveName=() +gtmSlaveServer=() # value none means GTM slave is not available. Give none if you don't configure GTM Slave. +gtmSlavePort=() # Not used if you don't configure GTM slave. +gtmSlaveDir=() # Not used if you don't configure GTM slave. +# Please note that when you have GTM failover, then there will be no slave available until you configure the slave +# again. (pgxc_add_gtm_slave function will handle it) + +#---- Configuration ---- +gtmSlaveSpecificExtraConfig=() # Will be added to Slave's gtm.conf (done at initialization only) + +#---- GTM Proxy ------------------------------------------------------------------------------------------------------- +# GTM proxy will be selected based upon which server each component runs on. +# When fails over to the slave, the slave inherits its master's gtm proxy. It should be +# reconfigured based upon the new location. +# +# To do so, slave should be restarted. So pg_ctl promote -> (edit postgresql.conf and recovery.conf) -> pg_ctl restart +# +# You don't have to configure GTM Proxy if you dont' configure GTM slave or you are happy if every component connects +# to GTM Master directly. If you configure GTL slave, you must configure GTM proxy too. + +#---- Shortcuts ------ +gtmProxyDir=() + +#---- Overall ------- +gtmProxy=() # Specify y if you conifugre at least one GTM proxy. You may not configure gtm proxies + # only when you dont' configure GTM slaves. + # If you specify this value not to y, the following parameters will be set to default empty values. + # If we find there're no valid Proxy server names (means, every servers are specified + # as none), then gtmProxy value will be set to "n" and all the entries will be set to + # empty values. +gtmProxyNames=() # No used if it is not configured +gtmProxyServers=() # Specify none if you dont' configure it. +gtmProxyPorts=() # Not used if it is not configured. +gtmProxyDirs=() # Not used if it is not configured. + +#---- Configuration ---- +gtmPxyExtraConfig=n # Extra configuration parameter for gtm_proxy. Coordinator section has an example. + +#---- Coordinators ---------------------------------------------------------------------------------------------------- + +#---- shortcuts ---------- +coordMasterDir=$dataDirRoot/coord_master +coordSlaveDir=$HOME/coord_slave +coordArchLogDir=$HOME/coord_archlog + +#---- Overall ------------ +coordNames=() # Master and slave use the same name +coordPorts=() # Master server listening ports +poolerPorts=() # Master pooler ports +coordPgHbaEntries=(::1/128) # Assumes that all the coordinator (master/slave) accepts + # the same connection + # This entry allows only $pgxcOwner to connect. + # If you'd like to setup another connection, you should + # supply these entries through files specified below. +#coordPgHbaEntries=(127.0.0.1/32) # Same as above but for IPv4 connections + +#---- Master ------------- +coordMasterServers=() # none means this master is not available +coordMasterDirs=() +coordMaxWALsender=5 # max_wal_senders: needed to configure slave. If zero value is specified, + # it is expected to supply this parameter explicitly by external files + # specified in the following. If you don't configure slaves, leave this value to zero. +coordMaxWALSenders=() + # max_wal_senders configuration for each coordinator. + +#---- Slave ------------- +coordSlave=n # Specify y if you configure at least one coordiantor slave. Otherwise, the following + # configuration parameters will be set to empty values. + # If no effective server names are found (that is, every servers are specified as none), + # then coordSlave value will be set to n and all the following values will be set to + # empty values. +coordSlaveSync=n # Specify to connect with synchronized mode. +coordSlaveServers=() # none means this slave is not available +coordSlavePorts=() # coordinator slave listening ports +coordSlavePoolerPorts=() # coordinator slave pooler ports +coordSlaveDirs=() +coordArchLogDirs=() + +#---- Configuration files--- +# Need these when you'd like setup specific non-default configuration +# These files will go to corresponding files for the master. +# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries +# Or you may supply these files manually. +coordExtraConfig=coordExtraConfig # Extra configuration file for coordinators. + # This file will be added to all the coordinators' + # postgresql.conf +# Pleae note that the following sets up minimum parameters which you may want to change. +# You can put your postgresql.conf lines here. +cat > $coordExtraConfig <<EOF +#================================================ +# Added to all the coordinator postgresql.conf +# Original: $coordExtraConfig +log_destination = 'stderr' +logging_collector = on +log_directory = 'pg_log' +listen_addresses = '*' +max_connections = 100 +hot_standby = off +EOF + +# Additional Configuration file for specific coordinator master. +# You can define each setting by similar means as above. +coordSpecificExtraConfig=() +coordSpecificExtraPgHba=() + +#---- Datanodes ------------------------------------------------------------------------------------------------------- + +#---- Shortcuts -------------- +datanodeMasterDir=$dataDirRoot/dn_master +datanodeSlaveDir=$dataDirRoot/dn_slave +datanodeArchLogDir=$dataDirRoot/datanode_archlog + +#---- Overall --------------- +primaryDatanode= # Primary Node. +datanodeNames=() +datanodePorts=() # Master and slave use the same port! +datanodePoolerPorts=() # Master and slave use the same port! +datanodePgHbaEntries=(::1/128) # Assumes that all the coordinator (master/slave) accepts + # the same connection + # This list sets up pg_hba.conf for $pgxcOwner user. + # If you'd like to setup other entries, supply them + # through extra configuration files specified below. +#datanodePgHbaEntries=(127.0.0.1/32) # Same as above but for IPv4 connections + +#---- Master ---------------- +datanodeMasterServers=() # none means this master is not available. + # This means that there should be the master but is down. + # The cluster is not operational until the master is + # recovered and ready to run. +datanodeMasterDirs=() +datanodeMaxWalSender=5 # max_wal_senders: needed to configure slave. If zero value is + # specified, it is expected this parameter is explicitly supplied + # by external configuration files. + # If you don't configure slaves, leave this value zero. +datanodeMaxWALSenders=() + # max_wal_senders configuration for each datanode + +#---- Slave ----------------- +datanodeSlave=n # Specify y if you configure at least one coordiantor slave. Otherwise, the following + # configuration parameters will be set to empty values. + # If no effective server names are found (that is, every servers are specified as none), + # then datanodeSlave value will be set to n and all the following values will be set to + # empty values. +datanodeSlaveServers=() # value none means this slave is not available +datanodeSlavePorts=() # Master and slave use the same port! +datanodeSlavePoolerPorts=() # Master and slave use the same port! +#datanodeSlaveSync=y # If datanode slave is connected in synchronized mode +datanodeSlaveDirs=() +datanodeArchLogDirs=() + +# ---- Configuration files --- +# You may supply your bash script to setup extra config lines and extra pg_hba.conf entries here. +# These files will go to corresponding files for the master. +# Or you may supply these files manually. +datanodeExtraConfig=datanodeExtraConfig +cat > $datanodeExtraConfig <<EOF +#================================================ +# Added to all the datanode postgresql.conf +# Original: $datanodeExtraConfig +log_destination = 'stderr' +logging_collector = on +log_directory = 'pg_log' +listen_addresses = '*' +max_connections = 100 +hot_standby = off +EOF +# Additional Configuration file for specific datanode master. +# You can define each setting by similar means as above. +datanodeSpecificExtraConfig=() +datanodeSpecificExtraPgHba=() diff --git a/contrib/pgxc_ctl/variables.h b/contrib/pgxc_ctl/variables.h index 002336c6a3..d408c86fe1 100644 --- a/contrib/pgxc_ctl/variables.h +++ b/contrib/pgxc_ctl/variables.h @@ -74,6 +74,8 @@ void var_assign(char **dest, char *src); char *listValue(char *name); int extendVar(char *name, int newSize, char *def_value); int doesExist(char *name, int idx); +void assign_arrayEl_internal(char *name, int idx, char *val, char *pad, + int extend); #define AddMember(a, b) do{if((a) == NULL) (a) = Malloc0(sizeof(char *)); (a) = add_member((a), (b));}while(0) void clean_array(char **array); |