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

Commit 3eb77eb

Browse files
committed
Refactor the fsync queue for wider use.
Previously, md.c and checkpointer.c were tightly integrated so that fsync calls could be handed off and processed in the background. Introduce a system of callbacks and file tags, so that other modules can hand off fsync work in the same way. For now only md.c uses the new interface, but other users are being proposed. Since there may be use cases that are not strictly SMGR implementations, use a new function table for sync handlers rather than extending the traditional SMGR one. Instead of using a bitmapset of segment numbers for each RelFileNode in the checkpointer's hash table, make the segment number part of the key. This requires sending explicit "forget" requests for every segment individually when relations are dropped, but suits the file layout schemes of proposed future users better (ie sparse or high segment numbers). Author: Shawn Debnath and Thomas Munro Reviewed-by: Thomas Munro, Andres Freund Discussion: https://postgr.es/m/CAEepm=2gTANm=e3ARnJT=n0h8hf88wqmaZxk0JYkxw+b21fNrw@mail.gmail.com
1 parent 33215d1 commit 3eb77eb

File tree

18 files changed

+904
-890
lines changed

18 files changed

+904
-890
lines changed

src/backend/access/transam/twophase.c

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
#include "replication/walsender.h"
9999
#include "storage/fd.h"
100100
#include "storage/ipc.h"
101+
#include "storage/md.h"
101102
#include "storage/predicate.h"
102103
#include "storage/proc.h"
103104
#include "storage/procarray.h"

src/backend/access/transam/xact.c

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "storage/fd.h"
5151
#include "storage/freespace.h"
5252
#include "storage/lmgr.h"
53+
#include "storage/md.h"
5354
#include "storage/predicate.h"
5455
#include "storage/proc.h"
5556
#include "storage/procarray.h"

src/backend/access/transam/xlog.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "storage/reinit.h"
6767
#include "storage/smgr.h"
6868
#include "storage/spin.h"
69+
#include "storage/sync.h"
6970
#include "utils/builtins.h"
7071
#include "utils/guc.h"
7172
#include "utils/memutils.h"
@@ -6981,7 +6982,7 @@ StartupXLOG(void)
69816982
if (ArchiveRecoveryRequested && IsUnderPostmaster)
69826983
{
69836984
PublishStartupProcessInformation();
6984-
SetForwardFsyncRequests();
6985+
EnableSyncRequestForwarding();
69856986
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
69866987
bgwriterLaunched = true;
69876988
}
@@ -8566,7 +8567,7 @@ CreateCheckPoint(int flags)
85668567
* the REDO pointer. Note that smgr must not do anything that'd have to
85678568
* be undone if we decide no checkpoint is needed.
85688569
*/
8569-
smgrpreckpt();
8570+
SyncPreCheckpoint();
85708571

85718572
/* Begin filling in the checkpoint WAL record */
85728573
MemSet(&checkPoint, 0, sizeof(checkPoint));
@@ -8856,7 +8857,7 @@ CreateCheckPoint(int flags)
88568857
/*
88578858
* Let smgr do post-checkpoint cleanup (eg, deleting old files).
88588859
*/
8859-
smgrpostckpt();
8860+
SyncPostCheckpoint();
88608861

88618862
/*
88628863
* Update the average distance between checkpoints if the prior checkpoint

src/backend/commands/dbcommands.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include "storage/fd.h"
5555
#include "storage/lmgr.h"
5656
#include "storage/ipc.h"
57+
#include "storage/md.h"
5758
#include "storage/procarray.h"
5859
#include "storage/smgr.h"
5960
#include "utils/acl.h"
@@ -941,11 +942,11 @@ dropdb(const char *dbname, bool missing_ok)
941942
* worse, it will delete files that belong to a newly created database
942943
* with the same OID.
943944
*/
944-
ForgetDatabaseFsyncRequests(db_id);
945+
ForgetDatabaseSyncRequests(db_id);
945946

946947
/*
947948
* Force a checkpoint to make sure the checkpointer has received the
948-
* message sent by ForgetDatabaseFsyncRequests. On Windows, this also
949+
* message sent by ForgetDatabaseSyncRequests. On Windows, this also
949950
* ensures that background procs don't hold any open files, which would
950951
* cause rmdir() to fail.
951952
*/
@@ -2150,7 +2151,7 @@ dbase_redo(XLogReaderState *record)
21502151
DropDatabaseBuffers(xlrec->db_id);
21512152

21522153
/* Also, clean out any fsync requests that might be pending in md.c */
2153-
ForgetDatabaseFsyncRequests(xlrec->db_id);
2154+
ForgetDatabaseSyncRequests(xlrec->db_id);
21542155

21552156
/* Clean out the xlog relcache too */
21562157
XLogDropDatabase(xlrec->db_id);

src/backend/postmaster/checkpointer.c

+14-26
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,8 @@
108108
*/
109109
typedef struct
110110
{
111-
RelFileNode rnode;
112-
ForkNumber forknum;
113-
BlockNumber segno; /* see md.c for special values */
114-
/* might add a real request-type field later; not needed yet */
111+
SyncRequestType type; /* request type */
112+
FileTag ftag; /* file identifier */
115113
} CheckpointerRequest;
116114

117115
typedef struct
@@ -349,7 +347,7 @@ CheckpointerMain(void)
349347
/*
350348
* Process any requests or signals received recently.
351349
*/
352-
AbsorbFsyncRequests();
350+
AbsorbSyncRequests();
353351

