Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit09e196e

Browse files
committed
Use callbacks in SlruScanDirectory for the actual action
Previously, the code assumed that the only possible action to take wasto delete files behind a certain cutoff point. The async notify codewas already a crock: it used a different "pagePrecedes" function fortruncation than for regular operation. By allowing it to pass acallback to SlruScanDirectory it can do cleanly exactly what it needs todo.The clog.c code also had its own use for SlruScanDirectory, which ismade a bit simpler with this.
1 parent1a00c0e commit09e196e

File tree

4 files changed

+94
-59
lines changed

4 files changed

+94
-59
lines changed

‎src/backend/access/transam/clog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ TruncateCLOG(TransactionId oldestXact)
606606
cutoffPage=TransactionIdToPage(oldestXact);
607607

608608
/* Check to see if there's any files that could be removed */
609-
if (!SlruScanDirectory(ClogCtl,cutoffPage, false))
609+
if (!SlruScanDirectory(ClogCtl,SlruScanDirCbReportPresence,&cutoffPage))
610610
return;/* nothing to remove */
611611

612612
/* Write XLOG record and flush XLOG to disk */

‎src/backend/access/transam/slru.c

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ static bool SlruPhysicalWritePage(SlruCtl ctl, int pageno, int slotno,
132132
staticvoidSlruReportIOError(SlruCtlctl,intpageno,TransactionIdxid);
133133
staticintSlruSelectLRUPage(SlruCtlctl,intpageno);
134134

135+
staticboolSlruScanDirCbDeleteCutoff(SlruCtlctl,char*filename,
136+
intsegpage,void*data);
135137

136138
/*
137139
* Initialization of shared memory
@@ -1137,33 +1139,84 @@ restart:;
11371139
LWLockRelease(shared->ControlLock);
11381140

11391141
/* Now we can remove the old segment(s) */
1140-
(void)SlruScanDirectory(ctl,cutoffPage, true);
1142+
(void)SlruScanDirectory(ctl,SlruScanDirCbDeleteCutoff,&cutoffPage);
11411143
}
11421144

