mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Specialize checkpointer sort functions.
When sorting a potentially large number of dirty buffers, the checkpointer can benefit from a faster sort routine. One reported improvement on a large buffer pool system was 1.4s -> 0.6s. Reviewed-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/CA%2BhUKGJ2-eaDqAum5bxhpMNhvuJmRDZxB_Tow0n-gse%2BHG0Yig%40mail.gmail.com
This commit is contained in:
@ -488,8 +488,8 @@ static void FindAndDropRelFileNodeBuffers(RelFileNode rnode,
|
|||||||
static void AtProcExit_Buffers(int code, Datum arg);
|
static void AtProcExit_Buffers(int code, Datum arg);
|
||||||
static void CheckForBufferLeaks(void);
|
static void CheckForBufferLeaks(void);
|
||||||
static int rnode_comparator(const void *p1, const void *p2);
|
static int rnode_comparator(const void *p1, const void *p2);
|
||||||
static int buffertag_comparator(const void *p1, const void *p2);
|
static inline int buffertag_comparator(const BufferTag *a, const BufferTag *b);
|
||||||
static int ckpt_buforder_comparator(const void *pa, const void *pb);
|
static inline int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b);
|
||||||
static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg);
|
static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg);
|
||||||
|
|
||||||
|
|
||||||
@ -1831,6 +1831,13 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ST_SORT sort_checkpoint_bufferids
|
||||||
|
#define ST_ELEMENT_TYPE CkptSortItem
|
||||||
|
#define ST_COMPARE(a, b) ckpt_buforder_comparator(a, b)
|
||||||
|
#define ST_SCOPE static
|
||||||
|
#define ST_DEFINE
|
||||||
|
#include <lib/sort_template.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BufferSync -- Write out all dirty buffers in the pool.
|
* BufferSync -- Write out all dirty buffers in the pool.
|
||||||
*
|
*
|
||||||
@ -1931,8 +1938,7 @@ BufferSync(int flags)
|
|||||||
* end up writing to the tablespaces one-by-one; possibly overloading the
|
* end up writing to the tablespaces one-by-one; possibly overloading the
|
||||||
* underlying system.
|
* underlying system.
|
||||||
*/
|
*/
|
||||||
qsort(CkptBufferIds, num_to_scan, sizeof(CkptSortItem),
|
sort_checkpoint_bufferids(CkptBufferIds, num_to_scan);
|
||||||
ckpt_buforder_comparator);
|
|
||||||
|
|
||||||
num_spaces = 0;
|
num_spaces = 0;
|
||||||
|
|
||||||
@ -4567,11 +4573,9 @@ WaitBufHdrUnlocked(BufferDesc *buf)
|
|||||||
/*
|
/*
|
||||||
* BufferTag comparator.
|
* BufferTag comparator.
|
||||||
*/
|
*/
|
||||||
static int
|
static inline int
|
||||||
buffertag_comparator(const void *a, const void *b)
|
buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
|
||||||
{
|
{
|
||||||
const BufferTag *ba = (const BufferTag *) a;
|
|
||||||
const BufferTag *bb = (const BufferTag *) b;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = rnode_comparator(&ba->rnode, &bb->rnode);
|
ret = rnode_comparator(&ba->rnode, &bb->rnode);
|
||||||
@ -4598,12 +4602,9 @@ buffertag_comparator(const void *a, const void *b)
|
|||||||
* It is important that tablespaces are compared first, the logic balancing
|
* It is important that tablespaces are compared first, the logic balancing
|
||||||
* writes between tablespaces relies on it.
|
* writes between tablespaces relies on it.
|
||||||
*/
|
*/
|
||||||
static int
|
static inline int
|
||||||
ckpt_buforder_comparator(const void *pa, const void *pb)
|
ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b)
|
||||||
{
|
{
|
||||||
const CkptSortItem *a = (const CkptSortItem *) pa;
|
|
||||||
const CkptSortItem *b = (const CkptSortItem *) pb;
|
|
||||||
|
|
||||||
/* compare tablespace */
|
/* compare tablespace */
|
||||||
if (a->tsId < b->tsId)
|
if (a->tsId < b->tsId)
|
||||||
return -1;
|
return -1;
|
||||||
@ -4694,6 +4695,13 @@ ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag *tag)
|
|||||||
IssuePendingWritebacks(context);
|
IssuePendingWritebacks(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ST_SORT sort_pending_writebacks
|
||||||
|
#define ST_ELEMENT_TYPE PendingWriteback
|
||||||
|
#define ST_COMPARE(a, b) buffertag_comparator(&a->tag, &b->tag)
|
||||||
|
#define ST_SCOPE static
|
||||||
|
#define ST_DEFINE
|
||||||
|
#include <lib/sort_template.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue all pending writeback requests, previously scheduled with
|
* Issue all pending writeback requests, previously scheduled with
|
||||||
* ScheduleBufferTagForWriteback, to the OS.
|
* ScheduleBufferTagForWriteback, to the OS.
|
||||||
@ -4713,8 +4721,7 @@ IssuePendingWritebacks(WritebackContext *context)
|
|||||||
* Executing the writes in-order can make them a lot faster, and allows to
|
* Executing the writes in-order can make them a lot faster, and allows to
|
||||||
* merge writeback requests to consecutive blocks into larger writebacks.
|
* merge writeback requests to consecutive blocks into larger writebacks.
|
||||||
*/
|
*/
|
||||||
qsort(&context->pending_writebacks, context->nr_pending,
|
sort_pending_writebacks(context->pending_writebacks, context->nr_pending);
|
||||||
sizeof(PendingWriteback), buffertag_comparator);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Coalesce neighbouring writes, but nothing else. For that we iterate
|
* Coalesce neighbouring writes, but nothing else. For that we iterate
|
||||||
|
Reference in New Issue
Block a user