Lockless StrategyGetBuffer clock sweep hotpath. rwlock-contention-clean
authorAndres Freund <andres@anarazel.de>
Tue, 23 Dec 2014 21:55:56 +0000 (22:55 +0100)
committerAndres Freund <andres@anarazel.de>
Tue, 23 Dec 2014 21:55:56 +0000 (22:55 +0100)
commitd6dcebfb7e3fd58949ef39ca1e6b47e39ac1df75
tree7afabfabca5abc9f7722cccdfda2ecd2c3e18fa9
parent5e78af23020185b1a870537e9f107d89cea36bae
Lockless StrategyGetBuffer clock sweep hotpath.

StrategyGetBuffer() has proven to be a bottleneck in a number of
buffer acquisition heavy workloads. To some degree this has already
been alleviated by 5d7962c6, but it's still can be quite a heavy
bottleneck.  The problem is that in unfortunate usage patterns a
single StrategyGetBuffer() call will have to look at a large number of
buffers - in turn making it likely that the process will be put to
sleep while still holding the spinlock.

Replace most of the buffer_strategy_lock for the clock sweep by a
atomic nextVictimBuffer variable. That variable, modulo NBuffers, is
the current hand of the clock sweep. The buffer clock-sweep only needs
to acquire the spinlock after a wraparound. And even then, only in the
process wrapping around. That alleviates nearly all the contention in
the relevant spinlock.

Reviewed-By: Robert Haas and Amit Kapila
src/backend/postmaster/bgwriter.c
src/backend/storage/buffer/freelist.c
src/include/storage/buf_internals.h