11431145
/*
1144-
* SimpleLruTruncate subroutine: scan directory for removable segments.
1145-
* Actually remove them iff doDeletions is true. Return TRUE iff any
1146-
* removable segments were found. Note: no locking is needed.
1146+
* SlruScanDirectory callback
1147+
* This callback reports true if there's any segment prior to the one
1148+
* containing the page passed as "data".
1149+
*/
1150+
bool
1151+
SlruScanDirCbReportPresence(SlruCtlctl,char*filename,intsegpage,void*data)
1152+
{
1153+
intcutoffPage=*(int*)data;
1154+
1155+
cutoffPage-=cutoffPage %SLRU_PAGES_PER_SEGMENT;
1156+
1157+
if (ctl->PagePrecedes(segpage,cutoffPage))
1158+
return true;/* found one; don't iterate any more */
1159+
1160+
return false;/* keep going */
1161+
}
1162+
1163+
/*
1164+
* SlruScanDirectory callback.
1165+
*This callback deletes segments prior to the one passed in as "data".
1166+
*/
1167+
staticbool
1168+
SlruScanDirCbDeleteCutoff(SlruCtlctl,char*filename,intsegpage,void*data)
1169+
{
1170+
charpath[MAXPGPATH];
1171+
intcutoffPage=*(int*)data;
1172+
1173+
if (ctl->PagePrecedes(segpage,cutoffPage))
1174+
{
1175+
snprintf(path,MAXPGPATH,"%s/%s",ctl->Dir,filename);
1176+
ereport(DEBUG2,
1177+
(errmsg("removing file \"%s\"",path)));
1178+
unlink(path);
1179+
}
1180+
1181+
return false;/* keep going */
1182+
}
1183+
1184+
/*
1185+
* SlruScanDirectory callback.
1186+
*This callback deletes all segments.
1187+
*/
1188+
bool
1189+
SlruScanDirCbDeleteAll(SlruCtlctl,char*filename,intsegpage,void*data)
1190+
{
1191+
charpath[MAXPGPATH];
1192+
1193+
snprintf(path,MAXPGPATH,"%s/%s",ctl->Dir,filename);
1194+
ereport(DEBUG2,
1195+
(errmsg("removing file \"%s\"",path)));
1196+
unlink(path);
1197+
1198+
return false;/* keep going */
1199+
}
1200+
1201+
/*
1202+
* Scan the SimpleLRU directory and apply a callback to each file found in it.
1203+
*
1204+
* If the callback returns true, the scan is stopped. The last return value
1205+
* from the callback is returned.
11471206
*
1148-
* This can be called directly from clog.c, for reasons explained there.
1207+
* Note that the ordering in which the directory is scanned is not guaranteed.
1208+
*
1209+
* Note that no locking is applied.
11491210
*/
11501211
bool
1151-
SlruScanDirectory(SlruCtlctl,intcutoffPage,booldoDeletions)
1212+
SlruScanDirectory(SlruCtlctl,SlruScanCallbackcallback,void*data)
11521213
{
1153-
boolfound= false;
11541214
DIR*cldir;
11551215
structdirent*clde;
11561216
intsegno;
11571217
intsegpage;
1158-
charpath[MAXPGPATH];
1159-
1160-
/*
1161-
* The cutoff point is the start of the segment containing cutoffPage.
1162-
* (This is redundant when called from SimpleLruTruncate, but not when
1163-
* called directly from clog.c.)
1164-
*/
1165-
cutoffPage-=cutoffPage %SLRU_PAGES_PER_SEGMENT;
1166-
1218+
boolretval;
1219+
11671220
cldir=AllocateDir(ctl->Dir);
11681221
while ((clde=ReadDir(cldir,ctl->Dir))!=NULL)
11691222
{
@@ -1172,20 +1225,15 @@ SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions)
11721225
{
11731226
segno= (int)strtol(clde->d_name,NULL,16);
11741227
segpage=segno*SLRU_PAGES_PER_SEGMENT;
1175-
if (ctl->PagePrecedes(segpage,cutoffPage))
1176-
{
1177-
found= true;
1178-
if (doDeletions)
1179-
{
1180-
snprintf(path,MAXPGPATH,"%s/%s",ctl->Dir,clde->d_name);
1181-
ereport(DEBUG2,
1182-
(errmsg("removing file \"%s\"",path)));
1183-
unlink(path);
1184-
}
1185-
}
1228+
1229+
elog(DEBUG2,"SlruScanDirectory invoking callback on %s/%s",
1230+
ctl->Dir,clde->d_name);
1231+
retval=callback(ctl,clde->d_name,segpage,data);
1232+
if (retval)
1233+
break;
11861234
}
11871235
}
11881236
FreeDir(cldir);
11891237

1190-
returnfound;
1238+
returnretval;
11911239
}

‎src/backend/commands/async.c

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ typedef struct QueuePosition
194194

