Ignore recovery_min_apply_delay until recovery has reached consistent state
authorFujii Masao <fujii@postgresql.org>
Sat, 5 Mar 2016 17:29:04 +0000 (02:29 +0900)
committerFujii Masao <fujii@postgresql.org>
Sat, 5 Mar 2016 17:43:26 +0000 (02:43 +0900)
Previously recovery_min_apply_delay was applied even before recovery
had reached consistency. This could cause us to wait a long time
unexpectedly for read-only connections to be allowed. It's problematic
because the standby was useless during that wait time.

This patch changes recovery_min_apply_delay so that it's applied once
the database has reached the consistent state. That is, even if the delay
is set, the standby tries to replay WAL records as fast as possible until
it has reached consistency.

Author: Michael Paquier
Reviewed-By: Julien Rouhaud
Reported-By: Greg Clough
Backpatch: 9.4, where recovery_min_apply_delay was added
Bug: #13770
Discussion: http://www.postgresql.org/message-id/20151111155006.2644.84564@wrigleys.postgresql.org

doc/src/sgml/recovery-config.sgml
src/backend/access/transam/xlog.c

index 119d5de553cedb7503c2040eba4c26a9c13d4ec9..1e9ad76b4398464d7c3b327729d28d7057f8ed15 100644 (file)
@@ -441,8 +441,9 @@ restore_command = 'copy "C:\\server\\archivedir\\%f" "%p"'  # Windows
         are not visible until the corresponding commit record is applied.
        </para>
        <para>
-        The delay occurs until the standby is promoted or triggered. After that
-        the standby will end recovery without further waiting.
+        The delay occurs once the database in recovery has reached a consistent
+        state, until the standby is promoted or triggered. After that the standby
+        will end recovery without further waiting.
        </para>
        <para>
         This parameter is intended for use with streaming replication deployments;
index cc845d23e20452cb41604e491f7908b6e77db8bb..7d23d8e21c66d6ca4639e6f4bef9181c88ed3b50 100644 (file)
@@ -5856,6 +5856,10 @@ recoveryApplyDelay(XLogRecord *record)
    if (recovery_min_apply_delay <= 0)
        return false;
 
+   /* no delay is applied on a database not yet consistent */
+   if (!reachedConsistency)
+       return false;
+
    /*
     * Is it a COMMIT record?
     *