Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit dee663f

Browse files
committed
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 3eb77eb. 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
1 parent ca7f8e2 commit dee663f

File tree

16 files changed

+252
-172
lines changed

16 files changed

+252
-172
lines changed

src/backend/access/transam/clog.c

+18-22
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "pg_trace.h"
4343
#include "pgstat.h"
4444
#include "storage/proc.h"
45+
#include "storage/sync.h"
4546

4647
/*
4748
* Defines for CLOG page sizes. A page is the same BLCKSZ as is used
@@ -691,7 +692,8 @@ CLOGShmemInit(void)
691692
{
692693
XactCtl->PagePrecedes = CLOGPagePrecedes;
693694
SimpleLruInit(XactCtl, "Xact", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
694-
XactSLRULock, "pg_xact", LWTRANCHE_XACT_BUFFER);
695+
XactSLRULock, "pg_xact", LWTRANCHE_XACT_BUFFER,
696+
SYNC_HANDLER_CLOG);
695697
}
696698

697699
/*
@@ -808,34 +810,19 @@ TrimCLOG(void)
808810
LWLockRelease(XactSLRULock);
809811
}
810812

811-
/*
812-
* This must be called ONCE during postmaster or standalone-backend shutdown
813-
*/
814-
void
815-
ShutdownCLOG(void)
816-
{
817-
/* Flush dirty CLOG pages to disk */
818-
TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(false);
819-
SimpleLruFlush(XactCtl, false);
820-
821-
/*
822-
* fsync pg_xact to ensure that any files flushed previously are durably
823-
* on disk.
824-
*/
825-
fsync_fname("pg_xact", true);
826-
827-
TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(false);
828-
}
829-
830813
/*
831814
* Perform a checkpoint --- either during shutdown, or on-the-fly
832815
*/
833816
void
834817
CheckPointCLOG(void)
835818
{
836-
/* Flush dirty CLOG pages to disk */
819+
/*
820+
* Write dirty CLOG pages to disk. This may result in sync requests
821+
* queued for later handling by ProcessSyncRequests(), as part of the
822+
* checkpoint.
823+
*/
837824
TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);
838-
SimpleLruFlush(XactCtl, true);
825+
SimpleLruWriteAll(XactCtl, true);
839826
TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
840827
}
841828

@@ -1026,3 +1013,12 @@ clog_redo(XLogReaderState *record)
10261013
else
10271014
elog(PANIC, "clog_redo: unknown op code %u", info);
10281015
}
1016+
1017+
/*
1018+
* Entrypoint for sync.c to sync clog files.
1019+
*/
1020+
int
1021+
clogsyncfiletag(const FileTag *ftag, char *path)
1022+
{
1023+
return SlruSyncFileTag(XactCtl, ftag, path);
1024+
}

src/backend/access/transam/commit_ts.c

+17-19
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,8 @@ CommitTsShmemInit(void)
555555
CommitTsCtl->PagePrecedes = CommitTsPagePrecedes;
556556
SimpleLruInit(CommitTsCtl, "CommitTs", CommitTsShmemBuffers(), 0,
557557
CommitTsSLRULock, "pg_commit_ts",
558-
LWTRANCHE_COMMITTS_BUFFER);
558+
LWTRANCHE_COMMITTS_BUFFER,
559+
SYNC_HANDLER_COMMIT_TS);
559560

560561
commitTsShared = ShmemInitStruct("CommitTs shared",
561562
sizeof(CommitTimestampShared),
@@ -798,30 +799,18 @@ DeactivateCommitTs(void)
798799
LWLockRelease(CommitTsSLRULock);
799800
}
800801

801-
/*
802-
* This must be called ONCE during postmaster or standalone-backend shutdown
803-
*/
804-
void
805-
ShutdownCommitTs(void)
806-
{
807-
/* Flush dirty CommitTs pages to disk */
808-
SimpleLruFlush(CommitTsCtl, false);
809-
810-
/*
811-
* fsync pg_commit_ts to ensure that any files flushed previously are
812-
* durably on disk.
813-
*/
814-
fsync_fname("pg_commit_ts", true);
815-
}
816-
817802
/*
818803
* Perform a checkpoint --- either during shutdown, or on-the-fly
819804
*/
820805
void
821806
CheckPointCommitTs(void)
822807
{
823-
/* Flush dirty CommitTs pages to disk */
824-
SimpleLruFlush(CommitTsCtl, true);
808+
/*
809+
* Write dirty CommitTs pages to disk. This may result in sync requests
810+
* queued for later handling by ProcessSyncRequests(), as part of the
811+
* checkpoint.
812+
*/
813+
SimpleLruWriteAll(CommitTsCtl, true);
825814
}
826815

827816
/*
@@ -1077,3 +1066,12 @@ commit_ts_redo(XLogReaderState *record)
10771066
else
10781067
elog(PANIC, "commit_ts_redo: unknown op code %u", info);
10791068
}
1069+
1070+
/*
1071+
* Entrypoint for sync.c to sync commit_ts files.
1072+
*/
1073+
int
1074+
committssyncfiletag(const FileTag *ftag, char *path)
1075+
{
1076+
return SlruSyncFileTag(CommitTsCtl, ftag, path);
1077+
}