195195
/* choose logically smaller QueuePosition */
196196
#defineQUEUE_POS_MIN(x,y) \
197-
(asyncQueuePagePrecedesLogically((x).page, (y).page) ? (x) : \
197+
(asyncQueuePagePrecedes((x).page, (y).page) ? (x) : \
198198
(x).page != (y).page ? (y) : \
199199
(x).offset < (y).offset ? (x) : (y))
200200

@@ -360,8 +360,7 @@ static bool backendHasExecutedInitialListen = false;
360360
boolTrace_notify= false;
361361

362362
/* local function prototypes */
363-
staticboolasyncQueuePagePrecedesPhysically(intp,intq);
364-
staticboolasyncQueuePagePrecedesLogically(intp,intq);
363+
staticboolasyncQueuePagePrecedes(intp,intq);
365364
staticvoidqueue_listen(ListenActionKindaction,constchar*channel);
366365
staticvoidAsync_UnlistenOnExit(intcode,Datumarg);
367366
staticvoidExec_ListenPreCommit(void);
@@ -388,25 +387,11 @@ static void NotifyMyFrontEnd(const char *channel,
388387
staticboolAsyncExistsPendingNotify(constchar*channel,constchar*payload);
389388
staticvoidClearPendingActionsAndNotifies(void);
390389

391-
392390
/*
393391
* We will work on the page range of 0..QUEUE_MAX_PAGE.
394-
*
395-
* asyncQueuePagePrecedesPhysically just checks numerically without any magic
396-
* if one page precedes another one. This is wrong for normal operation but
397-
* is helpful when clearing pg_notify/ during startup.
398-
*
399-
* asyncQueuePagePrecedesLogically compares using wraparound logic, as is
400-
* required by slru.c.
401392
*/
402393
staticbool
403-
asyncQueuePagePrecedesPhysically(intp,intq)
404-
{
405-
returnp<q;
406-
}
407-
408-
staticbool
409-
asyncQueuePagePrecedesLogically(intp,intq)
394+
asyncQueuePagePrecedes(intp,intq)
410395
{
411396
intdiff;
412397

@@ -484,7 +469,7 @@ AsyncShmemInit(void)
484469
/*
485470
* Set up SLRU management of the pg_notify data.
486471
*/
487-
AsyncCtl->PagePrecedes=asyncQueuePagePrecedesLogically;
472+
AsyncCtl->PagePrecedes=asyncQueuePagePrecedes;
488473
SimpleLruInit(AsyncCtl,"Async Ctl",NUM_ASYNC_BUFFERS,0,
489474
AsyncCtlLock,"pg_notify");
490475
/* Override default assumption that writes should be fsync'd */
@@ -494,15 +479,8 @@ AsyncShmemInit(void)
494479
{
495480
/*
496481
* During start or reboot, clean out the pg_notify directory.
497-
*
498-
* Since we want to remove every file, we temporarily use
499-
* asyncQueuePagePrecedesPhysically() and pass INT_MAX as the
500-
* comparison value; every file in the directory should therefore
501-
* appear to be less than that.
502482
*/
503-
AsyncCtl->PagePrecedes=asyncQueuePagePrecedesPhysically;
504-
(void)SlruScanDirectory(AsyncCtl,INT_MAX, true);
505-
AsyncCtl->PagePrecedes=asyncQueuePagePrecedesLogically;
483+
(void)SlruScanDirectory(AsyncCtl,SlruScanDirCbDeleteAll,NULL);
506484

507485
/* Now initialize page zero to empty */
508486
LWLockAcquire(AsyncCtlLock,LW_EXCLUSIVE);
@@ -1223,7 +1201,7 @@ asyncQueueIsFull(void)
12231201
nexthead=0;/* wrap around */
12241202
boundary=QUEUE_POS_PAGE(QUEUE_TAIL);
12251203
boundary-=boundary %SLRU_PAGES_PER_SEGMENT;
1226-
returnasyncQueuePagePrecedesLogically(nexthead,boundary);
1204+
returnasyncQueuePagePrecedes(nexthead,boundary);
12271205
}
12281206

12291207
/*
@@ -2074,7 +2052,7 @@ asyncQueueAdvanceTail(void)
20742052
*/
20752053
newtailpage=QUEUE_POS_PAGE(min);
20762054
boundary=newtailpage- (newtailpage %SLRU_PAGES_PER_SEGMENT);
2077-
if (asyncQueuePagePrecedesLogically(oldtailpage,boundary))
2055+
if (asyncQueuePagePrecedes(oldtailpage,boundary))
20782056
{
20792057
/*
20802058
* SimpleLruTruncate() will ask for AsyncCtlLock but will also release

‎src/include/access/slru.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno,
145145
externvoidSimpleLruWritePage(SlruCtlctl,intslotno);
146146
externvoidSimpleLruFlush(SlruCtlctl,boolcheckpoint);
147147
externvoidSimpleLruTruncate(SlruCtlctl,intcutoffPage);
148-
externboolSlruScanDirectory(SlruCtlctl,intcutoffPage,booldoDeletions);
148+
149+
typedefbool (*SlruScanCallback) (SlruCtlctl,char*filename,intsegpage,
150+
void*data);
151+
externboolSlruScanDirectory(SlruCtlctl,SlruScanCallbackcallback,void*data);
152+
153+
/* SlruScanDirectory public callbacks */
154+
externboolSlruScanDirCbReportPresence(SlruCtlctl,char*filename,
155+
intsegpage,void*data);
156+
externboolSlruScanDirCbDeleteAll(SlruCtlctl,char*filename,intsegpage,
157+
void*data);
149158

150159
#endif/* SLRU_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp