*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
***************
*** 1505,1514 **** SET ENABLE_SEQSCAN TO OFF;
        </indexterm>
        <listitem>
         <para>
!         Specifies whether transaction commit will wait for WAL records
!         to be written to disk before the command returns a <quote>success</>
!         indication to the client.  The default, and safe, setting is
!         <literal>on</>.  When <literal>off</>, there can be a delay between
          when success is reported to the client and when the transaction is
          really guaranteed to be safe against a server crash.  (The maximum
          delay is three times <xref linkend="guc-wal-writer-delay">.)  Unlike
--- 1505,1527 ----
        </indexterm>
        <listitem>
         <para>
!         Specifies the synchronization level for transaction commit, defining
!         what actions must take place before the command returns a <quote>success</>
!         indication to the client.  Valid values are <literal>on</>, <literal>off</>,
!         and <literal>local</>.  The default, and safe, value is <literal>on</>,
!         which waits for the transaction's WAL records to be flushed to disk and
!         replicated to the standby server.  When <literal>on</>, there will be a
!         delay while the client waits for confirmation of successful replication.
!         That delay will increase depending upon the physical distance and network
!         activity between primary and standby.  The commit wait will last until
!         a reply from the current synchronous standby indicates it has written
!         the commit record of the transaction to durable storage.
!         <literal>local</> waits for local flush to disk, but not synchronous
!         replication.  The synchronization level of <literal>on</> is the same as
!         that of <literal>local</> if <xref linkend="guc-synchronous-standby-names">
!         is empty or <xref linkend="guc-max-wal-senders"> is zero.  <literal>off</>
!         waits for neither local flush to disk nor synchronous replication.
!         When <literal>off</>, there can be a delay between
          when success is reported to the client and when the transaction is
          really guaranteed to be safe against a server crash.  (The maximum
          delay is three times <xref linkend="guc-wal-writer-delay">.)  Unlike
***************
*** 2057,2095 **** SET ENABLE_SEQSCAN TO OFF;
       </para>
  
       <variablelist>
-      <varlistentry id="guc-synchronous-replication" xreflabel="synchronous_replication">
-       <term><varname>synchronous_replication</varname> (<type>boolean</type>)</term>
-       <indexterm>
-        <primary><varname>synchronous_replication</> configuration parameter</primary>
-       </indexterm>
-       <listitem>
-        <para>
-         Specifies whether transaction commit will wait for WAL records
-         to be replicated before the command returns a <quote>success</>
-         indication to the client.  The default setting is <literal>off</>.
-         When <literal>on</>, there will be a delay while the client waits
-         for confirmation of successful replication. That delay will
-         increase depending upon the physical distance and network activity
-         between primary and standby. The commit wait will last until a
-         reply from the current synchronous standby indicates it has written
-         the commit record of the transaction to durable storage.  This
-         parameter has no effect if
-         <xref linkend="guc-synchronous-standby-names"> is empty or
-         <xref linkend="guc-max-wal-senders"> is zero.
-        </para>
-        <para>
-         This parameter can be changed at any time; the
-         behavior for any one transaction is determined by the setting in
-         effect when it commits.  It is therefore possible, and useful, to have
-         some transactions replicate synchronously and others asynchronously.
-         For example, to make a single multistatement transaction commit
-         asynchronously when the default is synchronous replication, issue
-         <command>SET LOCAL synchronous_replication TO OFF</> within the
-         transaction.
-        </para>
-       </listitem>
-      </varlistentry>
- 
       <varlistentry id="guc-synchronous-standby-names" xreflabel="synchronous_standby_names">
        <term><varname>synchronous_standby_names</varname> (<type>string</type>)</term>
        <indexterm>
--- 2070,2075 ----
***************
*** 2124,2130 **** SET ENABLE_SEQSCAN TO OFF;
          If a standby is removed from the list of servers then it will stop
          being the synchronous standby, allowing another to take its place.
          If the list is empty, synchronous replication will not be
!         possible, whatever the setting of <varname>synchronous_replication</>.
          Standbys may also be added to the list without restarting the server.
         </para>
        </listitem>
--- 2104,2110 ----
          If a standby is removed from the list of servers then it will stop
          being the synchronous standby, allowing another to take its place.
          If the list is empty, synchronous replication will not be
