When managing configuration changes through automatic systems like Chef
or Puppet, there is a problem: How do you manage changes requiring a
restart?

Generally, you'd set it up so that when a configuration file is changed,
the server is reloaded.  But for settings that require a restart, well,
I don't know.  From discussions with others, it emerged that a way to
ask the server whether a restart is necessary would be useful.  Then you
can either automate the restart, or have a monitoring system warn you
about it, and possibly schedule a restart separately or undo the
configuration file change.

So here is a patch for that.  It adds a column pending_restart to
pg_settings that is true when the configuration file contains a changed
setting that requires a restart.  We already had the logic to detect
such changes, for producing the log entry.  I have also set it up so
that if you change your mind and undo the setting and reload the server,
the pending_restart flag is reset to false.
>From dd477dba05c5fc3a6e51535bb8280a67d22271f5 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pete...@gmx.net>
Date: Sat, 14 Feb 2015 21:58:59 -0500
Subject: [PATCH] Add pg_settings.pending_restart column

---
 doc/src/sgml/catalogs.sgml          |  6 ++++++
 src/backend/utils/misc/guc.c        | 21 ++++++++++++++++++++-
 src/include/catalog/catversion.h    |  2 +-
 src/include/catalog/pg_proc.h       |  2 +-
 src/include/utils/guc_tables.h      |  1 +
 src/test/regress/expected/rules.out |  5 +++--
 6 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 515a40e..4d1a401 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -8841,6 +8841,12 @@ <title><structname>pg_settings</> Columns</title>
       or when examined by a non-superuser)
       </entry>
      </row>
+     <row>
+      <entry><structfield>pending_restart</structfield></entry>
+      <entry><type>boolean</type></entry>
+      <entry>Set to true of the value has been changed in the configuration
+       file but needs a restart.</entry>
+     </row>
     </tbody>
    </tgroup>
   </table>
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 9572777..44a2fc2 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5834,12 +5834,15 @@ set_config_option(const char *name, const char *value,
 				{
 					if (*conf->variable != newval)
 					{
+						record->status |= GUC_PENDING_RESTART;
 						ereport(elevel,
 								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
 										name)));
 						return 0;
 					}
+					else
+						record->status &= ~GUC_PENDING_RESTART;
 					return -1;
 				}
 
@@ -5922,12 +5925,15 @@ set_config_option(const char *name, const char *value,
 				{
 					if (*conf->variable != newval)
 					{
+						record->status |= GUC_PENDING_RESTART;
 						ereport(elevel,
 								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
 										name)));
 						return 0;
 					}
+					else
+						record->status &= ~GUC_PENDING_RESTART;
 					return -1;
 				}
 
@@ -6010,12 +6016,15 @@ set_config_option(const char *name, const char *value,
 				{
 					if (*conf->variable != newval)
 					{
+						record->status |= GUC_PENDING_RESTART;
 						ereport(elevel,
 								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
 										name)));
 						return 0;
 					}
+					else
+						record->status &= ~GUC_PENDING_RESTART;
 					return -1;
 				}
 
@@ -6116,12 +6125,15 @@ set_config_option(const char *name, const char *value,
 					if (*conf->variable == NULL || newval == NULL ||
 						strcmp(*conf->variable, newval) != 0)
 					{
+						record->status |= GUC_PENDING_RESTART;
 						ereport(elevel,
 								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
 										name)));
 						return 0;
 					}
+					else
+						record->status &= ~GUC_PENDING_RESTART;
 					return -1;
 				}
 
@@ -6209,12 +6221,15 @@ set_config_option(const char *name, const char *value,
 				{
 					if (*conf->variable != newval)
 					{
+						record->status |= GUC_PENDING_RESTART;
 						ereport(elevel,
 								(errcode(ERRCODE_CANT_CHANGE_RUNTIME_PARAM),
 								 errmsg("parameter \"%s\" cannot be changed without restarting the server",
 										name)));
 						return 0;
 					}
+					else
+						record->status &= ~GUC_PENDING_RESTART;
 					return -1;
 				}
 
@@ -7907,6 +7922,8 @@ GetConfigOptionByNum(int varnum, const char **values, bool *noshow)
 		values[14] = NULL;
 		values[15] = NULL;
 	}
