Skip to content

Commit 57d5ac0

Browse files
authored
Implement support for citus.local_hostname. (#731)
* Implement support for citus.local_hostname. * Allow retry when configuration file does not exists. There seem to be a race condition at process startup where we overwrite the configuration file when merging the command line arguments with the pre-existing setup. For a short while the configuration file is reported missing (ENOENT). Implement a very small retry loop so that `pg_autoctl do pgsetup wait` is more reliable, in particular in the test suite.
1 parent 0b8e181 commit 57d5ac0

12 files changed

Lines changed: 104 additions & 19 deletions

File tree

src/bin/pg_autoctl/cli_do_misc.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,22 @@ keeper_cli_add_default_settings(int argc, char **argv)
8888
{
8989
KeeperConfig config = keeperOptions;
9090
LocalPostgresServer postgres = { 0 };
91-
bool missingPgdataOk = false;
92-
bool postgresNotRunningOk = false;
9391

94-
keeper_config_init(&config, missingPgdataOk, postgresNotRunningOk);
92+
bool missingPgdataIsOk = true;
93+
bool pgIsNotRunningIsOk = true;
94+
bool monitorDisabledIsOk = true;
95+
96+
if (!keeper_config_read_file(&config,
97+
missingPgdataIsOk,
98+
pgIsNotRunningIsOk,
99+
monitorDisabledIsOk))
100+
{
101+
exit(EXIT_CODE_BAD_CONFIG);
102+
}
103+
95104
local_postgres_init(&postgres, &(config.pgSetup));
96105

97-
if (!postgres_add_default_settings(&postgres))
106+
if (!postgres_add_default_settings(&postgres, config.hostname))
98107
{
99108
log_fatal("Failed to add the default settings for streaming replication "
100109
"used by pg_auto_failover to postgresql.conf, "

src/bin/pg_autoctl/config.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,35 @@ ProbeConfigurationFileRole(const char *filename)
286286

287287
log_debug("Probing configuration file \"%s\"", filename);
288288

289-
if (!read_ini_file(filename, configOptions))
289+
/*
290+
* There is a race condition at process startup where a configuration file
291+
* can disappear while being overwritten. Reduce the chances of that
292+
* happening by making more than one attempt at reading the file.
293+
*/
294+
char *fileContents = NULL;
295+
296+
for (int attempts = 0; fileContents == NULL && attempts < 3; attempts++)
290297
{
291-
log_fatal("Failed to parse configuration file \"%s\"", filename);
292-
exit(EXIT_CODE_BAD_CONFIG);
298+
long fileSize = 0L;
299+
300+
if (read_file_if_exists(filename, &fileContents, &fileSize))
301+
{
302+
break;
303+
}
304+
305+
pg_usleep(100 * 1000); /* 100ms */
306+
}
307+
308+
if (fileContents == NULL)
309+
{
310+
log_error("Failed to read configuration file \"%s\"", filename);
311+
return PG_AUTOCTL_ROLE_UNKNOWN;
312+
}
313+
314+
if (!parse_ini_buffer(filename, fileContents, configOptions))
315+
{
316+
log_error("Failed to parse configuration file \"%s\"", filename);
317+
return PG_AUTOCTL_ROLE_UNKNOWN;
293318
}
294319

295320
log_debug("ProbeConfigurationFileRole: %s", config.role);

src/bin/pg_autoctl/fsm_transition.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ fsm_init_primary(Keeper *keeper)
232232
return false;
233233
}
234234

235-
if (!postgres_add_default_settings(postgres))
235+
if (!postgres_add_default_settings(postgres, config->hostname))
236236
{
237237
log_error("Failed to initialize postgres as primary because "
238238
"adding default settings failed, see above for details");

src/bin/pg_autoctl/ini_file.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,27 @@ read_ini_file(const char *filename, IniOption *optionList)
2626
{
2727
char *fileContents = NULL;
2828
long fileSize = 0L;
29-
IniOption *option;
3029

3130
/* read the current postgresql.conf contents */
3231
if (!read_file(filename, &fileContents, &fileSize))
3332
{
3433
return false;
3534
}
3635

36+
return parse_ini_buffer(filename, fileContents, optionList);
37+
}
38+
39+
40+
/*
41+
* parse_ini_buffer parses the content of a config.ini file.
42+
*/
43+
bool
44+
parse_ini_buffer(const char *filename,
45+
char *fileContents,
46+
IniOption *optionList)
47+
{
48+
IniOption *option;
49+
3750
/* parse the content of the file as per INI syntax rules */
3851
ini_t *ini = ini_load(fileContents, NULL);
3952
free(fileContents);

src/bin/pg_autoctl/ini_file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ typedef struct IniOption
9393
{ INI_END_T, NULL, NULL, NULL, false, false, NULL, -1, -1, NULL, NULL, NULL }
9494

9595
bool read_ini_file(const char *filename, IniOption *opts);
96+
bool parse_ini_buffer(const char *filename,
97+
char *fileContents,
98+
IniOption *optionList);
9699
bool ini_validate_options(IniOption *optionList);
97100
bool ini_set_option_value(IniOption *option, const char *value);
98101
bool ini_option_to_string(IniOption *option, char *dest, size_t size);

src/bin/pg_autoctl/keeper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ keeper_ensure_configuration(Keeper *keeper, bool postgresNotRunningIsOk)
805805
* options being found in our pg_autoctl configuration file or for other
806806
* reasons.
807807
*/
808-
if (!postgres_add_default_settings(postgres))
808+
if (!postgres_add_default_settings(postgres, config->hostname))
809809
{
810810
log_warn("Failed to edit Postgres configuration after "
811811
"reloading pg_autoctl configuration, "

src/bin/pg_autoctl/keeper_pg_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ create_database_and_extension(Keeper *keeper)
905905
* shared_preload_libraries when dealing with a Citus worker or coordinator
906906
* node.
907907
*/
908-
if (!postgres_add_default_settings(&initPostgres))
908+
if (!postgres_add_default_settings(&initPostgres, config->hostname))
909909
{
910910
log_error("Failed to add default settings to newly initialized "
911911
"PostgreSQL instance, see above for details");

src/bin/pg_autoctl/monitor_pg_init.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,9 @@ monitor_add_postgres_default_settings(Monitor *monitor)
343343
}
344344
}
345345

346-
if (!pg_add_auto_failover_default_settings(pgSetup, configFilePath,
346+
if (!pg_add_auto_failover_default_settings(pgSetup,
347+
config->hostname,
348+
configFilePath,
347349
monitor_default_settings))
348350
{
349351
log_error("Failed to add default settings to \"%s\": couldn't "

src/bin/pg_autoctl/pgctl.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ static bool pg_include_config(const char *configFilePath,
4646
static bool ensure_default_settings_file_exists(const char *configFilePath,
4747
GUC *settings,
4848
PostgresSetup *pgSetup,
49+
const char *hostname,
4950
bool includeTuning);
5051
static bool prepare_guc_settings_from_pgsetup(const char *configFilePath,
5152
PQExpBuffer config,
5253
GUC *settings,
5354
PostgresSetup *pgSetup,
55+
const char *hostname,
5456
bool includeTuning);
5557
static void log_program_output(Program prog, int outLogLevel, int errorLogLevel);
5658

@@ -731,7 +733,8 @@ find_extension_control_file(const char *pg_ctl, const char *extName)
731733
*/
732734
bool
733735
pg_add_auto_failover_default_settings(PostgresSetup *pgSetup,
734-
char *configFilePath,
736+
const char *hostname,
737+
const char *configFilePath,
735738
GUC *settings)
736739
{
737740
bool includeTuning = true;
@@ -750,6 +753,7 @@ pg_add_auto_failover_default_settings(PostgresSetup *pgSetup,
750753
if (!ensure_default_settings_file_exists(pgAutoFailoverDefaultsConfigPath,
751754
settings,
752755
pgSetup,
756+
hostname,
753757
includeTuning))
754758
{
755759
return false;
@@ -870,6 +874,7 @@ static bool
870874
ensure_default_settings_file_exists(const char *configFilePath,
871875
GUC *settings,
872876
PostgresSetup *pgSetup,
877+
const char *hostname,
873878
bool includeTuning)
874879
{
875880
PQExpBuffer defaultConfContents = createPQExpBuffer();
@@ -884,6 +889,7 @@ ensure_default_settings_file_exists(const char *configFilePath,
884889
defaultConfContents,
885890
settings,
886891
pgSetup,
892+
hostname,
887893
includeTuning))
888894
{
889895
/* errors have already been logged */
@@ -957,6 +963,7 @@ prepare_guc_settings_from_pgsetup(const char *configFilePath,
957963
PQExpBuffer config,
958964
GUC *settings,
959965
PostgresSetup *pgSetup,
966+
const char *hostname,
960967
bool includeTuning)
961968
{
962969
char tuning[BUFSIZE] = { 0 };
@@ -1101,14 +1108,23 @@ prepare_guc_settings_from_pgsetup(const char *configFilePath,
11011108
setting->name, pgSetup->citusClusterName);
11021109
}
11031110
}
1111+
else if (streq(setting->name, "citus.local_hostname"))
1112+
{
1113+
if (hostname != NULL && !IS_EMPTY_STRING_BUFFER(hostname))
1114+
{
1115+
appendPQExpBuffer(config, "%s = '%s'\n",
1116+
setting->name, hostname);
1117+
}
1118+
}
11041119
else if (setting->value != NULL &&
11051120
!IS_EMPTY_STRING_BUFFER(setting->value))
11061121
{
11071122
appendPQExpBuffer(config, "%s = %s\n",
11081123
setting->name,
11091124
setting->value);
11101125
}
1111-
else
1126+
else if (setting->value == NULL ||
1127+
IS_EMPTY_STRING_BUFFER(setting->value))
11121128
{
11131129
/*
11141130
* Our GUC entry has a NULL (or empty) value. Skip the setting.
@@ -1122,6 +1138,13 @@ prepare_guc_settings_from_pgsetup(const char *configFilePath,
11221138
*/
11231139
log_debug("GUC setting \"%s\" has a NULL value", setting->name);
11241140
}
1141+
else
1142+
{
1143+
/* the GUC setting in the array has not been processed */
1144+
log_error("BUG: GUC settings \"%s\" has not been processed",
1145+
setting->name);
1146+
return false;
1147+
}
11251148
}
11261149

11271150
if (includeTuning)
@@ -2004,6 +2027,7 @@ pg_write_recovery_conf(const char *pgdata, ReplicationSource *replicationSource)
20042027
return ensure_default_settings_file_exists(recoveryConfPath,
20052028
recoverySettings,
20062029
NULL,
2030+
NULL,
20072031
includeTuning);
20082032
}
20092033

@@ -2103,6 +2127,7 @@ pg_write_standby_signal(const char *pgdata,
21032127
if (!ensure_default_settings_file_exists(standbyConfigFilePath,
21042128
recoverySettings,
21052129
NULL,
2130+
NULL,
21062131
includeTuning))
21072132
{
21082133
return false;

src/bin/pg_autoctl/pgctl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ bool set_pg_ctl_from_config_bindir(PostgresSetup *pgSetup, const char *pg_config
3838
bool find_pg_config_from_pg_ctl(const char *pg_ctl, char *pg_config, size_t size);
3939

4040
bool pg_add_auto_failover_default_settings(PostgresSetup *pgSetup,
41-
char *configFilePath,
41+
const char *hostname,
42+
const char *configFilePath,
4243
GUC *settings);
4344

4445
bool pg_auto_failover_default_settings_file_exists(PostgresSetup *pgSetup);

0 commit comments

Comments
 (0)