]> granicus.if.org Git - postgresql/commitdiff
Merge synchronous_replication setting into synchronous_commit.
authorRobert Haas <rhaas@postgresql.org>
Mon, 4 Apr 2011 20:13:01 +0000 (16:13 -0400)
committerRobert Haas <rhaas@postgresql.org>
Mon, 4 Apr 2011 20:25:52 +0000 (16:25 -0400)
This means one less thing to configure when setting up synchronous
replication, and also avoids some ambiguity around what the behavior
should be when the settings of these variables conflict.

Fujii Masao, with additional hacking by me.

doc/src/sgml/config.sgml
doc/src/sgml/high-availability.sgml
doc/src/sgml/release-9.1.sgml
src/backend/access/transam/xact.c
src/backend/postmaster/autovacuum.c
src/backend/replication/syncrep.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/access/xact.h
src/include/replication/syncrep.h

index 8a6d7b7c5fdbf430c64d7d0f90ee65e8b337f6b6..bb5527c06242a1241e33f671cda90c95bc9fae46 100644 (file)
@@ -1507,8 +1507,9 @@ SET ENABLE_SEQSCAN TO OFF;
        <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
+        indication to the client.  Valid values are <literal>on</>,
+        <literal>local</>, and <literal>off</>.  The default, and safe, value
+        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
@@ -1522,6 +1523,19 @@ SET ENABLE_SEQSCAN TO OFF;
         exact certainty about the durability of a transaction.  For more
         discussion see <xref linkend="wal-async-commit">.
        </para>
+       <para>
+        If <xref linkend="guc-synchronous-standby-names"> is set, this
+        parameter also controls whether or not transaction commit will wait
+        for the transaction's WAL records to be flushed to disk and replicated
+        to the standby server.  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.  If synchronous
+        replication is in use, it will normally be sensible either to wait
+        both for WAL records to reach both the local and remote disks, or
+        to allow the transaction to commit asynchronously.  However, the
+        special value <literal>local</> is available for transactions that
+        wish to wait for local flush to disk, but not synchronous replication.
+       </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
@@ -2057,39 +2071,6 @@ 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>
@@ -2098,7 +2079,7 @@ SET ENABLE_SEQSCAN TO OFF;
       <listitem>
        <para>
         Specifies a priority ordered list of standby names that can offer
-        synchronous replication.  At any one time there will be just one
+        synchronous replication.  At any one time there will be at most one
         synchronous standby that will wake sleeping users following commit.
         The synchronous standby will be the first named standby that is
         both currently connected and streaming in real-time to the standby
@@ -2114,18 +2095,17 @@ SET ENABLE_SEQSCAN TO OFF;
         not enforced for uniqueness. In case of duplicates one of the standbys
         will be chosen to be the synchronous standby, though exactly which
         one is indeterminate.
-       </para>
-       <para>
-        No value is set by default.
         The special entry <literal>*</> matches any application_name, including
         the default application name of <literal>walreceiver</>.
        </para>
        <para>
-        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.
+        If no synchronous standby names are specified, then synchronous
+        replication is not enabled and transaction commit will never wait for
+        replication.  This is the default configuration.  Even when
+        synchronous replication is enabled, individual transactions can be
+        configured not to wait for replication by setting the
+        <xref linkend="guc-synchronous-commit"> parameter to
+        <literal>local</> or <literal>off</>.
        </para>
       </listitem>
      </varlistentry>
index f6308dd7849008d3ed8c92043837e0f0e564cf28..6dbc6bcd721373ae8a3061b1af2926233219d4d2 100644 (file)
@@ -929,19 +929,18 @@ primary_conninfo = 'host=192.168.1.50 port=5432 user=foo password=foopass'
     <title>Basic Configuration</title>
 
    <para>
-    All parameters have useful default values, so we can enable
-    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
+    Once streaming replication has been configured, configuring synchronous
+    replication requires only one additional configuration step:
+    <xref linkend="guc-synchronous-standby-names"> must be set to
+    a non-empty value.  <varname>synchronous_commit</> must also be set to
+    <literal>on</>, but since this is the default value, typically no change is
+    required.  This configuration will cause each commit to wait for
+    confirmation that the standby has written the commit record to durable
+    storage, 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.
+    users or databases, or dynamically by applications, in order to control
+    the durability guarantee on a per-transaction basis.
    </para>
 
    <para>
@@ -959,17 +958,10 @@ synchronous_replication = on
    </para>
 
    <para>
-    Users will stop waiting if a fast shutdown is requested, though the
-    server does not fully shutdown until all outstanding WAL records are
-    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.
+    Users will stop waiting if a fast shutdown is requested.  However, as
+    when using asynchronous replication, the server will does not fully
+    shutdown until all outstanding WAL records are transferred to the currently
+    connected standby servers.
    </para>
 
    </sect3>
@@ -1019,9 +1011,9 @@ 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.
+    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,8 +1065,8 @@ 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.
+    <varname>synchronous_commit</> = <literal>off</>, otherwise those
+    requests will wait forever for the standby to appear.
    </para>
 
    </sect3>
