Add init[db] option to pg_ctl
authorPeter Eisentraut
Thu, 10 Dec 2009 06:32:28 +0000 (06:32 +0000)
committerPeter Eisentraut
Thu, 10 Dec 2009 06:32:28 +0000 (06:32 +0000)
pg_ctl gets a new mode that runs initdb.  Adjust the documentation a bit to
not assume that initdb is the only way to run database cluster initialization.
But don't replace initdb as the canonical way.

Author: Zdenek Kotala 

doc/src/sgml/config.sgml
doc/src/sgml/manage-ag.sgml
doc/src/sgml/ref/initdb.sgml
doc/src/sgml/ref/pg_ctl-ref.sgml
doc/src/sgml/runtime.sgml
doc/src/sgml/xfunc.sgml
src/bin/pg_ctl/pg_ctl.c

index d5f55e0539bd6e9d45fd71caa183a005b518d952..1fb32c8de398d6c700881239df026d232ab680d9 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
   Server Configuration
@@ -54,9 +54,9 @@
    
     One way to set these parameters is to edit the file
     postgresql.confpostgresql.conf,
-    which is normally kept in the data directory. (initdb
-    installs a default copy there.) An example of what this file might look
-    like is:
+    which is normally kept in the data directory.  (A default copy is
+    installed there when the database cluster directory is
+    initialized.)  An example of what this file might look like is:
 
 # This is a comment
 log_connections = yes
index a2c196f1dd953208c6da15d38574afb879fd229e..8712e5c97886f3773f56fd914742c2dd39faa7b0 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
  Managing Databases
@@ -119,8 +119,8 @@ CREATE DATABASE name;
   
    A second database,
    template1,template1
-   is also created by
-   initdb.  Whenever a new database is created within the
+   is also created during database cluster initialization.  Whenever a
+   new database is created within the
    cluster, template1 is essentially cloned.
    This means that any changes you make in template1 are
    propagated to all subsequently created databases. Therefore it is
@@ -196,7 +196,8 @@ createdb -O rolename dbname
    template1, that is, only the standard objects
    predefined by your version of
    PostgreSQL.  template0
-   should never be changed after initdb.  By instructing
+   should never be changed after the database cluster has been
+   initialized.  By instructing
    CREATE DATABASE to copy template0 instead
    of template1, you can create a virgin user
    database that contains none of the site-local additions in
@@ -453,7 +454,8 @@ CREATE TABLE foo(i int);
   
 
   
