问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

微信xlog文件可以删除吗?

发布网友 发布时间:2022-04-26 16:39

我来回答

2个回答

懂视网 时间:2022-04-10 20:44

一、问题
经常会在复制的时候遇到这样的问题,需要复制的xlog文件找不到了。那么xlog文件什么时候删除?又会删除多少保留多少个xlog文件?都有哪些xlog文件需要保留?本文将从原理上对这些问题进行解读。

二、原理
每次checkpoint后都会根据需要删除或者回收不再需要的xlog文件。
1、首先估算两次checkpoint之间产生的xlog量,根据这个量会计算出未来最大的日志文件号从而回收不再需要的文件将其重命名为未来即将使用的日志文件号:
1.1 UpdateCheckPointDistanceEstimate估算checkpoint之前产生的日志量:
?? ?if (CheckPointDistanceEstimate < nbytes)//上次估算量比这次估算的小,则更新为这次的估算量
?? ??? ?CheckPointDistanceEstimate = nbytes;
?? ?else//否则,适当增加
?? ??? ?CheckPointDistanceEstimate =(0.90 CheckPointDistanceEstimate + 0.10 (double) nbytes);
2、计算上一次checkpoint时,所在的文件段号_logSegNo:
?? ?XLByteToSeg(PriorRedoPtr, _logSegNo);
3、计算需要保留的文件段号:从该段号_logSegNo开始的文件都不能被删除,之前的需要删除或回收:根据备机请求以及wal_keep_segments计算KeepLogSeg(recptr, &_logSegNo);
技术图片

4、遍历pg_wal目录下的所有xlog文件,进行删除:RemoveOldXlogFiles
4.1 跳过时间线进行比较,如果pg_wal目录下的文件比_logSegNo小则被删除或回收。那么什么条件下次被回收?
--RemoveXlogFile
4.2 计算回收文件重命名的未来最大文件段号recycleSegNo:
?? ?1)如果本次是第一次checkpoint,则未来最大段号recycleSegNo=当前段文件号+10
?? ?2)否则调用函数XLOGfileslop计算:
?? ??? ?2.1 估算下一次checkpoint结束时日志位置:
?? ??? ??? ?distance=(2.0+checkpoint_completion_target)CheckPointDistanceEstimate
?? ??? ??? ?distance
=1.1
?? ??? ??? ?recycleSegNo = (XLogSegNo) ceil(((double) PriorRedoPtr + distance) / XLOG_SEG_SIZE);
?? ??? ?2.2 minSegNo = PriorRedoPtr / XLOG_SEG_SIZE + ConvertToXSegs(min_wal_size_mb) - 1;
?? ??? ??? ?maxSegNo = PriorRedoPtr / XLOG_SEG_SIZE + ConvertToXSegs(max_wal_size_mb) - 1;
?? ??? ?2.3 if (recycleSegNo < minSegNo)
?? ??? ??? ??? ?recycleSegNo = minSegNo;
?? ??? ??? ?if (recycleSegNo > maxSegNo)
?? ??? ??? ??? ?recycleSegNo = maxSegNo;
4.3 如果当前段文件号endlogSegNo < recycleSegNo,则调用InstallXLogFileSegment进行回收:
?? ?1)在endlogSegNo和recycleSegNo之间找一个free slot num,即没有该段文件号的xlog文件
?? ?2)将需要删除的文件名命名为该free slot号的文件名
?? ?3)如果没有找到free slot则直接删除该文件
--RemoveXlogFile

三、代码流程
1、checkpoint顶层函数CreateCheckPoint:


CreateCheckPoint:
 XLogCtlInsert *Insert = &XLogCtl->Insert;//标识插入的位置
 curInsert = XLogBytePosToRecPtr(Insert->CurrBytePos);//添加页头大小后的位置
 //(((curInsert) % XLOG_BLCKSZ == 0) ? 0 : (XLOG_BLCKSZ - (curInsert) % XLOG_BLCKSZ))
 freespace = INSERT_FREESPACE(curInsert);//curInsert所在页是否有空闲空间
 if (freespace == 0){
 if (curInsert % XLogSegSize == 0)//正好一个xlog段文件用完,即将使用下一个段文件,则跳过36字节
  curInsert += SizeOfXLogLongPHD;//36字节
 else//xlog段文件中正好一页用完,即将使用下一页,则跳过20字节
  curInsert += SizeOfXLogShortPHD;//20字节
 }
 checkPoint.redo = curInsert;//xlog文件上,实际的即将插入位置
 RedoRecPtr = XLogCtl->Insert.RedoRecPtr = checkPoint.redo;
 ...
 //插入checkpoint记录后末尾位置,即下一个xlog开始的位置
 recptr = XLogInsert(RM_XLOG_ID,shutdown ? XLOG_CHECKPOINT_SHUTDOWN :XLOG_CHECKPOINT_ONLINE);
 ...
 PriorRedoPtr = ControlFile->checkPointCopy.redo;//上一次checkpoint的起始位置
 ...
 if (PriorRedoPtr != InvalidXLogRecPtr){//上一次checkpoint开始到这一次checkpoint开始,产生的XLOG大小为入参
 /*
 CheckPointDistanceEstimate:
 1、CheckPointDistanceEstimate<RedoRecPtr - PriorRedoPtr时:RedoRecPtr - PriorRedoPtr
 2、CheckPointDistanceEstimate>=RedoRecPtr - PriorRedoPtr时:0.9*CheckPointDistanceEstimate+0.1*(RedoRecPtr - PriorRedoPtr)
 */
 UpdateCheckPointDistanceEstimate(RedoRecPtr - PriorRedoPtr);
 //_logSegNo = (PriorRedoPtr) / XLogSegSize
 XLByteToSeg(PriorRedoPtr, _logSegNo);
 KeepLogSeg(recptr, &_logSegNo);
 _logSegNo--;
 RemoveOldXlogFiles(_logSegNo, PriorRedoPtr, recptr);

2、两个宏定义

#define UsableBytesInPage (XLOG_BLCKSZ - SizeOfXLogShortPHD)//注意:不是文件第一页
#define UsableBytesInSegment ((XLOG_SEG_SIZE / XLOG_BLCKSZ) * UsableBytesInPage - (SizeOfXLogLongPHD - SizeOfXLogShortPHD))

3、函数XLogBytePosToRecPtr

static XLogRecPtr
XLogBytePosToRecPtr(uint64 bytepos)
{

 //bytepos:不包括xlog页的页头等额外字节占用的大小
 fullsegs = bytepos / UsableBytesInSegment;
 bytesleft = bytepos % UsableBytesInSegment;
 /*
 1、如果bytesleft < XLOG_BLCKSZ-32,则表示定位到第一页上,则文件偏移值跳过第一页页头大小
 2、如果bytesleft >= XLOG_BLCKSZ-32,则表示定位不是第一页
 */
 if (bytesleft < XLOG_BLCKSZ - SizeOfXLogLongPHD){
 /* fits on first page of segment */
 seg_offset = bytesleft + SizeOfXLogLongPHD;
 }else{
 /* account for the first page on segment with long header */
 seg_offset = XLOG_BLCKSZ;//先跳过第一页
 bytesleft -= XLOG_BLCKSZ - SizeOfXLogLongPHD;//去掉第一页存放XLOG的大小

 fullpages = bytesleft / UsableBytesInPage;//剩下的需要几个页
 bytesleft = bytesleft % UsableBytesInPage;//剩下的偏移
 // 文件偏移=第一页大小+剩下的几个页大小+剩下的偏移+最后一页的页头
 seg_offset += fullpages * XLOG_BLCKSZ + bytesleft + SizeOfXLogShortPHD;
 }
 //result=(fullsegs) * XLOG_SEG_SIZE + seg_offset
 XLogSegNoOffsetToRecPtr(fullsegs, seg_offset, result);
 return result;
}

4、函数KeepLogSeg

static void
KeepLogSeg(XLogRecPtr recptr, XLogSegNo *logSegNo)
{
 //segno为当前xlog即将插入位置在第几个文件上
 XLByteToSeg(recptr, segno);
 //XLogCtl->replicationSlotMinLSN;备机上请求预留的最小值?
 keep = XLogGetReplicationSlotMinimumLSN();
 /* compute limit for wal_keep_segments first */
 if (wal_keep_segments > 0){
 /* 
 首先计算wal_keep_segments得到的限制:
 1、比如wal_keep_segments值是10,若当前insert的位置的文件号segno为5,那么向前推进到1
 2、否则向前推进wal_keep_segments后的segno前的可删除
 */
 if (segno <= wal_keep_segments)
  segno = 1;
 else
  segno = segno - wal_keep_segments;
 }

 /* then check whether slots limit removal further */
 //计算slots限制,如果其算出的值小于wal_keep_segments计算出的值,则需要使用slotSegNo,slots还有用,不能删除
 if (max_replication_slots > 0 && keep != InvalidXLogRecPtr){
 XLByteToSeg(keep, slotSegNo);
 if (slotSegNo <= 0)
  segno = 1;
 else if (slotSegNo < segno)
  segno = slotSegNo;
 }

 /* don‘t delete WAL segments newer than the calculated segment */
 if (segno < *logSegNo)
 *logSegNo = segno;
 //note:
 //如果计算出的segno比上次checkpoint时的文件号logSegNo还有小,则取这次计算的segno
 //如果计算出的segno比上次checkpoint时的文件号logSegNo大,则取上次checkpoint时的文件号。
 //因为恢复时如果是主机,读取最新checkpoint记录失败后,会读取上一次checkpoint记录,如果上次checkpoint的文件被删除,这里就读取不到记录了
}
5、函数RemoveOldXlogFiles

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;
    }

  • PostgreSQL如何删除不使用的xlog文件

    标签:new   oca   rabl   with   whether   segment   tps   nim   install   

    热心网友 时间:2022-04-10 17:52

    很多人会误以为xlog文件是.log(日志)文件,认为可以删除,但事实并非如此

    想要了解xlog文件是否可以删除,首先需要知道xlog是什么文件。
    xlog文件并不是一般的log日志文本文件,而是一种语音通话记录文件或者说是手机录音文件,但它又不是普通的音频格式,因此我们一般很难打开它,手机与电脑都无法直接打开该文件。

    在微信中,如果我们删除手机微信文件夹中的xlog文件,会导致微信中之前的语音记录丢失,它相当于QQ聊天记录文件,应该属于一种加密文件,普通文本或者影音工具无法直接打开,仅能在微信中通过查看语音记录播放打开。
    现在再来回答xlog文件可以删除吗,是不是就很简单呢?
    对于用户来说,xlog文件并不是普通的log文本文件,而是一种特殊的语音通话记录文件,微信中删除了此文件,会导致此前的微信语音聊天记录丢失,如果微信语录记录不重要或者已经备份,那么这个文件是可以删除的,如果没有备份需要保留微信语音聊天记录,这个xlog文件就不能删除了。
    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
    租临时演员在婚礼中的效果 eva破买觉醒版的还是普通版的 TAT EVA初号机模型 公司以员工绩效罚款违法吗 张衡怎么造句 地动仪怎么造句 一般情况下,企业对程序员素质要求中不包括( )。 做一个程序员应该具备哪些素质? 自己家里是什么意思? 你家里都是什么意思啊 移动充电宝停电能弹出来吗? 扫码充电宝在本机没有插电的情况下能还进去吗? 充电宝没电了怎么办 有用户投诉共享充电宝没电客服怎么回复 早春呈水部张十八员外表达了诗人怎样的思想感情 淘宝海外代购怎么开店 求助想做海外代购怎么找货源? 带壳生蚝高压锅蒸多久 生蚝需要把两边的肉都要割断她吗 泡生蚝肉的水变干净了是不是蚝死了? 蚝肉为什么要用水浸泡 五分熟牛排怎么煎 牛排五分熟煎多长时间 二加两笔的字有哪些? “二”字加两笔有多少个字 “二”再加两笔能组成哪些字 “二”字加两笔,能写出多少汉字 “二”字上加两笔,有些什么字? “二”字加两笔能组成哪些新字? 二字加两笔可以组成哪些字 二字加两笔能组成多少个字? 手机发现 不少 .xlog 文件 抽动症有哪些具体的表现? 抽动症症状有哪些 ? 抽动症的病因有什么? 抽动症的症状都有什么? 抽动症有哪几种类型? 抽动症是怎样形成的? 抽动症是怎么引起的 抽动症的定义都有哪些? 什么是抽动症?得了抽动症怎么办? 抽动症有些什么行为举止 学游戏开发怎么找工作,在哪上班 现在学习电竞找工作好找吗? 对于学游戏策划的来说,找工作的时候应该注意些什么? 在游戏原画行业怎么找一份工作这么难? 学游戏原画找工作容易吗? 游戏类学习哪个方向比较好找工作呢? 大学生找工作难吗~~~ 学的技术是计算机的,但是想往游戏发展 学习游戏开发好找工作吗 在北大青鸟学游戏开发,毕业后好找工作吗?