index 5671682b3f1ecf9e50c345fdc5c8d3070fae34be..5152bb3fe4021d40bb20bc3b6bb26c770b3494ec 100644 (file)
       </para>
 
       <para>
+       This allows the primary to wait for a standby to write the transaction
+       information to disk before acknowledging the commit.
        One standby at a time can take the role of the synchronous standby,
        as controlled by the
        <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.
+       <link linkend="guc-synchronous-commit"><varname>synchronous_commit</></link>
+       setting.
       </para>
      </listitem>
 
index c8b582cce8e4d6e5c581fa498d0e495f3f77680b..503506f1f0d7cc9d5a8efc0f241f246474527020 100644 (file)
@@ -68,7 +68,7 @@ bool          XactReadOnly;
 bool           DefaultXactDeferrable = false;
 bool           XactDeferrable;
 
-bool           XactSyncCommit = true;
+int                    synchronous_commit = SYNCHRONOUS_COMMIT_ON;
 
 int                    CommitDelay = 0;        /* precommit delay in microseconds */
 int                    CommitSiblings = 5; /* # concurrent xacts needed to sleep */
@@ -1056,7 +1056,8 @@ 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())
+       if ((wrote_xlog && synchronous_commit >= SYNCHRONOUS_COMMIT_LOCAL) ||
+               forceSyncCommit || nrels > 0)
        {
                /*
                 * Synchronous commit case:
index efc8e7cc82cf0142ca4e8d733798f4372204cbea..675bfced63c277bcc6554426698005620fefee29 100644 (file)
@@ -1531,7 +1531,8 @@ 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);
+       if (synchronous_commit == SYNCHRONOUS_COMMIT_ON)
+               SetConfigOption("synchronous_commit", "local", PGC_SUSET, PGC_S_OVERRIDE);
 
        /*
         * Get the info about the database we're going to work on.
index 17c255480eb47c227bf9b8391c78e39a32725f08..0d3381465108919d5c086e8ae01223c32afb2742 100644 (file)
@@ -63,7 +63,6 @@
 #include "utils/ps_status.h"
 
 /* User-settable parameters for sync rep */
-bool   synchronous_replication = false;                /* Only set in user backends */
 char   *SyncRepStandbyNames;
 
 #define SyncStandbysDefined() \
index b49bdaea9d038633d65a99dfb69ab880fba19c21..1f7a7d24f833d9f79e1d45021e7b62eca1df8001 100644 (file)
@@ -350,6 +350,23 @@ static const struct config_enum_entry constraint_exclusion_options[] = {
        {NULL, 0, false}
 };
 
+/*
+ * 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
  */
@@ -746,22 +763,6 @@ static struct config_bool ConfigureNamesBool[] =
                &enableFsync,
                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."),
@@ -2908,6 +2909,16 @@ static struct config_enum ConfigureNamesEnum[] =
                assign_session_replication_role, NULL
        },
 
+       {
+               {"synchronous_commit", PGC_USERSET, WAL_SETTINGS,
+                       gettext_noop("Sets the current transaction's synchronization level."),
+                       NULL
+               },
+               &synchronous_commit,
+               SYNCHRONOUS_COMMIT_ON, synchronous_commit_options,
+               NULL, NULL
+       },
+
        {
                {"trace_recovery_messages", PGC_SIGHUP, DEVELOPER_OPTIONS,
                        gettext_noop("Enables logging of recovery-related debugging information."),
index 43481859993e18ee8d2437b720335f69ac639584..b8a1582eaa90b980b0a8477361244d316c2a97a4 100644 (file)
 #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
+#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
 #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
index 1685a0167f55f0f53b195ea9ac57925674f4832d..44101453445f0dc4dad60c460234af5ba6597ecb 100644 (file)
@@ -52,8 +52,15 @@ extern bool XactReadOnly;
 extern bool DefaultXactDeferrable;
 extern bool XactDeferrable;
 
-/* Asynchronous commits */
-extern bool XactSyncCommit;
+typedef enum
+{
+       SYNCHRONOUS_COMMIT_OFF,         /* asynchronous commit */
+       SYNCHRONOUS_COMMIT_LOCAL,       /* wait for only local flush */
+       SYNCHRONOUS_COMMIT_ON           /* wait for local flush and sync rep */
+} SyncCommitLevel;
+
+/* Synchronous commit level */
+extern int     synchronous_commit;
 
 /* Kluge for 2PC support */
 extern bool MyXactAccessedTempRel;
index 188ec65745c76dc174eecec7fee822ce56f17cc4..696edccb120ec7898c5438b1445c360b160e335c 100644 (file)
@@ -20,7 +20,7 @@
 #include "utils/guc.h"
 
 #define SyncRepRequested() \
-       (synchronous_replication && max_wal_senders > 0)
+       (max_wal_senders > 0 && synchronous_commit == SYNCHRONOUS_COMMIT_ON)
 
 /* syncRepState */
 #define SYNC_REP_NOT_WAITING           0
@@ -28,7 +28,6 @@
 #define SYNC_REP_WAIT_COMPLETE         2
 
 /* user-settable parameters for synchronous replication */
-extern bool synchronous_replication;
 extern char *SyncRepStandbyNames;
 
 /* called by user backend */