-   Two tablespaces are automatically created by initdb. The
+   Two tablespaces are automatically created when the database cluster
+   is initialized.  The
    pg_global tablespace is used for shared system catalogs. The
    pg_default tablespace is the default tablespace of the
    template1 and template0 databases (and, therefore,
index 110c21eb8c5f0e277a0c130b0bc954916cc8202a..875a0e5eae2373245b1b9613857bb93f7b3ade6f 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -309,10 +309,20 @@ PostgreSQL documentation
 
  
 
+  Notes
+
+  
+   initdb can also be invoked via
+   pg_ctl initdb.
+  
+
  
   See Also
 
   
+   
    
   
  
index 638f3f18714af2d3c4ea0dd8e63cffe778905ffb..16d937363490227bca894e26a70b0345806369ab 100644 (file)
@@ -1,5 +1,5 @@
 
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
 
  
   pg_ctl
-  start, stop, or restart a PostgreSQL server
+  initialize, start, stop, or restart a PostgreSQL server
  
 
  
@@ -22,6 +22,13 @@ PostgreSQL documentation
  
   
 
+   pg_ctl
+   init[db]
+   -s
+   -D datadir
+   -o options
+   
+
    pg_ctl
    start
    -w
@@ -105,7 +112,8 @@ PostgreSQL documentation
  
   Description
   
-   pg_ctl is a utility for starting,
+   pg_ctl is a utility for initializing a
+   PostgreSQL database cluster, starting,
    stopping, or restarting the PostgreSQL
    backend server (), or displaying the
    status of a running server.  Although the server can be started
@@ -115,6 +123,15 @@ PostgreSQL documentation
    controlled shutdown.
   
 
+  
+   The  or  mode creates a
+   new
+   PostgreSQL database cluster.  A database
+   cluster is a collection of databases that are managed by a single
+   server instance.  This mode invokes the initdb
+   command.  See  for details.
+  
+
   
    In  mode, a new server is launched.  The
    server is started in the background, and standard input is attached to
@@ -263,6 +280,12 @@ PostgreSQL documentation
         option unless you are doing something unusual and get errors
         that the postgres executable was not found.
        
+
+       
+        In init mode, this option analogously
+        specifies the location of the initdb
+        executable.
+       
       
      
 
@@ -542,9 +565,10 @@ Command line was:
  
   See Also
 
-  
-   
-  
+  
+   
+   
+  
  
 
 
index 6cd5b7ce6053be7792eb08b1af8ab983f494ad2d..a68ba64dac52ce68603c1d9d8b967a190535ac12 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
 
  Server Setup and Operation
    
   
 
+  
+   Alternatively, you can run initdb via
+   the 
+   programpg_ctl like so:
+
+pg_ctl -D /usr/local/pgsql/data initdb
+
+   This may be more intuitive if you are
+   using pg_ctl for starting and stopping the
+   server (see ), so
+   that pg_ctl would be the sole command you use
+   for managing the database server instance.
+  
+
   
    initdb will attempt to create the directory you
    specify if it does not already exist. It is likely that it will not
index b0ef51c7df6dd92c0d2f976b8249f7e2be92593f..d8caa9893d6908fe202f32bb3465ea29744263f9 100644 (file)
@@ -1,4 +1,4 @@
-
+
 
  
   User-Defined Functions
@@ -1353,7 +1353,8 @@ CREATE FUNCTION test(int, int) RETURNS int
 
    
     Normally, all internal functions present in the
-    server are declared during the initialization of the database cluster (initdb),
+    server are declared during the initialization of the database cluster
+    (see ),
     but a user could use CREATE FUNCTION
     to create additional alias names for an internal function.
     Internal functions are declared in CREATE FUNCTION
index 1942db9f13ae8d677adc643cd025efd03ea29df1..1e874a700f711109b395533c2bb63049a845e9ba 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.115 2009/11/14 15:39:36 mha Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_ctl/pg_ctl.c,v 1.116 2009/12/10 06:32:28 petere Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -57,6 +57,7 @@ typedef enum
 typedef enum
 {
    NO_COMMAND = 0,
+   INIT_COMMAND,
    START_COMMAND,
    STOP_COMMAND,
    RESTART_COMMAND,
@@ -82,7 +83,7 @@ static char *pgdata_opt = NULL;
 static char *post_opts = NULL;
 static const char *progname;
 static char *log_file = NULL;
-static char *postgres_path = NULL;
+static char *exec_path = NULL;
 static char *register_servicename = "PostgreSQL";      /* FIXME: + version ID? */
 static char *register_username = NULL;
 static char *register_password = NULL;
@@ -100,6 +101,7 @@ static void do_advice(void);
 static void do_help(void);
 static void set_mode(char *modeopt);
 static void set_sig(char *signame);
+static void do_init(void);
 static void do_start(void);
 static void do_stop(void);
 static void do_restart(void);
@@ -358,11 +360,11 @@ start_postmaster(void)
     */
    if (log_file != NULL)
        snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1 &" SYSTEMQUOTE,
-                postgres_path, pgdata_opt, post_opts,
+                exec_path, pgdata_opt, post_opts,
                 DEVNULL, log_file);
    else
        snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1 &" SYSTEMQUOTE,
-                postgres_path, pgdata_opt, post_opts, DEVNULL);
+                exec_path, pgdata_opt, post_opts, DEVNULL);
 
    return system(cmd);
 #else                          /* WIN32 */
@@ -376,10 +378,10 @@ start_postmaster(void)
 
    if (log_file != NULL)
        snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" >> \"%s\" 2>&1" SYSTEMQUOTE,
-                postgres_path, pgdata_opt, post_opts, DEVNULL, log_file);
+                exec_path, pgdata_opt, post_opts, DEVNULL, log_file);
    else
        snprintf(cmd, MAXPGPATH, "CMD /C " SYSTEMQUOTE "\"%s\" %s%s < \"%s\" 2>&1" SYSTEMQUOTE,
-                postgres_path, pgdata_opt, post_opts, DEVNULL);
+                exec_path, pgdata_opt, post_opts, DEVNULL);
 
    if (!CreateRestrictedProcess(cmd, &pi, false))
        return GetLastError();
@@ -607,13 +609,70 @@ read_post_opts(void)
                                         * name */
                    post_opts = arg1 + 1;       /* point past whitespace */
                }
-               if (postgres_path == NULL)
-                   postgres_path = optline;
+               if (exec_path == NULL)
+                   exec_path = optline;
            }
        }
    }
 }
 
