PGC_INTERNAL, PGC_S_OVERRIDE);
        /* If we have no other source of client_encoding, use server encoding */
        SetConfigOption("client_encoding", GetDatabaseEncodingName(),
-                                       PGC_BACKEND, PGC_S_DEFAULT);
+                                       PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
 
        /* assign locale variables */
        collate = NameStr(dbform->datcollate);
 
 #include <ctype.h>
 #include <unistd.h>
 
+#include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "storage/fd.h"
 #include "utils/guc.h"
                                   *tail;
        char       *cvc = NULL;
        struct config_string *cvc_struct;
-       const char *envvar;
        int                     i;
 
        Assert(context == PGC_POSTMASTER || context == PGC_SIGHUP);
                                stack->source = PGC_S_DEFAULT;
                }
 
-               /* Now we can re-apply the wired-in default */
+               /* Now we can re-apply the wired-in default (i.e., the boot_val) */
                set_config_option(gconf->name, NULL, context, PGC_S_DEFAULT,
                                                  GUC_ACTION_SET, true);
                if (context == PGC_SIGHUP)
        }
 
        /*
-        * Restore any variables determined by environment variables.  This
-        * is a no-op except in the case where one of these had been in the
-        * config file and is now removed.  PGC_S_ENV_VAR will override the
-        * wired-in default we just applied, but cannot override any other source.
+        * Restore any variables determined by environment variables or
+        * dynamically-computed defaults.  This is a no-op except in the case
+        * where one of these had been in the config file and is now removed.
         *
-        * Keep this list in sync with InitializeGUCOptions()!
-        * PGPORT can be ignored, because it cannot be changed without restart.
-        * We assume rlimit hasn't changed, either.
+        * In particular, we *must not* do this during the postmaster's
+        * initial loading of the file, since the timezone functions in
+        * particular should be run only after initialization is complete.
+        *
+        * XXX this is an unmaintainable crock, because we have to know how
+        * to set (or at least what to call to set) every variable that could
+        * potentially have PGC_S_DYNAMIC_DEFAULT or PGC_S_ENV_VAR source.
+        * However, there's no time to redesign it for 9.1.
         */
