Skip to content

Commit fa13316

Browse files
authored
Implement basis for Citus Secondaries support (cluster_name). (#616)
1 parent 742c498 commit fa13316

35 files changed

Lines changed: 1358 additions & 101 deletions

src/bin/pg_autoctl/cli_common.c

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ static void stop_postgres_and_remove_pgdata_and_config(ConfigFilePaths *pathname
7272
* { "verbose", no_argument, NULL, 'v' },
7373
* { "quiet", no_argument, NULL, 'q' },
7474
* { "help", no_argument, NULL, 'h' },
75+
* { "secondary", no_argument, NULL, 'z' }
76+
* { "citus-cluster", required_argument, NULL, 'Z' },
7577
* { "candidate-priority", required_argument, NULL, 'P'},
7678
* { "replication-quorum", required_argument, NULL, 'r'},
7779
* { "help", no_argument, NULL, 0 },
@@ -105,11 +107,12 @@ cli_common_keeper_getopts(int argc, char **argv,
105107
LocalOptionConfig.prepare_promotion_walreceiver = -1;
106108
LocalOptionConfig.postgresql_restart_failure_timeout = -1;
107109
LocalOptionConfig.postgresql_restart_failure_max_retries = -1;
108-
LocalOptionConfig.pgSetup.settings.candidatePriority =
109-
FAILOVER_NODE_CANDIDATE_PRIORITY;
110+
LocalOptionConfig.pgSetup.settings.candidatePriority = -1;
110111
LocalOptionConfig.pgSetup.settings.replicationQuorum =
111112
FAILOVER_NODE_REPLICATION_QUORUM;
112113

114+
/* default to a "primary" in citus node_role terms */
115+
LocalOptionConfig.citusRole = CITUS_ROLE_PRIMARY;
113116

114117
optind = 0;
115118

@@ -182,6 +185,26 @@ cli_common_keeper_getopts(int argc, char **argv,
182185
break;
183186
}
184187

188+
case 'z':
189+
{
190+
/* { "secondary", no_argument, NULL, 'z' } */
191+
strlcpy(LocalOptionConfig.citusRoleStr, "secondary", NAMEDATALEN);
192+
LocalOptionConfig.citusRole = CITUS_ROLE_SECONDARY;
193+
log_trace("--secondary");
194+
break;
195+
}
196+
197+
case 'Z':
198+
{
199+
/* { "citus-cluster", required_argument, NULL, 'Z' }, */
200+
strlcpy(LocalOptionConfig.pgSetup.citusClusterName,
201+
optarg,
202+
NAMEDATALEN);
203+
log_trace("--citus-cluster %s",
204+
LocalOptionConfig.pgSetup.citusClusterName);
205+
break;
206+
}
207+
185208
case 'U':
186209
{
187210
/* { "username", required_argument, NULL, 'U' } */
@@ -510,6 +533,41 @@ cli_common_keeper_getopts(int argc, char **argv,
510533
exit(EXIT_CODE_BAD_ARGS);
511534
}
512535

536+
/* check --secondary and --candidate-priority */
537+
if (LocalOptionConfig.pgSetup.settings.candidatePriority == -1)
538+
{
539+
/* --candidate-priority has not been used */
540+
if (LocalOptionConfig.citusRole == CITUS_ROLE_SECONDARY)
541+
{
542+
/* a Citus secondary can't be a target for failover */
543+
LocalOptionConfig.pgSetup.settings.candidatePriority = 0;
544+
}
545+
else
546+
{
547+
/* here we install the default candidate priority */
548+
LocalOptionConfig.pgSetup.settings.candidatePriority =
549+
FAILOVER_NODE_CANDIDATE_PRIORITY;
550+
}
551+
}
552+
else if (LocalOptionConfig.pgSetup.settings.candidatePriority > 0 &&
553+
LocalOptionConfig.citusRole == CITUS_ROLE_SECONDARY)
554+
{
555+
log_fatal("Citus does not support secondary roles that are "
556+
"also a candidate for failover: please use --secondary "
557+
"with --candidate-priority 0");
558+
exit(EXIT_CODE_BAD_ARGS);
559+
}
560+
561+
/* a --secondary citus worker requires a cluster name */
562+
if (LocalOptionConfig.citusRole == CITUS_ROLE_SECONDARY)
563+
{
564+
if (IS_EMPTY_STRING_BUFFER(LocalOptionConfig.pgSetup.citusClusterName))
565+
{
566+
log_fatal("When using --secondary, also use --citus-cluster");
567+
exit(EXIT_CODE_BAD_ARGS);
568+
}
569+
}
570+
513571
if (errors > 0)
514572
{
515573
commandline_help(stderr);
@@ -573,6 +631,8 @@ cli_common_keeper_getopts(int argc, char **argv,
573631
* { "verbose", no_argument, NULL, 'v' },
574632
* { "quiet", no_argument, NULL, 'q' },
575633
* { "help", no_argument, NULL, 'h' },
634+
* { "secondary", no_argument, NULL, 'z' },
635+
* { "citus-cluster", required_argument, NULL, 'Z' },
576636
* { "candidate-priority", required_argument, NULL, 'P'},
577637
* { "replication-quorum", required_argument, NULL, 'r'},
578638
* { "help", no_argument, NULL, 0 },
@@ -1253,12 +1313,14 @@ cli_print_version_getopts(int argc, char **argv)
12531313
void
12541314
keeper_cli_print_version(int argc, char **argv)
12551315
{
1316+
const char *version = PG_AUTOCTL_VERSION;
1317+
12561318
if (outputJSON)
12571319
{
12581320
JSON_Value *js = json_value_init_object();
12591321
JSON_Object *root = json_value_get_object(js);
12601322

1261-
json_object_set_string(root, "pg_autoctl", PG_AUTOCTL_VERSION);
1323+
json_object_set_string(root, "pg_autoctl", version);
12621324
json_object_set_string(root,
12631325
"pgautofailover", PG_AUTOCTL_EXTENSION_VERSION);
12641326
json_object_set_string(root, "pg_major", PG_MAJORVERSION);
@@ -1270,7 +1332,7 @@ keeper_cli_print_version(int argc, char **argv)
12701332
}
12711333
else
12721334
{
1273-
fformat(stdout, "pg_autoctl version %s\n", PG_AUTOCTL_VERSION);
1335+
fformat(stdout, "pg_autoctl version %s\n", version);
12741336
fformat(stdout,
12751337
"pg_autoctl extension version %s\n",
12761338
PG_AUTOCTL_EXTENSION_VERSION);
@@ -1333,10 +1395,8 @@ cli_drop_local_node(KeeperConfig *config, bool dropAndDestroy)
13331395
{
13341396
if (file_exists(config->pathnames.state))
13351397
{
1336-
bool ignoreMonitorErrors = true;
1337-
13381398
/* keeper_remove uses log_info() to explain what's happening */
1339-
if (!keeper_remove(&keeper, config, ignoreMonitorErrors))
1399+
if (!keeper_remove(&keeper, config))
13401400
{
13411401
log_fatal("Failed to remove local node from the pg_auto_failover "
13421402
"monitor, see above for details");

src/bin/pg_autoctl/cli_common.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ extern CommandLine drop_formation_command;
109109
extern CommandLine perform_failover_command;
110110
extern CommandLine perform_switchover_command;
111111

112-
113112
extern CommandLine *perform_subcommands[];
114113
extern CommandLine perform_commands;
115114

src/bin/pg_autoctl/cli_create_drop_node.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ cli_create_postgres_getopts(int argc, char **argv)
300300
{ "candidate-priority", required_argument, NULL, 'P' },
301301
{ "replication-quorum", required_argument, NULL, 'r' },
302302
{ "run", no_argument, NULL, 'x' },
303-
{ "help", no_argument, NULL, 0 },
304303
{ "no-ssl", no_argument, NULL, 'N' },
305304
{ "ssl-self-signed", no_argument, NULL, 's' },
306305
{ "ssl-mode", required_argument, &ssl_flag, SSL_MODE_FLAG },

src/bin/pg_autoctl/cli_do_root.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ extern CommandLine do_service_postgres_ctl_commands;
2525

2626
/* src/bin/pg_autoctl/cli_do_show.c */
2727
extern CommandLine do_show_commands;
28+
extern CommandLine do_pgsetup_commands;
29+
extern CommandLine do_service_postgres_ctl_commands;
30+
extern CommandLine do_service_commands;
2831

2932
/* src/bin/pg_autoctl/cli_do_demo.c */
3033
extern CommandLine do_demo_commands;
@@ -63,6 +66,8 @@ extern CommandLine do_standby_promote;
6366

6467
extern CommandLine do_discover;
6568

69+
extern CommandLine do_tmux_commands;
70+
6671
/* src/bin/pg_autoctl/cli_do_azure.c */
6772
extern CommandLine do_azure_ssh;
6873

src/bin/pg_autoctl/cli_root.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ extern CommandLine *create_subcommands[];
3434
extern CommandLine show_commands;
3535
extern CommandLine *show_subcommands[];
3636

37+
extern CommandLine show_commands_with_debug;
38+
extern CommandLine *show_subcommands_with_debug[];
39+
3740
extern CommandLine drop_commands;
3841
extern CommandLine *drop_subcommands[];
3942

src/bin/pg_autoctl/cli_show.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static void print_monitor_uri(Monitor *monitor, FILE *stream);
5555
static void print_formation_uri(SSLOptions *ssl,
5656
Monitor *monitor,
5757
const char *formation,
58+
const char *citusClusterName,
5859
FILE *stream);
5960
static void print_all_uri(SSLOptions *ssl,
6061
Monitor *monitor,
@@ -153,6 +154,7 @@ typedef struct ShowUriOptions
153154
{
154155
bool monitorOnly;
155156
char formation[NAMEDATALEN];
157+
char citusClusterName[NAMEDATALEN];
156158
} ShowUriOptions;
157159

158160
static ShowUriOptions showUriOptions = { 0 };
@@ -818,6 +820,7 @@ cli_show_uri_getopts(int argc, char **argv)
818820
{ "pgdata", required_argument, NULL, 'D' },
819821
{ "monitor", required_argument, NULL, 'm' },
820822
{ "formation", required_argument, NULL, 'f' },
823+
{ "citus-cluster", required_argument, NULL, 'Z' },
821824
{ "json", no_argument, NULL, 'J' },
822825
{ "version", no_argument, NULL, 'V' },
823826
{ "verbose", no_argument, NULL, 'v' },
@@ -874,6 +877,13 @@ cli_show_uri_getopts(int argc, char **argv)
874877
break;
875878
}
876879

880+
case 'Z':
881+
{
882+
strlcpy(showUriOptions.citusClusterName, optarg, NAMEDATALEN);
883+
log_trace("--citus-cluster %s", showUriOptions.citusClusterName);
884+
break;
885+
}
886+
877887
case 'V':
878888
{
879889
/* keeper_cli_print_version prints version and exits. */
@@ -951,8 +961,27 @@ cli_show_uri_getopts(int argc, char **argv)
951961
cli_common_get_set_pgdata_or_exit(&(options.pgSetup));
952962
}
953963

954-
/* when --pgdata is given, still initialise our pathnames */
955-
if (!IS_EMPTY_STRING_BUFFER(options.pgSetup.pgdata))
964+
/*
965+
* When --citus-cluster is used, but not --formation, then we assume
966+
* --formation default
967+
*/
968+
if (!IS_EMPTY_STRING_BUFFER(showUriOptions.citusClusterName) &&
969+
IS_EMPTY_STRING_BUFFER(showUriOptions.formation))
970+
{
971+
strlcpy(showUriOptions.formation, FORMATION_DEFAULT, NAMEDATALEN);
972+
}
973+
974+
/* use "default" citus cluster name when user didn't provide it */
975+
if (IS_EMPTY_STRING_BUFFER(showUriOptions.citusClusterName))
976+
{
977+
strlcpy(showUriOptions.citusClusterName,
978+
DEFAULT_CITUS_CLUSTER_NAME, NAMEDATALEN);
979+
}
980+
981+
cli_common_get_set_pgdata_or_exit(&(options.pgSetup));
982+
983+
if (!keeper_config_set_pathnames_from_pgdata(&(options.pathnames),
984+
options.pgSetup.pgdata))
956985
{
957986
if (!keeper_config_set_pathnames_from_pgdata(&(options.pathnames),
958987
options.pgSetup.pgdata))
@@ -1088,8 +1117,10 @@ cli_show_uri(int argc, char **argv)
10881117
}
10891118
else if (!IS_EMPTY_STRING_BUFFER(showUriOptions.formation))
10901119
{
1091-
(void) print_formation_uri(&ssl, &monitor,
1120+
(void) print_formation_uri(&ssl,
1121+
&monitor,
10921122
showUriOptions.formation,
1123+
showUriOptions.citusClusterName,
10931124
stdout);
10941125
}
10951126
else
@@ -1134,12 +1165,14 @@ static void
11341165
print_formation_uri(SSLOptions *ssl,
11351166
Monitor *monitor,
11361167
const char *formation,
1168+
const char *citusClusterName,
11371169
FILE *stream)
11381170
{
11391171
char postgresUri[MAXCONNINFO];
11401172

11411173
if (!monitor_formation_uri(monitor,
11421174
formation,
1175+
citusClusterName,
11431176
ssl,
11441177
postgresUri,
11451178
MAXCONNINFO))

src/bin/pg_autoctl/defaults.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
#define PG_AUTOCTL_STATE_VERSION 1
1515

1616
/* additional version information for printing version on CLI */
17-
#define PG_AUTOCTL_VERSION "1.4.2"
17+
#define PG_AUTOCTL_VERSION "1.5.0"
1818

1919
/* version of the extension that we requite to talk to on the monitor */
20-
#define PG_AUTOCTL_EXTENSION_VERSION "1.4"
20+
#define PG_AUTOCTL_EXTENSION_VERSION "1.5.0.1"
2121

2222
/* environment variable to use to make DEBUG facilities available */
2323
#define PG_AUTOCTL_DEBUG "PG_AUTOCTL_DEBUG"
@@ -85,6 +85,9 @@
8585
#define POSTGRESQL_FAILS_TO_START_TIMEOUT 20
8686
#define POSTGRESQL_FAILS_TO_START_RETRIES 3
8787

88+
#define DEFAULT_CITUS_ROLE "primary"
89+
#define DEFAULT_CITUS_CLUSTER_NAME "default"
90+
8891
#define FAILOVER_FORMATION_NUMBER_SYNC_STANDBYS 1
8992
#define FAILOVER_NODE_CANDIDATE_PRIORITY 50
9093
#define FAILOVER_NODE_REPLICATION_QUORUM true

src/bin/pg_autoctl/demoapp.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,12 @@ demoapp_grab_formation_uri(DemoAppOptions *options, char *pguri, size_t size,
8181
/* allow lots of retries to connect to the monitor at startup */
8282
pgsql_set_monitor_interactive_retry_policy(&(monitor.pgsql.retryPolicy));
8383

84-
if (!monitor_formation_uri(&monitor, options->formation, &ssl, pguri, size))
84+
if (!monitor_formation_uri(&monitor,
85+
options->formation,
86+
"default",
87+
&ssl,
88+
pguri,
89+
size))
8590
{
8691
int groupsCount = 0;
8792

src/bin/pg_autoctl/fsm.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@ bool fsm_prepare_cascade(Keeper *keeper);
6969
bool fsm_follow_new_primary(Keeper *keeper);
7070
bool fsm_cleanup_and_resume_as_primary(Keeper *keeper);
7171

72+
/*
73+
* Extra helpers.
74+
*/
75+
bool prepare_replication(Keeper *keeper, NodeState otherNodeState);
76+
7277
/*
7378
* Generic API to use the previous definitions.
7479
*/

src/bin/pg_autoctl/keeper.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,7 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState)
13101310
config->pgSetup.pgKind,
13111311
config->pgSetup.settings.candidatePriority,
13121312
config->pgSetup.settings.replicationQuorum,
1313+
config->pgSetup.citusClusterName,
13131314
&mayRetry,
13141315
&assignedState))
13151316
{
@@ -1439,7 +1440,7 @@ keeper_register_and_init(Keeper *keeper, NodeState initialState)
14391440
* local state file.
14401441
*/
14411442
bool
1442-
keeper_remove(Keeper *keeper, KeeperConfig *config, bool ignore_monitor_errors)
1443+
keeper_remove(Keeper *keeper, KeeperConfig *config)
14431444
{
14441445
int errors = 0;
14451446

@@ -1473,13 +1474,8 @@ keeper_remove(Keeper *keeper, KeeperConfig *config, bool ignore_monitor_errors)
14731474
config->hostname,
14741475
config->pgSetup.pgport))
14751476
{
1476-
/* we already logged about errors */
1477-
errors++;
1478-
1479-
if (!ignore_monitor_errors)
1480-
{
1481-
return false;
1482-
}
1477+
/* errors have already been logged */
1478+
return false;
14831479
}
14841480
}
14851481

0 commit comments

Comments
 (0)