pg.ddx.io pgsql-bugs@postgresql.org mailing list archive
help / color / mirror / Atom feed From: Tom Lane <tgl@sss.pgh.pa.us>
To: Andres Freund <andres@anarazel.de>
Cc: Sisson, David <David.Sisson@dell.com>
Cc: Tomas Vondra <tomas.vondra@enterprisedb.com>
Cc: pgsql-bugs@lists.postgresql.org <pgsql-bugs@lists.postgresql.org>
Subject: Re: BUG #17757: Not honoring huge_pages setting during initdb causes DB crash in Kubernetes
Date: Mon, 23 Jan 2023 17:51:46 -0500
Message-ID: <2139743.1674514306@sss.pgh.pa.us> (raw )
In-Reply-To: <20230123195504.uvlcd3aytn3jg744@awork3.anarazel.de >
References: <17757-dbdfc1f1c954a6db@postgresql.org >
<4ce40288-5b88-f9fb-ea11-fc932c61472b@enterprisedb.com >
<1113115.1674343827@sss.pgh.pa.us >
<127328f2-4e01-e9ec-c9b1-76aef967343f@enterprisedb.com >
<20230122020826.x6geac6qjiinr66a@awork3.anarazel.de >
<LV2PR19MB5765BF10D8D3FD015C6011468EC89@LV2PR19MB5765.namprd19.prod.outlook.com >
<20230123195504.uvlcd3aytn3jg744@awork3.anarazel.de >
Andres Freund <andres@anarazel.de> writes:
> It's a fault of the environment if mmap(MAP_HUGETLB) causes a SIGBUS. Normally
> huge_pages = try is harmless, because it'll just fall back. That source of
> SIGBUSes needs to be fixed regardless of anything else - plenty allocators try
> to use huge pages for example, so you'll run into problems regardless of
> postgres' default.
That seems likely to me too.
> That said, I'm for allowing to specify options to initdb.
Yeah, I think that has enough other potential applications to be worth
doing. Here's a quick draft patch (sans user-facing docs as yet).
It injects any given values into postgresql.auto.conf, not
postgresql.conf proper. I did that mainly because the latter looked
beyond the abilities of the primitive string-munging code we have in
there, but I think it can be argued to be a reasonable choice anyway.
regards, tom lane
Attachments:
override-config-options-during-initdb-0.1.patch (text/x-diff, 8.3K) download
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 7a58c33ace..e6f1f42cae 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -82,6 +82,13 @@
/* Ideally this would be in a .h file, but it hardly seems worth the trouble */
extern const char *select_default_timezone(const char *share_path);
+/* simple list of strings */
+typedef struct _stringlist
+{
+ char *str;
+ struct _stringlist *next;
+} _stringlist;
+
static const char *const auth_methods_host[] = {
"trust", "reject", "scram-sha-256", "md5", "password", "ident", "radius",
#ifdef ENABLE_GSS
@@ -142,6 +149,8 @@ static char *pwfilename = NULL;
static char *superuser_password = NULL;
static const char *authmethodhost = NULL;
static const char *authmethodlocal = NULL;
+static _stringlist *extra_guc_names = NULL;
+static _stringlist *extra_guc_values = NULL;
static bool debug = false;
static bool noclean = false;
static bool noinstructions = false;
@@ -253,6 +262,7 @@ static void check_input(char *path);
static void write_version_file(const char *extrapath);
static void set_null_conf(void);
static void test_config_settings(void);
+static bool test_specific_config_settings(int test_conns, int test_buffs);
static void setup_config(void);
static void bootstrap_template1(void);
static void setup_auth(FILE *cmdfd);
@@ -359,6 +369,27 @@ escape_quotes_bki(const char *src)
return result;
}
+/*
+ * Add an item at the end of a stringlist.
+ */
+static void
+add_stringlist_item(_stringlist **listhead, const char *str)
+{
+ _stringlist *newentry = pg_malloc(sizeof(_stringlist));
+ _stringlist *oldentry;
+
+ newentry->str = pg_strdup(str);
+ newentry->next = NULL;
+ if (*listhead == NULL)
+ *listhead = newentry;
+ else
+ {
+ for (oldentry = *listhead; oldentry->next; oldentry = oldentry->next)
+ /* skip */ ;
+ oldentry->next = newentry;
+ }
+}
+
/*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
@@ -873,11 +904,9 @@ test_config_settings(void)
400, 300, 200, 100, 50
};
- char cmd[MAXPGPATH];
const int connslen = sizeof(trial_conns) / sizeof(int);
const int bufslen = sizeof(trial_bufs) / sizeof(int);
int i,
- status,
test_conns,
test_buffs,
ok_buffers = 0;
@@ -903,19 +932,7 @@ test_config_settings(void)
test_conns = trial_conns[i];
test_buffs = MIN_BUFS_FOR_CONNS(test_conns);
- snprintf(cmd, sizeof(cmd),
- "\"%s\" --check %s %s "
- "-c max_connections=%d "
- "-c shared_buffers=%d "
- "-c dynamic_shared_memory_type=%s "
- "< \"%s\" > \"%s\" 2>&1",
- backend_exec, boot_options, extra_options,
- test_conns, test_buffs,
- dynamic_shared_memory_type,
- DEVNULL, DEVNULL);
- fflush(NULL);
- status = system(cmd);
- if (status == 0)
+ if (test_specific_config_settings(test_conns, test_buffs))
{
ok_buffers = test_buffs;
break;
@@ -940,19 +957,7 @@ test_config_settings(void)
break;
}
- snprintf(cmd, sizeof(cmd),
- "\"%s\" --check %s %s "
- "-c max_connections=%d "
- "-c shared_buffers=%d "
- "-c dynamic_shared_memory_type=%s "
- "< \"%s\" > \"%s\" 2>&1",
- backend_exec, boot_options, extra_options,
- n_connections, test_buffs,
- dynamic_shared_memory_type,
- DEVNULL, DEVNULL);
- fflush(NULL);
- status = system(cmd);
- if (status == 0)
+ if (test_specific_config_settings(n_connections, test_buffs))
break;
}
n_buffers = test_buffs;
@@ -968,6 +973,48 @@ test_config_settings(void)
printf("%s\n", default_timezone ? default_timezone : "GMT");
}
+/*
+ * Test a specific combination of configuration settings.
+ */
+static bool
+test_specific_config_settings(int test_conns, int test_buffs)
+{
+ PQExpBuffer cmd = createPQExpBuffer();
+ int status;
+ _stringlist *gnames,
+ *gvalues;
+
+ /* Set up the test postmaster invocation */
+ printfPQExpBuffer(cmd,
+ "\"%s\" --check %s %s "
+ "-c max_connections=%d "
+ "-c shared_buffers=%d "
+ "-c dynamic_shared_memory_type=%s",
+ backend_exec, boot_options, extra_options,
+ test_conns, test_buffs,
+ dynamic_shared_memory_type);
+
+ /* Add any user-given setting overrides */
+ for (gnames = extra_guc_names, gvalues = extra_guc_values;
+ gnames != NULL; /* assume lists have the same length */
+ gnames = gnames->next, gvalues = gvalues->next)
+ {
+ appendPQExpBuffer(cmd, " -c %s=", gnames->str);
+ appendShellString(cmd, gvalues->str);
+ }
+
+ appendPQExpBuffer(cmd,
+ " < \"%s\" > \"%s\" 2>&1",
+ DEVNULL, DEVNULL);
+
+ fflush(NULL);
+ status = system(cmd->data);
+
+ destroyPQExpBuffer(cmd);
+
+ return (status == 0);
+}
+
/*
* Calculate the default wal_size with a "pretty" unit.
*/
@@ -994,7 +1041,10 @@ setup_config(void)
char **conflines;
char repltok[MAXPGPATH];
char path[MAXPGPATH];
- char *autoconflines[3];
+ char **autoconflines;
+ int numautoconflines;
+ _stringlist *gnames,
+ *gvalues;
fputs(_("creating configuration files ... "), stdout);
fflush(stdout);
@@ -1152,15 +1202,32 @@ setup_config(void)
if (chmod(path, pg_file_create_mode) != 0)
pg_fatal("could not change permissions of \"%s\": %m", path);
+ free(conflines);
+
+
/*
- * create the automatic configuration file to store the configuration
- * parameters set by ALTER SYSTEM command. The parameters present in this
- * file will override the value of parameters that exists before parse of
- * this file.
+ * Create the automatic configuration file that stores the configuration
+ * parameters set by the ALTER SYSTEM command. We also place any
+ * parameter values set with initdb's -c option into this file.
*/
+ numautoconflines = 2; /* fixed header lines */
+ for (gnames = extra_guc_names; gnames != NULL; gnames = gnames->next)
+ numautoconflines++;
+ autoconflines = (char **) pg_malloc((numautoconflines + 1) * sizeof(char *));
+
autoconflines[0] = pg_strdup("# Do not edit this file manually!\n");
autoconflines[1] = pg_strdup("# It will be overwritten by the ALTER SYSTEM command.\n");
- autoconflines[2] = NULL;
+ numautoconflines = 2;
+ for (gnames = extra_guc_names, gvalues = extra_guc_values;
+ gnames != NULL; /* assume lists have the same length */
+ gnames = gnames->next, gvalues = gvalues->next)
+ {
+ autoconflines[numautoconflines++] =
+ psprintf("%s = '%s'\n",
+ gnames->str,
+ escape_quotes(gvalues->str));
+ }
+ autoconflines[numautoconflines] = NULL;
sprintf(path, "%s/postgresql.auto.conf", pg_data);
@@ -1168,7 +1235,7 @@ setup_config(void)
if (chmod(path, pg_file_create_mode) != 0)
pg_fatal("could not change permissions of \"%s\": %m", path);
- free(conflines);
+ free(autoconflines);
/* pg_hba.conf */
@@ -2103,6 +2170,7 @@ usage(const char *progname)
printf(_(" -A, --auth=METHOD default authentication method for local connections\n"));
printf(_(" --auth-host=METHOD default authentication method for local TCP/IP connections\n"));
printf(_(" --auth-local=METHOD default authentication method for local-socket connections\n"));
+ printf(_(" -c NAME=VALUE override default setting for server parameter\n"));
printf(_(" [-D, --pgdata=]DATADIR location for this database cluster\n"));
printf(_(" -E, --encoding=ENCODING set default encoding for new databases\n"));
printf(_(" -g, --allow-group-access allow group read/execute on data directory\n"));
@@ -2808,7 +2876,8 @@ main(int argc, char *argv[])
/* process command-line options */
- while ((c = getopt_long(argc, argv, "A:dD:E:gkL:nNsST:U:WX:", long_options, &option_index)) != -1)
+ while ((c = getopt_long(argc, argv, "A:c:dD:E:gkL:nNsST:U:WX:",
+ long_options, &option_index)) != -1)
{
switch (c)
{
@@ -2831,6 +2900,24 @@ main(int argc, char *argv[])
case 11:
authmethodhost = pg_strdup(optarg);
break;
+ case 'c':
+ {
+ char *buf = pg_strdup(optarg);
+ char *equals = strchr(buf, '=');
+
+ if (!equals)
+ {
+ pg_log_error("-c %s requires a value", buf);
+ pg_log_error_hint("Try \"%s --help\" for more information.",
+ progname);
+ exit(1);
+ }
+ *equals++ = '\0'; /* terminate variable name */
+ add_stringlist_item(&extra_guc_names, buf);
+ add_stringlist_item(&extra_guc_values, equals);
+ pfree(buf);
+ }
+ break;
case 'D':
pg_data = pg_strdup(optarg);
break;
view thread (25+ messages) latest in thread
Message-ID: <2139743.1674514306@sss.pgh.pa.us>
Permalink: ../2139743.1674514306@sss.pgh.pa.us/
Also on: postgresql.org/message-id/2139743.1674514306@sss.pgh.pa.us
copy link · copy postgr.es · copy git am
reply Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-bugs@postgresql.org
Cc: tgl@sss.pgh.pa.us, andres@anarazel.de, David.Sisson@dell.com, tomas.vondra@enterprisedb.com, pgsql-bugs@lists.postgresql.org
Subject: Re: BUG #17757: Not honoring huge_pages setting during initdb causes DB crash in Kubernetes
In-Reply-To: <2139743.1674514306@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox