PostgreSQL如何删除不使用的xlog文件(3)

static void
RemoveOldXlogFiles(XLogSegNo segno, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
{
//首先获取xlog目录
xldir = AllocateDir(XLOGDIR);
if (xldir == NULL)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open write-ahead log directory \"%s\": %m",
XLOGDIR)));

/*
 构建一个log文件名,用于判断,该文件之前的xlog可以删除。用不到时间线,所以可以使用0
 */
XLogFileName(lastoff, 0, segno);

while ((xlde = ReadDir(xldir, XLOGDIR)) != NULL){
    /* 忽略非xlog文件 */
    if (!IsXLogFileName(xlde->d_name) &&
        !IsPartialXLogFileName(xlde->d_name))
        continue;
    /*
    1、跳过时间线进行比较
    */
    if (strcmp(xlde->d_name + 8, lastoff + 8) <= 0){
        if (XLogArchiveCheckDone(xlde->d_name)){//如果没有开启归档:总是TRUE;否则,归档完成后才为TRUE
            /* Update the last removed location in shared memory first */
            //XLogCtl->lastRemovedSegNo = segno;
            UpdateLastRemovedPtr(xlde->d_name);
            RemoveXlogFile(xlde->d_name, PriorRedoPtr, endptr);
        }
    }
}

}

6、函数RemoveXlogFile

RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
{

XLByteToSeg(endptr, endlogSegNo);
if (PriorRedoPtr == InvalidXLogRecPtr)
    recycleSegNo = endlogSegNo + 10;
else
    recycleSegNo = XLOGfileslop(PriorRedoPtr);

snprintf(path, MAXPGPATH, XLOGDIR "/%s", segname);

if (endlogSegNo <= recycleSegNo &&
    lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&
    InstallXLogFileSegment(&endlogSegNo, path,
                          true, recycleSegNo, true))
{
    endlogSegNo++;
}else{
    rc = durable_unlink(path, LOG);
}

}

7、函数InstallXLogFileSegment

static bool
InstallXLogFileSegment(XLogSegNo segno, char tmppath,
bool find_free, XLogSegNo max_segno,
bool use_lock)
{
XLogFilePath(path, ThisTimeLineID, segno);
/

•We want to be sure that only one process does this at a time.
*/
if (use_lock)
LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);

if (!find_free)
{
/ Force installation: get rid of any pre-existing segment file /
durable_unlink(path, DEBUG1);//删除文件并持久化到磁盘
}else{
/ Find a free slot to put it in /
while (stat(path, &stat_buf) == 0){//获取文件信息并保存到stat_buf中,成功返回0
//在segno和max_segno之间找一个空闲的段号,即目录中没有这个段号的xlog文件
if ((segno) >= max_segno){
/ Failed to find a free slot within specified range /
if (use_lock)
LWLockRelease(ControlFileLock);
return false;
}
(segno)++;
XLogFilePath(path, ThisTimeLineID, segno);
}
}
if (durable_link_or_rename(tmppath, path, LOG) != 0){//将tmppath重命名为path并持久化
if (use_lock)
LWLockRelease(ControlFileLock);
/ durable_link_or_rename already emitted log message */
return false;
}
if (use_lock)
LWLockRelease(ControlFileLock);
return true;
}

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/0fc1fde7e66660927d6c939ec2a0a02d.html