mirror of
https://github.com/postgres/postgres.git
synced 2025-11-28 11:44:57 +03:00
Defer flushing of SLRU files.
Previously, we called fsync() after writing out individual pg_xact,
pg_multixact and pg_commit_ts pages due to cache pressure, leading to
regular I/O stalls in user backends and recovery. Collapse requests for
the same file into a single system call as part of the next checkpoint,
as we already did for relation files, using the infrastructure developed
by commit 3eb77eba. This can cause a significant improvement to
recovery performance, especially when it's otherwise CPU-bound.
Hoist ProcessSyncRequests() up into CheckPointGuts() to make it clearer
that it applies to all the SLRU mini-buffer-pools as well as the main
buffer pool. Rearrange things so that data collected in CheckpointStats
includes SLRU activity.
Also remove the Shutdown{CLOG,CommitTS,SUBTRANS,MultiXact}() functions,
because they were redundant after the shutdown checkpoint that
immediately precedes them. (I'm not sure if they were ever needed, but
they aren't now.)
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> (parts)
Tested-by: Jakub Wartak <Jakub.Wartak@tomtom.com>
Discussion: https://postgr.es/m/CA+hUKGLJ=84YT+NvhkEEDAuUtVHMfQ9i-N7k_o50JmQ6Rpj_OQ@mail.gmail.com
This commit is contained in:
@@ -1831,11 +1831,13 @@ MultiXactShmemInit(void)
|
||||
SimpleLruInit(MultiXactOffsetCtl,
|
||||
"MultiXactOffset", NUM_MULTIXACTOFFSET_BUFFERS, 0,
|
||||
MultiXactOffsetSLRULock, "pg_multixact/offsets",
|
||||
LWTRANCHE_MULTIXACTOFFSET_BUFFER);
|
||||
LWTRANCHE_MULTIXACTOFFSET_BUFFER,
|
||||
SYNC_HANDLER_MULTIXACT_OFFSET);
|
||||
SimpleLruInit(MultiXactMemberCtl,
|
||||
"MultiXactMember", NUM_MULTIXACTMEMBER_BUFFERS, 0,
|
||||
MultiXactMemberSLRULock, "pg_multixact/members",
|
||||
LWTRANCHE_MULTIXACTMEMBER_BUFFER);
|
||||
LWTRANCHE_MULTIXACTMEMBER_BUFFER,
|
||||
SYNC_HANDLER_MULTIXACT_MEMBER);
|
||||
|
||||
/* Initialize our shared state struct */
|
||||
MultiXactState = ShmemInitStruct("Shared MultiXact State",
|
||||
@@ -2100,19 +2102,6 @@ TrimMultiXact(void)
|
||||
SetMultiXactIdLimit(oldestMXact, oldestMXactDB, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* This must be called ONCE during postmaster or standalone-backend shutdown
|
||||
*/
|
||||
void
|
||||
ShutdownMultiXact(void)
|
||||
{
|
||||
/* Flush dirty MultiXact pages to disk */
|
||||
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(false);
|
||||
SimpleLruFlush(MultiXactOffsetCtl, false);
|
||||
SimpleLruFlush(MultiXactMemberCtl, false);
|
||||
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the MultiXact data to save in a checkpoint record
|
||||
*/
|
||||
@@ -2143,9 +2132,13 @@ CheckPointMultiXact(void)
|
||||
{
|
||||
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(true);
|
||||
|
||||
/* Flush dirty MultiXact pages to disk */
|
||||
SimpleLruFlush(MultiXactOffsetCtl, true);
|
||||
SimpleLruFlush(MultiXactMemberCtl, true);
|
||||
/*
|
||||
* Write dirty MultiXact pages to disk. This may result in sync requests
|
||||
* queued for later handling by ProcessSyncRequests(), as part of the
|
||||
* checkpoint.
|
||||
*/
|
||||
SimpleLruWriteAll(MultiXactOffsetCtl, true);
|
||||
SimpleLruWriteAll(MultiXactMemberCtl, true);
|
||||
|
||||
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(true);
|
||||
}
|
||||
@@ -2728,14 +2721,10 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result)
|
||||
entryno = MultiXactIdToOffsetEntry(multi);
|
||||
|
||||
/*
|
||||
* Flush out dirty data, so PhysicalPageExists can work correctly.
|
||||
* SimpleLruFlush() is a pretty big hammer for that. Alternatively we
|
||||
* could add an in-memory version of page exists, but find_multixact_start
|
||||
* is called infrequently, and it doesn't seem bad to flush buffers to
|
||||
* disk before truncation.
|
||||
* Write out dirty data, so PhysicalPageExists can work correctly.
|
||||
*/
|
||||
SimpleLruFlush(MultiXactOffsetCtl, true);
|
||||
SimpleLruFlush(MultiXactMemberCtl, true);
|
||||
SimpleLruWriteAll(MultiXactOffsetCtl, true);
|
||||
SimpleLruWriteAll(MultiXactMemberCtl, true);
|
||||
|
||||
if (!SimpleLruDoesPhysicalPageExist(MultiXactOffsetCtl, pageno))
|
||||
return false;
|
||||
@@ -3386,3 +3375,21 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
|
||||
|
||||
SRF_RETURN_DONE(funccxt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entrypoint for sync.c to sync offsets files.
|
||||
*/
|
||||
int
|
||||
multixactoffsetssyncfiletag(const FileTag *ftag, char *path)
|
||||
{
|
||||
return SlruSyncFileTag(MultiXactOffsetCtl, ftag, path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Entrypoint for sync.c to sync members files.
|
||||
*/
|
||||
int
|
||||
multixactmemberssyncfiletag(const FileTag *ftag, char *path)
|
||||
{
|
||||
return SlruSyncFileTag(MultiXactMemberCtl, ftag, path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user