Change checkpoint_completion_target default to 0.9

Common recommendations are that the checkpoint should be spread out as
much as possible, provided we avoid having it take too long.  This
change updates the default to 0.9 (from 0.5) to match that
recommendation.

There was some debate about possibly removing the option entirely but it
seems there may be some corner-cases where having it set much lower to
try to force the checkpoint to be as fast as possible could result in
fewer periods of time of reduced performance due to kernel flushing.
General agreement is that the "spread more" is the preferred approach
though and those who need to tune away from that value are much less
common.

Reviewed-By: Michael Paquier, Peter Eisentraut, Tom Lane, David Steele,
Nathan Bossart
Discussion: https://postgr.es/m/20201207175329.GM16415%40tamriel.snowman.net
This commit is contained in:
Stephen Frost 2021-03-24 13:07:51 -04:00
parent e5595de03e
commit bbcc4eb2e0
6 changed files with 30 additions and 18 deletions

View File

@ -3302,9 +3302,15 @@ include_dir 'conf.d'
<listitem> <listitem>
<para> <para>
Specifies the target of checkpoint completion, as a fraction of Specifies the target of checkpoint completion, as a fraction of
total time between checkpoints. The default is 0.5. total time between checkpoints. The default is 0.9, which spreads the
This parameter can only be set in the <filename>postgresql.conf</filename> checkpoint across almost all of the available interval, providing fairly
file or on the server command line. consistent I/O load while also leaving some time for checkpoint
completion overhead. Reducing this parameter is not recommended because
it causes the checkpoint to complete faster. This results in a higher
rate of I/O during the checkpoint followed by a period of less I/O between
the checkpoint completion and the next scheduled checkpoint. This
parameter can only be set in the <filename>postgresql.conf</filename> file
or on the server command line.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -571,22 +571,29 @@
writing dirty buffers during a checkpoint is spread over a period of time. writing dirty buffers during a checkpoint is spread over a period of time.
That period is controlled by That period is controlled by
<xref linkend="guc-checkpoint-completion-target"/>, which is <xref linkend="guc-checkpoint-completion-target"/>, which is
given as a fraction of the checkpoint interval. given as a fraction of the checkpoint interval (configured by using
<varname>checkpoint_timeout</varname>).
The I/O rate is adjusted so that the checkpoint finishes when the The I/O rate is adjusted so that the checkpoint finishes when the
given fraction of given fraction of
<varname>checkpoint_timeout</varname> seconds have elapsed, or before <varname>checkpoint_timeout</varname> seconds have elapsed, or before
<varname>max_wal_size</varname> is exceeded, whichever is sooner. <varname>max_wal_size</varname> is exceeded, whichever is sooner.
With the default value of 0.5, With the default value of 0.9,
<productname>PostgreSQL</productname> can be expected to complete each checkpoint <productname>PostgreSQL</productname> can be expected to complete each checkpoint
in about half the time before the next checkpoint starts. On a system a bit before the next scheduled checkpoint (at around 90% of the last checkpoint's
that's very close to maximum I/O throughput during normal operation, duration). This spreads out the I/O as much as possible so that the checkpoint
you might want to increase <varname>checkpoint_completion_target</varname> I/O load is consistent throughout the checkpoint interval. The disadvantage of
to reduce the I/O load from checkpoints. The disadvantage of this is that this is that prolonging checkpoints affects recovery time, because more WAL
prolonging checkpoints affects recovery time, because more WAL segments segments will need to be kept around for possible use in recovery. A user
will need to be kept around for possible use in recovery. Although concerned about the amount of time required to recover might wish to reduce
<varname>checkpoint_completion_target</varname> can be set as high as 1.0, <varname>checkpoint_timeout</varname> so that checkpoints occur more frequently
it is best to keep it less than that (perhaps 0.9 at most) since but still spread the I/O across the checkpoint interval. Alternatively,
checkpoints include some other activities besides writing dirty buffers. <varname>checkpoint_completion_target</varname> could be reduced, but this would
result in times of more intense I/O (during the checkpoint) and times of less I/O
(after the checkpoint completed but before the next scheduled checkpoint) and
therefore is not recommended.
Although <varname>checkpoint_completion_target</varname> could be set as high as
1.0, it is typically recommended to set it to no higher than 0.9 (the default)
since checkpoints include some other activities besides writing dirty buffers.
A setting of 1.0 is quite likely to result in checkpoints not being A setting of 1.0 is quite likely to result in checkpoints not being
completed on time, which would result in performance loss due to completed on time, which would result in performance loss due to
unexpected variation in the number of WAL segments needed. unexpected variation in the number of WAL segments needed.

View File

@ -145,7 +145,7 @@ static CheckpointerShmemStruct *CheckpointerShmem;
*/ */
int CheckPointTimeout = 300; int CheckPointTimeout = 300;
int CheckPointWarning = 30; int CheckPointWarning = 30;
double CheckPointCompletionTarget = 0.5; double CheckPointCompletionTarget = 0.9;
/* /*
* Private state * Private state

View File

@ -3725,7 +3725,7 @@ static struct config_real ConfigureNamesReal[] =
NULL NULL
}, },
&CheckPointCompletionTarget, &CheckPointCompletionTarget,
0.5, 0.0, 1.0, 0.9, 0.0, 1.0,
NULL, NULL, NULL NULL, NULL, NULL
}, },

View File

@ -231,7 +231,7 @@
#checkpoint_timeout = 5min # range 30s-1d #checkpoint_timeout = 5min # range 30s-1d
#max_wal_size = 1GB #max_wal_size = 1GB
#min_wal_size = 80MB #min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0 #checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 0 # measured in pages, 0 disables #checkpoint_flush_after = 0 # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables #checkpoint_warning = 30s # 0 disables

View File

@ -26,7 +26,6 @@ my $bravo = get_new_node('bravo');
$bravo->init_from_backup($alpha, 'bkp', has_streaming => 1); $bravo->init_from_backup($alpha, 'bkp', has_streaming => 1);
$bravo->append_conf('postgresql.conf', <<EOF); $bravo->append_conf('postgresql.conf', <<EOF);
checkpoint_timeout=1h checkpoint_timeout=1h
checkpoint_completion_target=0.9
EOF EOF
$bravo->start; $bravo->start;