+static char *
+find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
+{
+   int         ret;
+   char       *found_path;
+
+   found_path = pg_malloc(MAXPGPATH);
+
+   if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
+   {
+       char        full_path[MAXPGPATH];
+
+       if (find_my_exec(argv0, full_path) < 0)
+           strlcpy(full_path, progname, sizeof(full_path));
+
+       if (ret == -1)
+           write_stderr(_("The program \"%s\" is needed by %s "
+                          "but was not found in the\n"
+                          "same directory as \"%s\".\n"
+                          "Check your installation.\n"),
+                        target, progname, full_path);
+       else
+           write_stderr(_("The program \"%s\" was found by \"%s\"\n"
+                          "but was not the same version as %s.\n"
+                          "Check your installation.\n"),
+                        target, full_path, progname);
+       exit(1);
+   }
+
+   return found_path;
+}
+
+static void
+do_init(void)
+{
+   char cmd[MAXPGPATH];
+
+   if (exec_path == NULL)
+       exec_path = find_other_exec_or_die(argv0, "initdb", "initdb (PostgreSQL) " PG_VERSION "\n");
+
+   if (post_opts == NULL)
+       post_opts = "";
+
+   if (!silent_mode)
+       snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s" SYSTEMQUOTE,
+                exec_path, pgdata_opt, post_opts);
+   else
+       snprintf(cmd, MAXPGPATH, SYSTEMQUOTE "\"%s\" %s%s > \"%s\"" SYSTEMQUOTE,
+                exec_path, pgdata_opt, post_opts, DEVNULL);
+   
+   if (system(cmd) != 0)
+   {
+       write_stderr(_("%s: database system initialization failed\n"), progname);
+       exit(1);
+   }
+}
+
 static void
 do_start(void)
 {
@@ -636,36 +695,8 @@ do_start(void)
    if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
        pgdata_opt = "";
 
-   if (postgres_path == NULL)
-   {
-       char       *postmaster_path;
-       int         ret;
-
-       postmaster_path = pg_malloc(MAXPGPATH);
-
-       if ((ret = find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
-                                  postmaster_path)) < 0)
-       {
-           char        full_path[MAXPGPATH];
-
-           if (find_my_exec(argv0, full_path) < 0)
-               strlcpy(full_path, progname, sizeof(full_path));
-
-           if (ret == -1)
-               write_stderr(_("The program \"postgres\" is needed by %s "
-                              "but was not found in the\n"
-                              "same directory as \"%s\".\n"
-                              "Check your installation.\n"),
-                            progname, full_path);
-           else
-               write_stderr(_("The program \"postgres\" was found by \"%s\"\n"
-                              "but was not the same version as %s.\n"
-                              "Check your installation.\n"),
-                            full_path, progname);
-           exit(1);
-       }
-       postgres_path = postmaster_path;
-   }
+   if (exec_path == NULL)
+       exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
 
 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
    if (allow_core_files)
@@ -1536,6 +1567,7 @@ do_help(void)
    printf(_("%s is a utility to start, stop, restart, reload configuration files,\n"
             "report the status of a PostgreSQL server, or signal a PostgreSQL process.\n\n"), progname);
    printf(_("Usage:\n"));
+   printf(_("  %s init[db]               [-D DATADIR] [-s] [-o \"OPTIONS\"]\n"), progname);
    printf(_("  %s start   [-w] [-t SECS] [-D DATADIR] [-s] [-l FILENAME] [-o \"OPTIONS\"]\n"), progname);
    printf(_("  %s stop    [-W] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"), progname);
    printf(_("  %s restart [-w] [-t SECS] [-D DATADIR] [-s] [-m SHUTDOWN-MODE]\n"
@@ -1568,7 +1600,7 @@ do_help(void)
 #endif
    printf(_("  -l, --log FILENAME     write (or append) server log to FILENAME\n"));
    printf(_("  -o OPTIONS             command line options to pass to postgres\n"
-            "                         (PostgreSQL server executable)\n"));
+            "                         (PostgreSQL server executable) or initdb\n"));
    printf(_("  -p PATH-TO-POSTGRES    normally not necessary\n"));
    printf(_("\nOptions for stop or restart:\n"));
    printf(_("  -m SHUTDOWN-MODE   can be \"smart\", \"fast\", or \"immediate\"\n"));
@@ -1770,7 +1802,7 @@ main(int argc, char **argv)
                    post_opts = xstrdup(optarg);
                    break;
                case 'p':
-                   postgres_path = xstrdup(optarg);
+                   exec_path = xstrdup(optarg);
                    break;
                case 'P':
                    register_password = xstrdup(optarg);
@@ -1825,7 +1857,10 @@ main(int argc, char **argv)
                exit(1);
            }
 
-           if (strcmp(argv[optind], "start") == 0)
+           if (strcmp(argv[optind], "init") == 0
+               || strcmp(argv[optind], "initdb") == 0)
+               ctl_command = INIT_COMMAND;
+           else if (strcmp(argv[optind], "start") == 0)
                ctl_command = START_COMMAND;
            else if (strcmp(argv[optind], "stop") == 0)
                ctl_command = STOP_COMMAND;
@@ -1922,6 +1957,9 @@ main(int argc, char **argv)
 
    switch (ctl_command)
    {
+       case INIT_COMMAND:
+           do_init();
+           break;
        case STATUS_COMMAND:
            do_status();
            break;