aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/ref/postgres-ref.sgml11
-rw-r--r--src/backend/postmaster/postmaster.c50
-rw-r--r--src/backend/utils/misc/guc.c8
-rw-r--r--src/bin/pg_checksums/t/002_actions.pl22
-rw-r--r--src/include/utils/guc.h6
5 files changed, 83 insertions, 14 deletions
diff --git a/doc/src/sgml/ref/postgres-ref.sgml b/doc/src/sgml/ref/postgres-ref.sgml
index 4aaa7abe1a2..f72c3b04e42 100644
--- a/doc/src/sgml/ref/postgres-ref.sgml
+++ b/doc/src/sgml/ref/postgres-ref.sgml
@@ -133,14 +133,21 @@ PostgreSQL documentation
<listitem>
<para>
Prints the value of the named run-time parameter, and exits.
- (See the <option>-c</option> option above for details.) This can
- be used on a running server, and returns values from
+ (See the <option>-c</option> option above for details.) This
+ returns values from
<filename>postgresql.conf</filename>, modified by any parameters
supplied in this invocation. It does not reflect parameters
supplied when the cluster was started.
</para>
<para>
+ This can be used on a running server for most parameters. However,
+ the server must be shut down for some runtime-computed parameters
+ (e.g., <xref linkend="guc-shared-memory-size"/> and
+ <xref linkend="guc-wal-segment-size"/>).
+ </para>
+
+ <para>
This option is meant for other programs that interact with a server
instance, such as <xref linkend="app-pg-ctl"/>, to query configuration
parameter values. User-facing applications should instead use <link
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index b2fe420c3cf..d16d881e570 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -896,15 +896,31 @@ PostmasterMain(int argc, char *argv[])
if (output_config_variable != NULL)
{
/*
- * "-C guc" was specified, so print GUC's value and exit. No extra
- * permission check is needed because the user is reading inside the
- * data dir.
+ * If this is a runtime-computed GUC, it hasn't yet been initialized,
+ * and the present value is not useful. However, this is a convenient
+ * place to print the value for most GUCs because it is safe to run
+ * postmaster startup to this point even if the server is already
+ * running. For the handful of runtime-computed GUCs that we cannot
+ * provide meaningful values for yet, we wait until later in
+ * postmaster startup to print the value. We won't be able to use -C
+ * on running servers for those GUCs, but using this option now would
+ * lead to incorrect results for them.
*/
- const char *config_val = GetConfigOption(output_config_variable,
- false, false);
+ int flags = GetConfigOptionFlags(output_config_variable, true);
- puts(config_val ? config_val : "");
- ExitPostmaster(0);
+ if ((flags & GUC_RUNTIME_COMPUTED) == 0)
+ {
+ /*
+ * "-C guc" was specified, so print GUC's value and exit. No
+ * extra permission check is needed because the user is reading
+ * inside the data dir.
+ */
+ const char *config_val = GetConfigOption(output_config_variable,
+ false, false);
+
+ puts(config_val ? config_val : "");
+ ExitPostmaster(0);
+ }
}
/* Verify that DataDir looks reasonable */
@@ -1034,6 +1050,26 @@ PostmasterMain(int argc, char *argv[])
InitializeShmemGUCs();
/*
+ * If -C was specified with a runtime-computed GUC, we held off printing
+ * the value earlier, as the GUC was not yet initialized. We handle -C
+ * for most GUCs before we lock the data directory so that the option may
+ * be used on a running server. However, a handful of GUCs are runtime-
+ * computed and do not have meaningful values until after locking the data
+ * directory, and we cannot safely calculate their values earlier on a
+ * running server. At this point, such GUCs should be properly
+ * initialized, and we haven't yet set up shared memory, so this is a good
+ * time to handle the -C option for these special GUCs.
+ */
+ if (output_config_variable != NULL)
+ {
+ const char *config_val = GetConfigOption(output_config_variable,
+ false, false);
+
+ puts(config_val ? config_val : "");
+ ExitPostmaster(0);
+ }
+
+ /*
* Set up shared memory and semaphores.
*/
reset_shared();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 23236fa4c3d..a6e4fcc24ed 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -1983,7 +1983,7 @@ static struct config_bool ConfigureNamesBool[] =
{"data_checksums", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows whether data checksums are turned on for this cluster."),
NULL,
- GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+ GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED
},
&data_checksums,
false,
@@ -2342,7 +2342,7 @@ static struct config_int ConfigureNamesInt[] =
{"shared_memory_size", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the size of the server's main shared memory area (rounded up to the nearest MB)."),
NULL,
- GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_UNIT_MB
+ GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_UNIT_MB | GUC_RUNTIME_COMPUTED
},
&shared_memory_size_mb,
0, 0, INT_MAX,
@@ -2407,7 +2407,7 @@ static struct config_int ConfigureNamesInt[] =
"in the form accepted by the chmod and umask system "
"calls. (To use the customary octal format the number "
"must start with a 0 (zero).)"),
- GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+ GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED
},
&data_directory_mode,
0700, 0000, 0777,
@@ -3231,7 +3231,7 @@ static struct config_int ConfigureNamesInt[] =
{"wal_segment_size", PGC_INTERNAL, PRESET_OPTIONS,
gettext_noop("Shows the size of write ahead log segments."),
NULL,
- GUC_UNIT_BYTE | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
+ GUC_UNIT_BYTE | GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_RUNTIME_COMPUTED
},
&wal_segment_size,
DEFAULT_XLOG_SEG_SIZE,
diff --git a/src/bin/pg_checksums/t/002_actions.pl b/src/bin/pg_checksums/t/002_actions.pl
index a18c104a94d..2cc8b68c75f 100644
--- a/src/bin/pg_checksums/t/002_actions.pl
+++ b/src/bin/pg_checksums/t/002_actions.pl
@@ -10,7 +10,7 @@ use PostgresNode;
use TestLib;
use Fcntl qw(:seek);
-use Test::More tests => 63;
+use Test::More tests => 69;
# Utility routine to create and check a table with corrupted checksums
@@ -178,11 +178,31 @@ command_fails(
[ 'pg_checksums', '--enable', '--filenode', '1234', '-D', $pgdata ],
"fails when relfilenodes are requested and action is --enable");
+# Test postgres -C for an offline cluster.
+# Run-time GUCs are safe to query here. Note that a lock file is created,
+# then unlinked, leading to an extra LOG entry showing in stderr.
+command_checks_all(
+ [ 'postgres', '-D', $pgdata, '-C', 'data_checksums' ],
+ 0,
+ [qr/^on$/],
+ # LOG entry when unlinking lock file.
+ [qr/database system is shut down/],
+ 'data_checksums=on is reported on an offline cluster');
+
# Checks cannot happen with an online cluster
$node->start;
command_fails([ 'pg_checksums', '--check', '-D', $pgdata ],
"fails with online cluster");
+# Test postgres -C on an online cluster.
+command_fails_like(
+ [ 'postgres', '-D', $pgdata, '-C', 'data_checksums' ],
+ qr/lock file .* already exists/,
+ 'data_checksums is not reported on an online cluster');
+command_ok(
+ [ 'postgres', '-D', $pgdata, '-C', 'work_mem' ],
+ 'non-runtime parameter is reported on an online cluster');
+
# Check corruption of table on default tablespace.
check_relation_corruption($node, 'corrupt1', 'pg_default');
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index a7c3a4958e0..aa18d304ac0 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -229,6 +229,12 @@ typedef enum
#define GUC_EXPLAIN 0x100000 /* include in explain */
+/*
+ * GUC_RUNTIME_COMPUTED is intended for runtime-computed GUCs that are only
+ * available via 'postgres -C' if the server is not running.
+ */
+#define GUC_RUNTIME_COMPUTED 0x200000
+
#define GUC_UNIT (GUC_UNIT_MEMORY | GUC_UNIT_TIME)