354352
if (got_SIGHUP)
355353
{
@@ -684,7 +682,7 @@ CheckpointWriteDelay(int flags, double progress)
684682
UpdateSharedMemoryConfig();
685683
}
686684

687-
AbsorbFsyncRequests();
685+
AbsorbSyncRequests();
688686
absorb_counter = WRITES_PER_ABSORB;
689687

690688
CheckArchiveTimeout();
@@ -709,7 +707,7 @@ CheckpointWriteDelay(int flags, double progress)
709707
* operations even when we don't sleep, to prevent overflow of the
710708
* fsync request queue.
711709
*/
712-
AbsorbFsyncRequests();
710+
AbsorbSyncRequests();
713711
absorb_counter = WRITES_PER_ABSORB;
714712
}
715713
}
@@ -1084,7 +1082,7 @@ RequestCheckpoint(int flags)
10841082
}
10851083

10861084
/*
1087-
* ForwardFsyncRequest
1085+
* ForwardSyncRequest
10881086
* Forward a file-fsync request from a backend to the checkpointer
10891087
*
10901088
* Whenever a backend is compelled to write directly to a relation
@@ -1093,15 +1091,6 @@ RequestCheckpoint(int flags)
10931091
* is dirty and must be fsync'd before next checkpoint. We also use this
10941092
* opportunity to count such writes for statistical purposes.
10951093
*
1096-
* This functionality is only supported for regular (not backend-local)
1097-
* relations, so the rnode argument is intentionally RelFileNode not
1098-
* RelFileNodeBackend.
1099-
*
1100-
* segno specifies which segment (not block!) of the relation needs to be
1101-
* fsync'd. (Since the valid range is much less than BlockNumber, we can
1102-
* use high values for special flags; that's all internal to md.c, which
1103-
* see for details.)
1104-
*
11051094
* To avoid holding the lock for longer than necessary, we normally write
11061095
* to the requests[] queue without checking for duplicates. The checkpointer
11071096
* will have to eliminate dups internally anyway. However, if we discover
@@ -1113,7 +1102,7 @@ RequestCheckpoint(int flags)
11131102
* let the backend know by returning false.
11141103
*/
11151104
bool
1116-
ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
1105+
ForwardSyncRequest(const FileTag *ftag, SyncRequestType type)
11171106
{
11181107
CheckpointerRequest *request;
11191108
bool too_full;
@@ -1122,7 +1111,7 @@ ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
11221111
return false; /* probably shouldn't even get here */
11231112

11241113
if (AmCheckpointerProcess())
1125-
elog(ERROR, "ForwardFsyncRequest must not be called in checkpointer");
1114+
elog(ERROR, "ForwardSyncRequest must not be called in checkpointer");
11261115

11271116
LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
11281117

@@ -1151,9 +1140,8 @@ ForwardFsyncRequest(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
11511140

11521141
/* OK, insert request */
11531142
request = &CheckpointerShmem->requests[CheckpointerShmem->num_requests++];
1154-
request->rnode = rnode;
1155-
request->forknum = forknum;
1156-
request->segno = segno;
1143+
request->ftag = *ftag;
1144+
request->type = type;
11571145

11581146
/* If queue is more than half full, nudge the checkpointer to empty it */
11591147
too_full = (CheckpointerShmem->num_requests >=
@@ -1284,16 +1272,16 @@ CompactCheckpointerRequestQueue(void)
12841272
}
12851273

12861274
/*
1287-
* AbsorbFsyncRequests
1288-
* Retrieve queued fsync requests and pass them to local smgr.
1275+
* AbsorbSyncRequests
1276+
* Retrieve queued sync requests and pass them to sync mechanism.
12891277
*
12901278
* This is exported because it must be called during CreateCheckPoint;
12911279
* we have to be sure we have accepted all pending requests just before
12921280
* we start fsync'ing. Since CreateCheckPoint sometimes runs in
12931281
* non-checkpointer processes, do nothing if not checkpointer.
12941282
*/
12951283
void
1296-
AbsorbFsyncRequests(void)
1284+
AbsorbSyncRequests(void)
12971285
{
12981286
CheckpointerRequest *requests = NULL;
12991287
CheckpointerRequest *request;
@@ -1335,7 +1323,7 @@ AbsorbFsyncRequests(void)
13351323
LWLockRelease(CheckpointerCommLock);
13361324

13371325
for (request = requests; n > 0; request++, n--)
1338-
RememberFsyncRequest(request->rnode, request->forknum, request->segno);
1326+
RememberSyncRequest(&request->ftag, request->type);
13391327

13401328
END_CRIT_SECTION();
13411329

src/backend/storage/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ subdir = src/backend/storage
88
top_builddir = ../../..
99
include $(top_builddir)/src/Makefile.global
1010

11-
SUBDIRS = buffer file freespace ipc large_object lmgr page smgr
11+
SUBDIRS = buffer file freespace ipc large_object lmgr page smgr sync
1212

1313
include $(top_srcdir)/src/backend/common.mk

src/backend/storage/buffer/bufmgr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -2584,7 +2584,7 @@ CheckPointBuffers(int flags)
25842584
BufferSync(flags);
25852585
CheckpointStats.ckpt_sync_t = GetCurrentTimestamp();
25862586
TRACE_POSTGRESQL_BUFFER_CHECKPOINT_SYNC_START();
2587-
smgrsync();
2587+
ProcessSyncRequests();
25882588
CheckpointStats.ckpt_sync_end_t = GetCurrentTimestamp();
25892589
TRACE_POSTGRESQL_BUFFER_CHECKPOINT_DONE();
25902590
}

0 commit comments

Comments
 (0)