src/backend/access/transam/multixact.c

+32-25
Original file line numberDiff line numberDiff line change
@@ -1831,11 +1831,13 @@ MultiXactShmemInit(void)
18311831
SimpleLruInit(MultiXactOffsetCtl,
18321832
"MultiXactOffset", NUM_MULTIXACTOFFSET_BUFFERS, 0,
18331833
MultiXactOffsetSLRULock, "pg_multixact/offsets",
1834-
LWTRANCHE_MULTIXACTOFFSET_BUFFER);
1834+
LWTRANCHE_MULTIXACTOFFSET_BUFFER,
1835+
SYNC_HANDLER_MULTIXACT_OFFSET);
18351836
SimpleLruInit(MultiXactMemberCtl,
18361837
"MultiXactMember", NUM_MULTIXACTMEMBER_BUFFERS, 0,
18371838
MultiXactMemberSLRULock, "pg_multixact/members",
1838-
LWTRANCHE_MULTIXACTMEMBER_BUFFER);
1839+
LWTRANCHE_MULTIXACTMEMBER_BUFFER,
1840+
SYNC_HANDLER_MULTIXACT_MEMBER);
18391841

18401842
/* Initialize our shared state struct */
18411843
MultiXactState = ShmemInitStruct("Shared MultiXact State",
@@ -2100,19 +2102,6 @@ TrimMultiXact(void)
21002102
SetMultiXactIdLimit(oldestMXact, oldestMXactDB, true);
21012103
}
21022104

2103-
/*
2104-
* This must be called ONCE during postmaster or standalone-backend shutdown
2105-
*/
2106-
void
2107-
ShutdownMultiXact(void)
2108-
{
2109-
/* Flush dirty MultiXact pages to disk */
2110-
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(false);
2111-
SimpleLruFlush(MultiXactOffsetCtl, false);
2112-
SimpleLruFlush(MultiXactMemberCtl, false);
2113-
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(false);
2114-
}
2115-
21162105
/*
21172106
* Get the MultiXact data to save in a checkpoint record
21182107
*/
@@ -2143,9 +2132,13 @@ CheckPointMultiXact(void)
21432132
{
21442133
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_START(true);
21452134

2146-
/* Flush dirty MultiXact pages to disk */
2147-
SimpleLruFlush(MultiXactOffsetCtl, true);
2148-
SimpleLruFlush(MultiXactMemberCtl, true);
2135+
/*
2136+
* Write dirty MultiXact pages to disk. This may result in sync requests
2137+
* queued for later handling by ProcessSyncRequests(), as part of the
2138+
* checkpoint.
2139+
*/
2140+
SimpleLruWriteAll(MultiXactOffsetCtl, true);
2141+
SimpleLruWriteAll(MultiXactMemberCtl, true);
21492142

21502143
TRACE_POSTGRESQL_MULTIXACT_CHECKPOINT_DONE(true);
21512144
}
@@ -2728,14 +2721,10 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result)
27282721
entryno = MultiXactIdToOffsetEntry(multi);
27292722

27302723
/*
2731-
* Flush out dirty data, so PhysicalPageExists can work correctly.
2732-
* SimpleLruFlush() is a pretty big hammer for that. Alternatively we
2733-
* could add an in-memory version of page exists, but find_multixact_start
2734-
* is called infrequently, and it doesn't seem bad to flush buffers to
2735-
* disk before truncation.
2724+
* Write out dirty data, so PhysicalPageExists can work correctly.
27362725
*/
2737-
SimpleLruFlush(MultiXactOffsetCtl, true);
2738-
SimpleLruFlush(MultiXactMemberCtl, true);
2726+
SimpleLruWriteAll(MultiXactOffsetCtl, true);
2727+
SimpleLruWriteAll(MultiXactMemberCtl, true);
27392728

27402729
if (!SimpleLruDoesPhysicalPageExist(MultiXactOffsetCtl, pageno))
27412730
return false;
@@ -3386,3 +3375,21 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
33863375

33873376
SRF_RETURN_DONE(funccxt);
33883377
}
3378+
3379+
/*
3380+
* Entrypoint for sync.c to sync offsets files.
3381+
*/
3382+
int
3383+
multixactoffsetssyncfiletag(const FileTag *ftag, char *path)
3384+
{
3385+
return SlruSyncFileTag(MultiXactOffsetCtl, ftag, path);
3386+
}
3387+
3388+
/*
3389+
* Entrypoint for sync.c to sync members files.
3390+
*/
3391+
int
3392+
multixactmemberssyncfiletag(const FileTag *ftag, char *path)
3393+
{
3394+
return SlruSyncFileTag(MultiXactMemberCtl, ftag, path);
3395+
}

0 commit comments

Comments
 (0)