Fix unlinking of SLRU segments.
Commit dee663f7 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
This commit is contained in:
parent
fac83dbd6f
commit
c732c3f8c1
@ -145,7 +145,7 @@ static int SlruSelectLRUPage(SlruCtl ctl, int pageno);
|
|||||||
|
|
||||||
static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename,
|
static bool SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename,
|
||||||
int segpage, void *data);
|
int segpage, void *data);
|
||||||
static void SlruInternalDeleteSegment(SlruCtl ctl, char *filename);
|
static void SlruInternalDeleteSegment(SlruCtl ctl, int segno);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialization of shared memory
|
* Initialization of shared memory
|
||||||
@ -1298,19 +1298,28 @@ restart:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete an individual SLRU segment, identified by the filename.
|
* Delete an individual SLRU segment.
|
||||||
*
|
*
|
||||||
* NB: This does not touch the SLRU buffers themselves, callers have to ensure
|
* NB: This does not touch the SLRU buffers themselves, callers have to ensure
|
||||||
* they either can't yet contain anything, or have already been cleaned out.
|
* they either can't yet contain anything, or have already been cleaned out.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
SlruInternalDeleteSegment(SlruCtl ctl, char *filename)
|
SlruInternalDeleteSegment(SlruCtl ctl, int segno)
|
||||||
{
|
{
|
||||||
char path[MAXPGPATH];
|
char path[MAXPGPATH];
|
||||||
|
|
||||||
snprintf(path, MAXPGPATH, "%s/%s", ctl->Dir, filename);
|
/* Forget any fsync requests queued for this segment. */
|
||||||
ereport(DEBUG2,
|
if (ctl->sync_handler != SYNC_HANDLER_NONE)
|
||||||
(errmsg("removing file \"%s\"", path)));
|
{
|
||||||
|
FileTag tag;
|
||||||
|
|
||||||
|
INIT_SLRUFILETAG(tag, ctl->sync_handler, segno);
|
||||||
|
RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlink the file. */
|
||||||
|
SlruFileName(ctl, path, segno);
|
||||||
|
ereport(DEBUG2, (errmsg("removing file \"%s\"", path)));
|
||||||
unlink(path);
|
unlink(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1322,7 +1331,6 @@ SlruDeleteSegment(SlruCtl ctl, int segno)
|
|||||||
{
|
{
|
||||||
SlruShared shared = ctl->shared;
|
SlruShared shared = ctl->shared;
|
||||||
int slotno;
|
int slotno;
|
||||||
char path[MAXPGPATH];
|
|
||||||
bool did_write;
|
bool did_write;
|
||||||
|
|
||||||
/* Clean out any possibly existing references to the segment. */
|
/* Clean out any possibly existing references to the segment. */
|
||||||
@ -1364,23 +1372,7 @@ restart:
|
|||||||
if (did_write)
|
if (did_write)
|
||||||
goto restart;
|
goto restart;
|
||||||
|
|
||||||
snprintf(path, MAXPGPATH, "%s/%04X", ctl->Dir, segno);
|
SlruInternalDeleteSegment(ctl, segno);
|
||||||
ereport(DEBUG2,
|
|
||||||
(errmsg("removing file \"%s\"", path)));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Tell the checkpointer to forget any sync requests, before we unlink the
|
|
||||||
* file.
|
|
||||||
*/
|
|
||||||
if (ctl->sync_handler != SYNC_HANDLER_NONE)
|
|
||||||
{
|
|
||||||
FileTag tag;
|
|
||||||
|
|
||||||
INIT_SLRUFILETAG(tag, ctl->sync_handler, segno);
|
|
||||||
RegisterSyncRequest(&tag, SYNC_FORGET_REQUEST, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink(path);
|
|
||||||
|
|
||||||
LWLockRelease(shared->ControlLock);
|
LWLockRelease(shared->ControlLock);
|
||||||
}
|
}
|
||||||
@ -1413,7 +1405,7 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data)
|
|||||||
int cutoffPage = *(int *) data;
|
int cutoffPage = *(int *) data;
|
||||||
|
|
||||||
if (ctl->PagePrecedes(segpage, cutoffPage))
|
if (ctl->PagePrecedes(segpage, cutoffPage))
|
||||||
SlruInternalDeleteSegment(ctl, filename);
|
SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT);
|
||||||
|
|
||||||
return false; /* keep going */
|
return false; /* keep going */
|
||||||
}
|
}
|
||||||
@ -1425,7 +1417,7 @@ SlruScanDirCbDeleteCutoff(SlruCtl ctl, char *filename, int segpage, void *data)
|
|||||||
bool
|
bool
|
||||||
SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data)
|
SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data)
|
||||||
{
|
{
|
||||||
SlruInternalDeleteSegment(ctl, filename);
|
SlruInternalDeleteSegment(ctl, segpage / SLRU_PAGES_PER_SEGMENT);
|
||||||
|
|
||||||
return false; /* keep going */
|
return false; /* keep going */
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user