1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

Allow the WAL writer to flush WAL at a reduced rate.

Commit 4de82f7d7 increased the WAL flush rate, mainly to increase the
likelihood that hint bits can be set quickly. More quickly set hint bits
can reduce contention around the clog et al.  But unfortunately the
increased flush rate can have a significant negative performance impact,
I have measured up to a factor of ~4.  The reason for this slowdown is
that if there are independent writes to the underlying devices, for
example because shared buffers is a lot smaller than the hot data set,
or because a checkpoint is ongoing, the fdatasync() calls force cache
flushes to be emitted to the storage.

This is achieved by flushing WAL only if the last flush was longer than
wal_writer_delay ago, or if more than wal_writer_flush_after (new GUC)
unflushed blocks are pending. Based on some tests the default for
wal_writer_delay is 1MB, which seems to work well both on SSD and
rotational media.

To avoid negative performance impact due to 4de82f7d7 an earlier
commit (db76b1e) made SetHintBits() more likely to succeed; preventing
performance regressions in the pgbench tests I performed.

Discussion: 20160118163908.GW10941@awork2.anarazel.de
This commit is contained in:
Andres Freund
2016-02-15 23:52:38 +01:00
parent 5df44d14ba
commit 7975c5e0a9
7 changed files with 141 additions and 52 deletions

View File

@ -2344,15 +2344,38 @@ include_dir 'conf.d'
</indexterm>
</term>
<listitem>
<para>
Specifies the delay between activity rounds for the WAL writer.
In each round the writer will flush WAL to disk. It then sleeps for
<varname>wal_writer_delay</> milliseconds, and repeats. The default
value is 200 milliseconds (<literal>200ms</>). Note that on many
systems, the effective resolution of sleep delays is 10 milliseconds;
setting <varname>wal_writer_delay</> to a value that is not a multiple
of 10 might have the same results as setting it to the next higher
multiple of 10. This parameter can only be set in the
<para>
Specifies how often the WAL writer flushes WAL. After flushing WAL it
sleeps for <varname>wal_writer_delay</> milliseconds, unless woken up
by an asynchronously committing transaction. In case the last flush
happened less than <varname>wal_writer_delay</> milliseconds ago and
less than <varname>wal_writer_flush_after</> bytes of WAL have been
produced since, WAL is only written to the OS, not flushed to disk.
The default value is 200 milliseconds (<literal>200ms</>). Note that
on many systems, the effective resolution of sleep delays is 10
milliseconds; setting <varname>wal_writer_delay</> to a value that is
not a multiple of 10 might have the same results as setting it to the
next higher multiple of 10. This parameter can only be set in the
<filename>postgresql.conf</> file or on the server command line.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-wal-writer-flush-after" xreflabel="wal_writer_flush_after">
<term><varname>wal_writer_flush_after</varname> (<type>integer</type>)
<indexterm>
<primary><varname>wal_writer_flush_after</> configuration parameter</primary>
</indexterm>
</term>
<listitem>
<para>
Specifies how often the WAL writer flushes WAL. In case the last flush
happened less than <varname>wal_writer_delay</> milliseconds ago and
less than <varname>wal_writer_flush_after</> bytes of WAL have been
produced since, WAL is only written to the OS, not flushed to disk.
If <varname>wal_writer_flush_after</> is set to <literal>0</> WAL is
flushed everytime the WAL writer has written WAL. The default is
<literal>1MB</literal>. This parameter can only be set in the
<filename>postgresql.conf</> file or on the server command line.
</para>
</listitem>