-       envvar = getenv("PGDATESTYLE");
-       if (envvar != NULL)
-               set_config_option("datestyle", envvar, PGC_POSTMASTER,
-                                                 PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
-       envvar = getenv("PGCLIENTENCODING");
-       if (envvar != NULL)
-               set_config_option("client_encoding", envvar, PGC_POSTMASTER,
-                                                 PGC_S_ENV_VAR, GUC_ACTION_SET, true);
-
+       if (context == PGC_SIGHUP)
+       {
+               InitializeGUCOptionsFromEnvironment();
+               pg_timezone_initialize();
+               pg_timezone_abbrev_initialize();
+               /* this selects SQL_ASCII in processes not connected to a database */
+               SetConfigOption("client_encoding", GetDatabaseEncodingName(),
+                                               PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT);
+       }
 
        /* If we got here all the options checked out okay, so apply them. */
        for (item = head; item; item = item->next)
 
 const char *const GucSource_Names[] =
 {
         /* PGC_S_DEFAULT */ "default",
+        /* PGC_S_DYNAMIC_DEFAULT */ "default",
         /* PGC_S_ENV_VAR */ "environment variable",
         /* PGC_S_FILE */ "configuration file",
         /* PGC_S_ARGV */ "command line",
 
 static int     guc_var_compare(const void *a, const void *b);
 static int     guc_name_compare(const char *namea, const char *nameb);
+static void InitializeGUCOptionsFromEnvironment(void);
 static void InitializeOneGUCOption(struct config_generic * gconf);
 static void push_old_value(struct config_generic * gconf, GucAction action);
 static void ReportGUCOption(struct config_generic * record);
 InitializeGUCOptions(void)
 {
        int                     i;
-       char       *env;
-       long            stack_rlimit;
 
        /*
         * Before log_line_prefix could possibly receive a nonempty setting, make
 
        /*
         * For historical reasons, some GUC parameters can receive defaults from
-        * environment variables.  Process those settings.      NB: if you add or
-        * remove anything here, see also ProcessConfigFile().
+        * environment variables.  Process those settings.
         */
+       InitializeGUCOptionsFromEnvironment();
+}
+
+/*
+ * Assign any GUC values that can come from the server's environment.
+ *
+ * This is called from InitializeGUCOptions, and also from ProcessConfigFile
+ * to deal with the possibility that a setting has been removed from
+ * postgresql.conf and should now get a value from the environment.
+ * (The latter is a kludge that should probably go away someday; if so,
+ * fold this back into InitializeGUCOptions.)
+ */
+static void
+InitializeGUCOptionsFromEnvironment(void)
+{
+       char       *env;
+       long            stack_rlimit;
 
        env = getenv("PGPORT");
        if (env != NULL)
        switch (pHolder->gen.source)
        {
                case PGC_S_DEFAULT:
+               case PGC_S_DYNAMIC_DEFAULT:
                case PGC_S_ENV_VAR:
                case PGC_S_FILE:
                case PGC_S_ARGV:
  *
  * This is called after initial loading of postgresql.conf.  If no
  * timezone_abbreviations setting was found therein, select default.
+ * If a non-default value is already installed, nothing will happen.
  */
 void
 pg_timezone_abbrev_initialize(void)
 {
-       if (timezone_abbreviations_string == NULL)
-       {
-               SetConfigOption("timezone_abbreviations", "Default",
-                                               PGC_POSTMASTER, PGC_S_DEFAULT);
-       }
+       SetConfigOption("timezone_abbreviations", "Default",
+                                       PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT);
 }
 
 static const char *
 
  */
 typedef enum
 {
-       PGC_S_DEFAULT,                          /* wired-in default */
+       PGC_S_DEFAULT,                          /* hard-wired default ("boot_val") */
+       PGC_S_DYNAMIC_DEFAULT,          /* default computed during initialization */
        PGC_S_ENV_VAR,                          /* postmaster environment variable */
        PGC_S_FILE,                                     /* postgresql.conf */
        PGC_S_ARGV,                                     /* postmaster command line */
 
  * This is called after initial loading of postgresql.conf.  If no TimeZone
  * setting was found therein, we try to derive one from the environment.
  * Likewise for log_timezone.
+ *
+ * Note: this is also called from ProcessConfigFile, to re-establish valid
+ * GUC settings if the GUCs have been reset to default following their
+ * removal from postgresql.conf.
  */
 void
 pg_timezone_initialize(void)
                log_timezone = def_tz;
        }
 
-       /* Now, set the timezone GUC if it's not already set */
-       if (GetConfigOption("timezone", false) == NULL)
-       {
-               /* Tell GUC about the value. Will redundantly call pg_tzset() */
+       /*
+        * Now, set the timezone and log_timezone GUCs if they're still default.
+        * (This will redundantly call pg_tzset().)
+        *
+        * We choose to label these values PGC_S_ENV_VAR, rather than
+        * PGC_S_DYNAMIC_DEFAULT which would be functionally equivalent, because
+        * they came either from getenv("TZ") or from libc behavior that's
+        * determined by process environment of some kind.
+        *
+        * Note: in the case where a setting has just been removed from
+        * postgresql.conf, this code will not do what you might expect, namely
+        * call select_default_timezone() and install that value as the setting.
+        * Rather, the previously active setting --- typically the one from
+        * postgresql.conf --- will be reinstalled, relabeled as PGC_S_ENV_VAR.
+        * If we did try to install the "correct" default value, the effect would
+        * be that each postmaster child would independently run an extremely
+        * expensive search of the timezone database, bringing the database to its
+        * knees for possibly multiple seconds.  This is so unpleasant, and could
+        * so easily be triggered quite unintentionally, that it seems better to
+        * violate the principle of least astonishment.
+        */
+       if (GetConfigOptionResetString("timezone") == NULL)
                SetConfigOption("timezone", pg_get_timezone_name(session_timezone),
                                                PGC_POSTMASTER, PGC_S_ENV_VAR);
-       }
 
-       /* Likewise for log timezone */
-       if (GetConfigOption("log_timezone", false) == NULL)
-       {
-               /* Tell GUC about the value. Will redundantly call pg_tzset() */
+       if (GetConfigOptionResetString("log_timezone") == NULL)
                SetConfigOption("log_timezone", pg_get_timezone_name(log_timezone),
                                                PGC_POSTMASTER, PGC_S_ENV_VAR);
-       }
 }