!         possible, whatever the setting of <varname>synchronous_commit</>.
          Standbys may also be added to the list without restarting the server.
         </para>
        </listitem>
*** a/doc/src/sgml/high-availability.sgml
--- b/doc/src/sgml/high-availability.sgml
***************
*** 933,945 **** primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
      synchronous replication easily just by setting this on the primary:
  
  <programlisting>
! synchronous_replication = on
  </programlisting>
  
!     When <varname>synchronous_replication</> is set, a commit will wait
!     for confirmation that the standby has received the commit record,
!     even if that takes a very long time.
!     <varname>synchronous_replication</> can be set by individual
      users, so can be configured in the configuration file, for particular
      users or databases, or dynamically by applications.
     </para>
--- 933,945 ----
      synchronous replication easily just by setting this on the primary:
  
  <programlisting>
! synchronous_commit = on
  </programlisting>
  
!     When <varname>synchronous_commit</> is set to <literal>on</>,
!     a commit will wait for confirmation that the standby has received
!     the commit record, even if that takes a very long time.
!     <varname>synchronous_commit</> can be set by individual
      users, so can be configured in the configuration file, for particular
      users or databases, or dynamically by applications.
     </para>
***************
*** 964,977 **** synchronous_replication = on
      transferred to standby servers.
     </para>
  
-    <para>
-     Note also that <varname>synchronous_commit</> is used when the user
-     specifies <varname>synchronous_replication</>, overriding even an
-     explicit setting of <varname>synchronous_commit</> to <literal>off</>.
-     This is because we must write WAL to disk on primary before we replicate
-     to ensure the standby never gets ahead of the primary.
-    </para>
- 
     </sect3>
  
     <sect3 id="synchronous-replication-performance">
--- 964,969 ----
***************
*** 1019,1027 **** synchronous_replication = on
      <title>Planning for High Availability</title>
  
     <para>
!     Commits made when synchronous_replication is set will wait until
!     the sync standby responds. The response may never occur if the last,
!     or only, standby should crash.
     </para>
  
     <para>
--- 1011,1019 ----
      <title>Planning for High Availability</title>
  
     <para>
!     Commits made when <varname>synchronous_commit</> is set to <literal>on</>
!     will wait until the sync standby responds. The response may never occur
!     if the last, or only, standby should crash.
     </para>
  
     <para>
***************
*** 1073,1080 **** synchronous_replication = on
      If you need to re-create a standby server while transactions are
      waiting, make sure that the commands to run pg_start_backup() and
      pg_stop_backup() are run in a session with
!     synchronous_replication = off, otherwise those requests will wait
!     forever for the standby to appear.
     </para>
  
     </sect3>
--- 1065,1072 ----
      If you need to re-create a standby server while transactions are
      waiting, make sure that the commands to run pg_start_backup() and
      pg_stop_backup() are run in a session with
!     <varname>synchronous_commit</> = <literal>off</>, otherwise those
!     requests will wait forever for the standby to appear.
     </para>
  
     </sect3>
*** a/doc/src/sgml/release-9.1.sgml
--- b/doc/src/sgml/release-9.1.sgml
***************
*** 656,662 ****
         <link linkend="guc-synchronous-standby-names"><varname>synchronous_standby_names</varname></link>
         setting.  Synchronous replication can be enabled or disabled on a
         per-transaction basis using the
!        <link linkend="guc-synchronous-replication"><varname>synchronous_replication</></link>
         setting.  This allows the primary to wait for a standby to write the
         transaction information to disk before acknowledging the commit.
        </para>
--- 656,662 ----
         <link linkend="guc-synchronous-standby-names"><varname>synchronous_standby_names</varname></link>
         setting.  Synchronous replication can be enabled or disabled on a
         per-transaction basis using the
!        <link linkend="guc-synchronous-commit"><varname>synchronous_commit</></link>
         setting.  This allows the primary to wait for a standby to write the
         transaction information to disk before acknowledging the commit.
        </para>
*** a/src/backend/access/transam/xact.c
--- b/src/backend/access/transam/xact.c
***************
*** 68,74 **** bool		XactReadOnly;
  bool		DefaultXactDeferrable = false;
  bool		XactDeferrable;
  
