Skip to content

Commit c732c3f

Browse files
committed
Fix unlinking of SLRU segments.
Commit dee663f intended to drop any queued up fsync requests before unlinking segment files, but missed a code path. Fix, by centralizing the forget-and-unlink code into a single function. Reported-by: Tomas Vondra <tomas.vondra@2ndquadrant.com> Discussion: https://postgr.es/m/20201104013205.icogbi773przyny5%40development
1 parent fac83db commit c732c3f

File tree

1 file changed

+18
-26
lines changed
  • src/backend/access/transam

1 file changed

+18
-26
lines changed

src/backend/access/transam/slru.c

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static int SlruSelectLRUPage(SlruCtl ctl, int pageno);
145145

146146
static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename,
147147
int segpage, void *data);
148-
static void SlruInternalDeleteSegment(SlruCtl ctl, char *filename);
148+
static void SlruInternalDeleteSegment(SlruCtl ctl, int segno);
149149

150150
/*
151151
* Initialization of shared memory
@@ -1298,19 +1298,28 @@ restart:;
12981298
}
12991299

13001300
/*
1301-
* Delete an individual SLRU segment, identified by the filename.
1301+
* Delete an individual SLRU segment.
13021302
*
13031303
* NB: This does not touch the SLRU buffers themselves, callers have to ensure
13041304
* they either can't yet contain anything, or have already been cleaned out.
13051305
*/
13061306
static void
1307-
SlruInternalDeleteSegment(SlruCtl ctl, char *filename)
1307+
SlruInternalDeleteSegment(SlruCtl ctl, int segno)
13081308
{
13091309
char path[MAXPGPATH];
13101310

1311-
snprintf(path, MAXPGPATH, "%s/%s", ctl->Dir, filename);
1312-
ereport(DEBUG2,
1313-
(errmsg("removing file \"%s\"", path)));
1311+
/* Forget any fsync requests queued for this segment. */
1312+
if (ctl->sync_handler != SYNC_HANDLER_NONE)
1313+
{
1314+
FileTag tag;
1315+
1316+
INIT_SLRUFILETAG(tag, ctl->sync_handler, segno);
1317+
RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true);
1318+
}
1319+
1320+
/* Unlink the file. */
1321+
SlruFileName(ctl, path, segno);
1322+
ereport(DEBUG2, (errmsg("removing file \"%s\"", path)));
13141323
unlink(path);
13151324
}
13161325

@@ -1322,7 +1331,6 @@ SlruDeleteSegment(SlruCtl ctl, int segno)
13221331
{
13231332
SlruShared shared = ctl->shared;
13241333
int slotno;
1325-
char path[MAXPGPATH];
13261334
bool did_write;
13271335

13281336
/* Clean out any possibly existing references to the segment. */
@@ -1364,23 +1372,7 @@ SlruDeleteSegment(SlruCtl ctl, int segno)
13641372
if (did_write)
13651373
goto restart;
13661374

1367-
snprintf(path, MAXPGPATH, "%s/%04X", ctl->Dir, segno);
1368-
ereport(DEBUG2,
1369-
(errmsg("removing file \"%s\"", path)));
1370-
1371-
/*
1372-
* Tell the checkpointer to forget any sync requests, before we unlink the
1373-
* file.
1374-
*/
1375-
if (ctl->sync_handler != SYNC_HANDLER_NONE)
1376-
{
1377-
FileTag tag;
1378-
1379-
INIT_SLRUFILETAG(tag, ctl->sync_handler, segno);
1380-
RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true);
1381-
}
1382-
1383-
unlink(path);
1375+
SlruInternalDeleteSegment(ctl, segno);
13841376

13851377
LWLockRelease(shared->ControlLock);
13861378
}
@@ -1413,7 +1405,7 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data)
14131405
int cutoffPage = *(int *) data;
14141406

14151407
if (ctl->PagePrecedes(segpage, cutoffPage))
1416-
SlruInternalDeleteSegment(ctl, filename);
1408+
SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT);
14171409

14181410
return false; /* keep going */
14191411
}
@@ -1425,7 +1417,7 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data)
14251417
bool
14261418
SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data)
14271419
{
1428-
SlruInternalDeleteSegment(ctl, filename);
1420+
SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT);
14291421

14301422
return false; /* keep going */
14311423
}

0 commit comments

Comments
 (0)