diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index d5f55e0539bd6e9d45fd71caa183a005b518d952..1fb32c8de398d6c700881239df026d232ab680d9 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.235 2009/11/28 23:38:06 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.236 2009/12/10 06:32:27 petere Exp $ -->
 
 <chapter Id="runtime-config">
   <title>Server Configuration</title>
@@ -54,9 +54,9 @@
    <para>
     One way to set these parameters is to edit the file
     <filename>postgresql.conf</><indexterm><primary>postgresql.conf</></>,
-    which is normally kept in the data directory. (<application>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:
 <programlisting>
 # This is a comment
 log_connections = yes
diff --git a/doc/src/sgml/manage-ag.sgml b/doc/src/sgml/manage-ag.sgml
index a2c196f1dd953208c6da15d38574afb879fd229e..8712e5c97886f3773f56fd914742c2dd39faa7b0 100644
--- a/doc/src/sgml/manage-ag.sgml
+++ b/doc/src/sgml/manage-ag.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.58 2009/05/06 16:15:20 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/manage-ag.sgml,v 2.59 2009/12/10 06:32:27 petere Exp $ -->
 
 <chapter id="managing-databases">
  <title>Managing Databases</title>
@@ -119,8 +119,8 @@ CREATE DATABASE <replaceable>name</>;
   <para>
    A second database,
    <literal>template1</literal>,<indexterm><primary>template1</></>
-   is also created by
-   <command>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, <literal>template1</literal> is essentially cloned.
    This means that any changes you make in <literal>template1</> are
    propagated to all subsequently created databases. Therefore it is
@@ -196,7 +196,8 @@ createdb -O <replaceable>rolename</> <replaceable>dbname</>
    <literal>template1</>, that is, only the standard objects
    predefined by your version of
    <productname>PostgreSQL</productname>.  <literal>template0</>
-   should never be changed after <command>initdb</>.  By instructing
+   should never be changed after the database cluster has been
+   initialized.  By instructing
    <command>CREATE DATABASE</> to copy <literal>template0</> instead
    of <literal>template1</>, you can create a <quote>virgin</> user
    database that contains none of the site-local additions in
@@ -453,7 +454,8 @@ CREATE TABLE foo(i int);
   </para>
 
   <para>
-   Two tablespaces are automatically created by <literal>initdb</>. The
+   Two tablespaces are automatically created when the database cluster
+   is initialized.  The
    <literal>pg_global</> tablespace is used for shared system catalogs. The
    <literal>pg_default</> tablespace is the default tablespace of the
    <literal>template1</> and <literal>template0</> databases (and, therefore,
diff --git a/doc/src/sgml/ref/initdb.sgml b/doc/src/sgml/ref/initdb.sgml
index 110c21eb8c5f0e277a0c130b0bc954916cc8202a..875a0e5eae2373245b1b9613857bb93f7b3ade6f 100644
--- a/doc/src/sgml/ref/initdb.sgml
+++ b/doc/src/sgml/ref/initdb.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/initdb.sgml,v 1.44 2008/09/23 09:20:34 heikki Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/initdb.sgml,v 1.45 2009/12/10 06:32:28 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -309,10 +309,20 @@ PostgreSQL documentation
 
  </refsect1>
 
+ <refsect1>
+  <title>Notes</title>
+
+  <para>
+   <command>initdb</command> can also be invoked via
+   <command>pg_ctl initdb</command>.
+  </para>
+ </refsect1>
+
  <refsect1>
   <title>See Also</title>
 
   <simplelist type="inline">
+   <member><xref linkend="app-pg-ctl"></member>
    <member><xref linkend="app-postgres"></member>
   </simplelist>
  </refsect1>
diff --git a/doc/src/sgml/ref/pg_ctl-ref.sgml b/doc/src/sgml/ref/pg_ctl-ref.sgml
index 638f3f18714af2d3c4ea0dd8e63cffe778905ffb..16d937363490227bca894e26a70b0345806369ab 100644
--- a/doc/src/sgml/ref/pg_ctl-ref.sgml
+++ b/doc/src/sgml/ref/pg_ctl-ref.sgml
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.46 2008/06/26 01:12:19 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/pg_ctl-ref.sgml,v 1.47 2009/12/10 06:32:28 petere Exp $
 PostgreSQL documentation
 -->
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>pg_ctl</refname>
-  <refpurpose>start, stop, or restart a <productname>PostgreSQL</productname> server</refpurpose>
+  <refpurpose>initialize, start, stop, or restart a <productname>PostgreSQL</productname> server</refpurpose>
  </refnamediv>
 
  <indexterm zone="app-pg-ctl">
@@ -22,6 +22,13 @@ PostgreSQL documentation
  <refsynopsisdiv>
   <cmdsynopsis>
 
+   <command>pg_ctl</command>
+   <arg choice="plain">init[db]</arg>
+   <arg>-s</arg>
+   <arg>-D <replaceable>datadir</replaceable></arg>
+   <arg>-o <replaceable>options</replaceable></arg>
+   <sbr>
+
    <command>pg_ctl</command>
    <arg choice="plain">start</arg>
    <arg>-w</arg>
@@ -105,7 +112,8 @@ PostgreSQL documentation
  <refsect1 id="app-pg-ctl-description">
   <title>Description</title>
   <para>
-   <application>pg_ctl</application> is a utility for starting,
+   <application>pg_ctl</application> is a utility for initializing a
+   <productname>PostgreSQL</productname> database cluster, starting,
    stopping, or restarting the <productname>PostgreSQL</productname>
    backend server (<xref linkend="app-postgres">), or displaying the
    status of a running server.  Although the server can be started
@@ -115,6 +123,15 @@ PostgreSQL documentation
    controlled shutdown.
   </para>
 
+  <para>
+   The <option>init</option> or <option>initdb</option> mode creates a
+   new
+   <productname>PostgreSQL</productname> database cluster.  A database
+   cluster is a collection of databases that are managed by a single
+   server instance.  This mode invokes the <command>initdb</command>
+   command.  See <xref linkend="app-initdb"> for details.
+  </para>
+
   <para>
    In <option>start</option> 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 <filename>postgres</filename> executable was not found.
        </para>
+
+       <para>
+        In <literal>init</literal> mode, this option analogously
+        specifies the location of the <filename>initdb</filename>
+        executable.
+       </para>
       </listitem>
      </varlistentry>
 
@@ -542,9 +565,10 @@ Command line was:
  <refsect1>
   <title>See Also</title>
 
-  <para>
-   <xref linkend="app-postgres">
-  </para>
+  <simplelist type="inline">
+   <member><xref linkend="app-initdb"></member>
+   <member><xref linkend="app-postgres"></member>
+  </simplelist>
  </refsect1>
 
 </refentry>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 6cd5b7ce6053be7792eb08b1af8ab983f494ad2d..a68ba64dac52ce68603c1d9d8b967a190535ac12 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.428 2009/04/27 16:27:36 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.429 2009/12/10 06:32:28 petere Exp $ -->
 
 <chapter Id="runtime">
  <title>Server Setup and Operation</title>
@@ -93,6 +93,20 @@
    </para>
   </tip>
 
+  <para>
+   Alternatively, you can run <command>initdb</command> via
+   the <xref linkend="app-pg-ctl">
+   program<indexterm><primary>pg_ctl</></> like so:
+<screen>
+<prompt>$</> <userinput>pg_ctl -D /usr/local/pgsql/data initdb</userinput>
+</screen>
+   This may be more intuitive if you are
+   using <command>pg_ctl</command> for starting and stopping the
+   server (see <xref linkend="server-start">), so
+   that <command>pg_ctl</command> would be the sole command you use
+   for managing the database server instance.
+  </para>
+
   <para>
    <command>initdb</command> will attempt to create the directory you
    specify if it does not already exist. It is likely that it will not
diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml
index b0ef51c7df6dd92c0d2f976b8249f7e2be92593f..d8caa9893d6908fe202f32bb3465ea29744263f9 100644
--- a/doc/src/sgml/xfunc.sgml
+++ b/doc/src/sgml/xfunc.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.142 2009/11/30 15:49:35 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.143 2009/12/10 06:32:28 petere Exp $ -->
 
  <sect1 id="xfunc">
   <title>User-Defined Functions</title>
@@ -1353,7 +1353,8 @@ CREATE FUNCTION test(int, int) RETURNS int
 
    <para>
     Normally, all internal functions present in the
-    server are declared during the initialization of the database cluster (<command>initdb</command>),
+    server are declared during the initialization of the database cluster
+    (see <xref linkend="creating-cluster">),
     but a user could use <command>CREATE FUNCTION</command>
     to create additional alias names for an internal function.
     Internal functions are declared in <command>CREATE FUNCTION</command>
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 1942db9f13ae8d677adc643cd025efd03ea29df1..1e874a700f711109b395533c2bb63049a845e9ba 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -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;