! bool		XactSyncCommit = true;
  
  int			CommitDelay = 0;	/* precommit delay in microseconds */
  int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
--- 68,74 ----
  bool		DefaultXactDeferrable = false;
  bool		XactDeferrable;
  
! int			XactSyncCommit = SYNCHRONOUS_COMMIT_ON;
  
  int			CommitDelay = 0;	/* precommit delay in microseconds */
  int			CommitSiblings = 5; /* # concurrent xacts needed to sleep */
***************
*** 1056,1062 **** RecordTransactionCommit(void)
  	 * if all to-be-deleted tables are temporary though, since they are lost
  	 * anyway if we crash.)
  	 */
! 	if ((wrote_xlog && XactSyncCommit) || forceSyncCommit || nrels > 0 || SyncRepRequested())
  	{
  		/*
  		 * Synchronous commit case:
--- 1056,1063 ----
  	 * if all to-be-deleted tables are temporary though, since they are lost
  	 * anyway if we crash.)
  	 */
! 	if ((wrote_xlog && XactSyncCommit >= SYNCHRONOUS_COMMIT_ON) ||
! 		forceSyncCommit || nrels > 0)
  	{
  		/*
  		 * Synchronous commit case:
*** a/src/backend/postmaster/autovacuum.c
--- b/src/backend/postmaster/autovacuum.c
***************
*** 1531,1537 **** AutoVacWorkerMain(int argc, char *argv[])
  	 * if we are waiting for standbys to connect. This is important to
  	 * ensure we aren't blocked from performing anti-wraparound tasks.
  	 */
! 	SetConfigOption("synchronous_replication", "off", PGC_SUSET, PGC_S_OVERRIDE);
  
  	/*
  	 * Get the info about the database we're going to work on.
--- 1531,1538 ----
  	 * if we are waiting for standbys to connect. This is important to
  	 * ensure we aren't blocked from performing anti-wraparound tasks.
  	 */
! 	if (XactSyncCommit == SYNCHRONOUS_COMMIT_ON)
! 		SetConfigOption("synchronous_commit", "local", PGC_SUSET, PGC_S_OVERRIDE);
  
  	/*
  	 * Get the info about the database we're going to work on.
*** a/src/backend/replication/syncrep.c
--- b/src/backend/replication/syncrep.c
***************
*** 63,69 ****
  #include "utils/ps_status.h"
  
  /* User-settable parameters for sync rep */
- bool	synchronous_replication = false;		/* Only set in user backends */
  char 	*SyncRepStandbyNames;
  
  #define SyncStandbysDefined() \
--- 63,68 ----
*** a/src/backend/utils/misc/guc.c
--- b/src/backend/utils/misc/guc.c
***************
*** 351,356 **** static const struct config_enum_entry constraint_exclusion_options[] = {
--- 351,373 ----
  };
  
  /*
+  * Although only "on", "off", and "local" are documented, we
+  * accept all the likely variants of "on" and "off".
+  */
+ static const struct config_enum_entry synchronous_commit_options[] = {
+ 	{"local", SYNCHRONOUS_COMMIT_LOCAL, false},
+ 	{"on", SYNCHRONOUS_COMMIT_ON, false},
+ 	{"off", SYNCHRONOUS_COMMIT_OFF, false},
+ 	{"true", SYNCHRONOUS_COMMIT_ON, true},
+ 	{"false", SYNCHRONOUS_COMMIT_OFF, true},
+ 	{"yes", SYNCHRONOUS_COMMIT_ON, true},
+ 	{"no", SYNCHRONOUS_COMMIT_OFF, true},
+ 	{"1", SYNCHRONOUS_COMMIT_ON, true},
+ 	{"0", SYNCHRONOUS_COMMIT_OFF, true},
+ 	{NULL, 0, false}
+ };
+ 
+ /*
   * Options for enum values stored in other modules
   */
  extern const struct config_enum_entry wal_level_options[];
***************
*** 747,768 **** static struct config_bool ConfigureNamesBool[] =
  		true, NULL, NULL
  	},
  	{
- 		{"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
- 			gettext_noop("Sets immediate fsync at commit."),
- 			NULL
- 		},
- 		&XactSyncCommit,
- 		true, NULL, NULL
- 	},
- 	{
- 		{"synchronous_replication", PGC_USERSET, WAL_REPLICATION,
- 			gettext_noop("Requests synchronous replication."),
- 			NULL
- 		},
- 		&synchronous_replication,
- 		false, NULL, NULL
- 	},
- 	{
  		{"zero_damaged_pages", PGC_SUSET, DEVELOPER_OPTIONS,
  			gettext_noop("Continues processing past damaged page headers."),
  			gettext_noop("Detection of a damaged page header normally causes PostgreSQL to "
--- 764,769 ----
***************
*** 2909,2914 **** static struct config_enum ConfigureNamesEnum[] =
--- 2910,2925 ----
  	},
  
  	{
+ 		{"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
+ 			gettext_noop("Sets the current transaction's synchronization level."),
+ 			NULL
+ 		},
+ 		&XactSyncCommit,
+ 		SYNCHRONOUS_COMMIT_ON, synchronous_commit_options,
+ 		NULL, NULL
+ 	},
+ 
+ 	{
  		{"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS,
  			gettext_noop("Enables logging of recovery-related debugging information."),
  			gettext_noop("Each level includes all the levels that follow it. The later"
*** a/src/backend/utils/misc/postgresql.conf.sample
--- b/src/backend/utils/misc/postgresql.conf.sample
***************
*** 153,159 ****
  #wal_level = minimal			# minimal, archive, or hot_standby
  					# (change requires restart)
  #fsync = on				# turns forced synchronization on or off
! #synchronous_commit = on		# immediate fsync at commit
  #wal_sync_method = fsync		# the default is the first option
  					# supported by the operating system:
  					#   open_datasync
--- 153,159 ----
  #wal_level = minimal			# minimal, archive, or hot_standby
  					# (change requires restart)
  #fsync = on				# turns forced synchronization on or off
! #synchronous_commit = on		# synchronization level; on, off, or local
  #wal_sync_method = fsync		# the default is the first option
  					# supported by the operating system:
  					#   open_datasync
***************
*** 184,193 ****
  #archive_timeout = 0		# force a logfile segment switch after this
  				# number of seconds; 0 disables
  
- # - Replication - User Settings
- 
- #synchronous_replication = off		# does commit wait for reply from standby
- 
  # - Streaming Replication - Server Settings
  
  #synchronous_standby_names = ''	# standby servers that provide sync rep
--- 184,189 ----
*** a/src/include/access/xact.h
--- b/src/include/access/xact.h
***************
*** 52,59 **** extern bool XactReadOnly;
  extern bool DefaultXactDeferrable;
  extern bool XactDeferrable;
  
! /* Asynchronous commits */
! extern bool XactSyncCommit;
  
  /* Kluge for 2PC support */
  extern bool MyXactAccessedTempRel;
--- 52,66 ----
  extern bool DefaultXactDeferrable;
  extern bool XactDeferrable;
  
! /* Synchronous commit level */
! extern int XactSyncCommit;
! 
! typedef enum
! {
! 	SYNCHRONOUS_COMMIT_OFF,		/* asynchronous commit */
! 	SYNCHRONOUS_COMMIT_ON,		/* wait for local flush and sync rep */
! 	SYNCHRONOUS_COMMIT_LOCAL	/* wait for only local flush */
! } SyncCommitLevel;
  
  /* Kluge for 2PC support */
  extern bool MyXactAccessedTempRel;
*** a/src/include/replication/syncrep.h
--- b/src/include/replication/syncrep.h
***************
*** 20,26 ****
  #include "utils/guc.h"
  
  #define SyncRepRequested() \
! 	(synchronous_replication && max_wal_senders > 0)
  
  /* syncRepState */
  #define SYNC_REP_NOT_WAITING		0
--- 20,26 ----
  #include "utils/guc.h"
  
  #define SyncRepRequested() \
! 	(max_wal_senders > 0 && XactSyncCommit == SYNCHRONOUS_COMMIT_ON)
  
  /* syncRepState */
  #define SYNC_REP_NOT_WAITING		0
***************
*** 28,34 ****
  #define SYNC_REP_WAIT_COMPLETE		2
  
  /* user-settable parameters for synchronous replication */
- extern bool synchronous_replication;
  extern char *SyncRepStandbyNames;
  
  /* called by user backend */
--- 28,33 ----
