Augment WAL records for btree delete with GetOldestXmin() to reduce
authorSimon Riggs <simon@2ndquadrant.com>
Fri, 29 Jan 2010 18:39:05 +0000 (18:39 +0000)
committerSimon Riggs <simon@2ndquadrant.com>
Fri, 29 Jan 2010 18:39:05 +0000 (18:39 +0000)
false positives during Hot Standby conflict processing. Simple
patch to enhance conflict processing, following previous discussions.
Controlled by parameter minimize_standby_conflicts = on | off, with
default off allows measurement of performance impact to see whether
it should be set on all the time.

doc/src/sgml/config.sgml
src/backend/access/nbtree/nbtpage.c
src/backend/access/transam/xlog.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/access/xlog.h

index 31b1ef6b1da36ce6278e870d99fe5b7f5f17c164..b8752206215fa15013863634d9c8ee0e728e6bab 100644 (file)
@@ -1840,6 +1840,22 @@ archive_command = 'copy "%p" "C:\\server\\archivedir\\%f"'  # Windows
       </listitem>
      </varlistentry>
 
+     <varlistentry id="minimize-standby-conflicts" xreflabel="minimize_standby_conflicts">
+      <term><varname>minimize_standby_conflicts</varname> (<type>boolean</type>)</term>
+      <indexterm>
+       <primary><varname>minimize_standby_conflicts</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Generates additional information to the transaction log (WAL) to minimize
+        the number of false positive cancelations caused by recovery conflicts on
+        a standby server that consumes WAL data from this server.
+        There is additional performance cost to enabling this parameter.
+        Parameter has no effect during recovery, only in normal running.
+       </para>
+      </listitem>
+     </varlistentry>
+
      </variablelist>
     </sect2>
    </sect1>
index eb8bc31a6e937ea0203b1c8f9b48c0690e52c5a0..318e5e43684e45e3b2b0362adc849eacb07f8507 100644 (file)
@@ -29,6 +29,7 @@
 #include "storage/freespace.h"
 #include "storage/indexfsm.h"
 #include "storage/lmgr.h"
+#include "storage/procarray.h"
 #include "utils/inval.h"
 #include "utils/snapmgr.h"
 
@@ -671,9 +672,18 @@ _bt_delitems(Relation rel, Buffer buf,
 {
    Page        page = BufferGetPage(buf);
    BTPageOpaque opaque;
+   TransactionId latestRemovedXid = InvalidTransactionId;
 
    Assert(isVacuum || lastBlockVacuumed == 0);
 
+   /*
+    * If allowed, calculate an accurate latestRemovedXid, otherwise
+    * pass InvalidTransactionId which can cause false positive
+    * conflicts to be assessed when we replay this WAL record.
+    */
+   if (!isVacuum && XLogStandbyInfoActive() && MinimizeStandbyConflicts)
+       latestRemovedXid = GetOldestXmin(false, true);
+
    /* No ereport(ERROR) until changes are logged */
    START_CRIT_SECTION();
 
@@ -721,13 +731,7 @@ _bt_delitems(Relation rel, Buffer buf,
            xlrec_delete.node = rel->rd_node;
            xlrec_delete.block = BufferGetBlockNumber(buf);
 
-           /*
-            * XXX: We would like to set an accurate latestRemovedXid, but
-            * there is no easy way of obtaining a useful value. So we punt
-            * and store InvalidTransactionId, which forces the standby to
-            * wait for/cancel all currently running transactions.
-            */
-           xlrec_delete.latestRemovedXid = InvalidTransactionId;
+           xlrec_delete.latestRemovedXid = latestRemovedXid;
            rdata[0].data = (char *) &xlrec_delete;
            rdata[0].len = SizeOfBtreeDelete;
        }
index a5e2e8f51529a2c98a445e059dbc418484b91179..13cb4079fe8fc3d7a9ef4ae3e6625a327bd2e30e 100644 (file)
@@ -71,6 +71,7 @@ bool      XLogArchiveMode = false;
 char      *XLogArchiveCommand = NULL;
 bool       XLogRequestRecoveryConnections = true;
 int            MaxStandbyDelay = 30;
+bool       MinimizeStandbyConflicts = false;
 bool       fullPageWrites = true;
 bool       log_checkpoints = false;
 int            sync_method = DEFAULT_SYNC_METHOD;
index 70d1cdde209c55d9bab00143b94917bff6694db2..d456564f0cc4cd118869bf6b3cd0458249e3fc0e 100644 (file)
@@ -1222,6 +1222,17 @@ static struct config_bool ConfigureNamesBool[] =
        true, NULL, NULL
    },
 
+   {
+       {"minimize_standby_conflicts", PGC_POSTMASTER, WAL_SETTINGS,
+           gettext_noop("Additional information is added to WAL records to"
+                        " minimize the number of false positive cancelations"
+                        " caused by recovery conflicts on WAL standby nodes."),
+           NULL
+       },
+       &MinimizeStandbyConflicts,
+       false, NULL, NULL
+   },
+
    {
        {"allow_system_table_mods", PGC_POSTMASTER, DEVELOPER_OPTIONS,
            gettext_noop("Allows modifications of the structure of system tables."),
index 95cab4d64fd61a9ad1b92997e6f86cb361e679e8..928ccc76edf85a011c7ed87fdde64cbc4857b728 100644 (file)
 #archive_timeout = 0       # force a logfile segment switch after this
                # number of seconds; 0 disables
 
+# - Hot Standby -
+
 #recovery_connections = on # allows connections during recovery
+#minimize_standby_conflicts = on # additional WAL info to avoid conflicts
 #max_standby_delay = 30        # max acceptable standby lag (s) to help queries
                # complete without conflict; -1 disables
 
index 2de7e9c3d007f1f6e276913a54efcffb0547ed6e..e2b2942cb9aba575ca37d8dd74c8861bfc4a3068 100644 (file)
@@ -183,6 +183,7 @@ extern int  XLogArchiveTimeout;
 extern bool log_checkpoints;
 extern bool XLogRequestRecoveryConnections;
 extern int MaxStandbyDelay;
+extern bool MinimizeStandbyConflicts;
 
 #define XLogArchivingActive()  (XLogArchiveMode)
 #define XLogArchiveCommandSet() (XLogArchiveCommand[0] != '\0')