+
+	values[16] = conf->status & GUC_PENDING_RESTART ? "t" : "f";
 }
 
 /*
@@ -7942,7 +7959,7 @@ show_config_by_name(PG_FUNCTION_ARGS)
  * show_all_settings - equiv to SHOW ALL command but implemented as
  * a Table Function.
  */
-#define NUM_PG_SETTINGS_ATTS	16
+#define NUM_PG_SETTINGS_ATTS	17
 
 Datum
 show_all_settings(PG_FUNCTION_ARGS)
@@ -8002,6 +8019,8 @@ show_all_settings(PG_FUNCTION_ARGS)
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 16, "sourceline",
 						   INT4OID, -1, 0);
+		TupleDescInitEntry(tupdesc, (AttrNumber) 17, "pending_restart",
+						   BOOLOID, -1, 0);
 
 		/*
 		 * Generate attribute metadata needed later to produce tuples from raw
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 2b7a0bb..cd89163 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201501281
+#define CATALOG_VERSION_NO	201502135
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 9edfdb8..04c58c0 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -3015,7 +3015,7 @@ DATA(insert OID = 2077 (  current_setting	PGNSP PGUID 12 1 0 0 0 f f f f t f s 1
 DESCR("SHOW X as a function");
 DATA(insert OID = 2078 (  set_config		PGNSP PGUID 12 1 0 0 0 f f f f f f v 3 0 25 "25 25 16" _null_ _null_ _null_ _null_ set_config_by_name _null_ _null_ _null_ ));
 DESCR("SET X as a function");
-DATA(insert OID = 2084 (  pg_show_all_settings	PGNSP PGUID 12 1 1000 0 0 f f f f t t s 0 0 2249 "" "{25,25,25,25,25,25,25,25,25,25,25,1009,25,25,25,23}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline}" _null_ show_all_settings _null_ _null_ _null_ ));
+DATA(insert OID = 2084 (  pg_show_all_settings	PGNSP PGUID 12 1 1000 0 0 f f f f t t s 0 0 2249 "" "{25,25,25,25,25,25,25,25,25,25,25,1009,25,25,25,23,16}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{name,setting,unit,category,short_desc,extra_desc,context,vartype,source,min_val,max_val,enumvals,boot_val,reset_val,sourcefile,sourceline,pending_restart}" _null_ show_all_settings _null_ _null_ _null_ ));
 DESCR("SHOW ALL as a function");
 DATA(insert OID = 1371 (  pg_lock_status   PGNSP PGUID 12 1 1000 0 0 f f f f t t v 0 0 2249 "" "{25,26,26,23,21,25,28,26,26,21,25,23,25,16,16}" "{o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{locktype,database,relation,page,tuple,virtualxid,transactionid,classid,objid,objsubid,virtualtransaction,pid,mode,granted,fastpath}" _null_ pg_lock_status _null_ _null_ _null_ ));
 DESCR("view system lock information");
diff --git a/src/include/utils/guc_tables.h b/src/include/utils/guc_tables.h
index cf319af..c0f9cb9 100644
--- a/src/include/utils/guc_tables.h
+++ b/src/include/utils/guc_tables.h
@@ -167,6 +167,7 @@ struct config_generic
  * Caution: the GUC_IS_IN_FILE bit is transient state for ProcessConfigFile.
  * Do not assume that its value represents useful information elsewhere.
  */
+#define GUC_PENDING_RESTART	0x0002
 
 
 /* GUC records for specific variable types */
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index d50b103..de10898 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1601,8 +1601,9 @@ pg_settings| SELECT a.name,
     a.boot_val,
     a.reset_val,
     a.sourcefile,
-    a.sourceline
-   FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline);
+    a.sourceline,
+    a.pending_restart
+   FROM pg_show_all_settings() a(name, setting, unit, category, short_desc, extra_desc, context, vartype, source, min_val, max_val, enumvals, boot_val, reset_val, sourcefile, sourceline, pending_restart);
 pg_shadow| SELECT pg_authid.rolname AS usename,
     pg_authid.oid AS usesysid,
     pg_authid.rolcreatedb AS usecreatedb,
-- 
2.3.0

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to