iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >XLOG段文件跳号现象分析
  • 257
分享到

XLOG段文件跳号现象分析

2024-04-02 19:04:59 257人浏览 泡泡鱼
摘要

一、原理 当执行promote 时,我们经常看到的结果是:生成一个新 XLOG 文件,名称为:时间线加 1 ,段文件名为之前的段文件号。那么做这个动作的时机是什么时候呢?是否只有这一种现象,会不会

一、原理

当执行promote 时,我们经常看到的结果是:生成一个新 XLOG 文件,名称为:时间线加 1 ,段文件名为之前的段文件号。那么做这个动作的时机是什么时候呢?是否只有这一种现象,会不会有其他现象?先透露下,当执行 promote 动作前,最后一个 XLOG 日志是 SWITCH 时,段文件号会加 1 。下面我们对其流程做详细分析,并通过 gdb 理解其原理。

     做这个动作的函数是 exitArcHiveRecovery , 调用时机为startup 进程退出的时刻,见堆栈:

Breakpoint 1, exitArchiveRecovery (endTLI=1, endOfLog=23053968) at xlog.c:5475
5475  InArchiveRecovery = false;
(gdb) bt
#0  exitArchiveRecovery (endTLI=1, endOfLog=23053968) at xlog.c:5475
#1  0x0815fc4b in StartupXLOG () at xlog.c:7460
#2  0x083Dbc56 in StartupProceSSMain () at startup.c:207
#3  0x08173cbf in AuxiliaryProcessMain (arGC=2, argv=0xbfa8a2f4) at bootstrap.c:451
#4  0x083dab93 in StartChildProcess (type=StartupProcess) at postmaster.c:5386
#5  0x083d5d86 in PostmasterMain (argc=1, argv=0xa22e7e8) at postmaster.c:1369
#6  0x0831c76c in main (argc=1, argv=0xa22e7e8) at main.c:228

具体代码行为恢复完成之后:

StartupXLOG-> 读取 checkpoint-> 恢复 ->exitArchiveRecovery : EndOfLog 为当前回放日志最后的位置, EndOfLogTLI 为当前退出时回放日志的时间线。当 data 目录下有 standby.signal 文件即该机器是备时 ArchiveRecoveryRequested 为 TRUE 。

XLOG段文件跳号现象分析

exitArchiveRecovery 函数调用流程如下:首先通过 endOfLog 即回放最后的位置计算出段文件日志号: endLogSegNo= (endOfLog - 1) / (wal_segment_size) ; startLogSegNo= endOfLog / (wal_segment_size) 。如果 endLogSegNo 等于 startLogSegNo ,表示回放位置为文件中间位置,在调用 XLogFileCopy 生成一个新文件,并将上个 XLOG 文件内容拷贝到新文件中;段文件号相同,时间线加 1 。如果 endLogSegNo 不等于 startLogSegNo ,即回放位置正好是文件大小的末尾处,或者正好是 SWITCH 这个日志,那么调用 XLogFileInit 函数进行初始化文件:

XLOG段文件跳号现象分析

XlogFileCopy 函数调用:调用 XLogFilePath 函数获取源 XLOG 文件名, OpenTransientFile 打开该文件,创建并打开一个临时 XLOG 文件 pg_wal/xlogtemp.pid , pid 为 startup 进程的 ID 号。 sizeof(buffer) 为一页大小 8192 字节,从源文件每次 read 一页数据并将之 write 到 xlogtemp 文件,最后一页数据如果不够 8192 字节,则有多少读取多少并写入文件。当文件拷贝完成后,执行一次 sync 。最后调用 InstallXLogFileSegment 将文件重命名。

XLOG段文件跳号现象分析

InstallXLogFileSegment 函数: XlogFileCopy 调用时, find_free 为 false ,直接将文件重命名为时间线加 1 的文件名; XLogFileInit 调用时为 TRUE ,将段文件号加 1 后(注意这里不是加 1 ,是因为正好是文件末尾,求得的是下一个段文件号,只是现象上看是加 1 ),重命名为时间线加 1 的文件,会先 stat 下这个文件,该流程返回值是 2 即该文件不存在,所以不会再将 segno 加 1 ,直接跳过虚框内的步骤,进入重命名流程 durable_like_or_rename 。

XLOG段文件跳号现象分析

XLogFileInit 函数的调用:首先获取新文件的文件名,即时间线加 1 ,段文件名为原文件名,本次 exitArchiveRecovery 函数的调用流程中, use_existent 为 TRUE 所以会视图打开该文件。当然因为该文件不存在所以打开失败。然后创建并打开一个临时文件 xlogtemp.pid ,将该文件全部清 0 ,最后 sync 。之后调用 InstallXLogFileSegment 函数重命名。最后打开新文件以供之后使用。

XLOG段文件跳号现象分析

二、GDB跟踪-lsn位置在xlog文件中间

1 、进入第一个断点,即函数入口

Breakpoint 1, exitArchiveRecovery (endTLI=1, endOfLog=23053968) at xlog.c:5475
5475  InArchiveRecovery = false;
(gdb) bt
#0  exitArchiveRecovery (endTLI=1, endOfLog=23053968) at xlog.c:5475
#1  0x0815fc4b in StartupXLOG () at xlog.c:7460
#2  0x083dbc56 in StartupProcessMain () at startup.c:207
#3  0x08173cbf in AuxiliaryProcessMain (argc=2, argv=0xbfa8a2f4) at bootstrap.c:451
#4  0x083dab93 in StartChildProcess (type=StartupProcess) at postmaster.c:5386
#5  0x083d5d86 in PostmasterMain (argc=1, argv=0xa22e7e8) at postmaster.c:1369
#6  0x0831c76c in main (argc=1, argv=0xa22e7e8) at main.c:228

2 、接着计算出段文件号,这两个值相等,即执行 promote 时, lsn 最后位置在文件中间。

5507  if (endLogSegNo == startLogSegNo)
(gdb) 
5517       XLogSegmentOffset(endOfLog, wal_segment_size));
(gdb) p endLogSegNo
$1 = 1
(gdb) p startLogSegNo
$2 = 1

3 、 lsn 在文件中间,调用 XlogFileCopy , upto 为 lsn 在最后文件的偏移

XLogFileCopy (destsegno=1, srcTLI=1, srcsegno=1, upto=6276752) at xlog.c:3405
3405  XLogFilePath(path, srcTLI, srcsegno, wal_segment_size);
(gdb) p 23053968%(16*1024*1024)
$3 = 6276752

4 、打开原文件 00000001 0000000000000001 ,以及临时文件 xlogtemp.29683

3406  srcfd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
(gdb) p path
$4 = "pg_wal/00000001", '0' <repeats 15 times>, "1", '\000' <repeats 869 times>, "\b\221\250\277gmE\b\004\005ĥ\000\000\000\001\030\221\250\277\bnE\b\004\005ĥ\000\000\000\001X\221\250\277$\207E\b\004\005ĥ\000\000\000\001", '\000' <repeats 13 times>"\270, \004\246X\221\250\277\000\000\000\000\000\000\000 \000\270\004\000\000\000\000\000\000\000\000\000\n\000\000\000\000\270\004\246\270\221\250\277dd\025\b\000\005ĥ\352\320a\b\341\n\000\000~\016b\b\000\000\000"
(gdb) n
(gdb) p tmppath
$5 = "pg_wal/xlogtemp.29683", '\000' <repeats 1002 times>
(gdb) n
3420  fd = OpenTransientFile(tmppath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY);

5 、循环进行拷贝,一次拷贝一页 8192 字节

3429  for (nbytes = 0; nbytes < wal_segment_size; nbytes += sizeof(buffer))
(gdb) p sizeof(buffer)
$6 = 8192
(gdb) n
3433   nread = upto - nbytes;
(gdb) 
3439   if (nread < sizeof(buffer))
(gdb) p nread
$7 = 6276752
(gdb) p 6276752/8192
$8 = 766

6 、 InstallXLogFileSegment 函数重命名, path 为 000000020000000000000001

Breakpoint 2, InstallXLogFileSegment (segno=0xbfa86968, tmppath=0xbfa88974 "pg_wal/xlogtemp.29683", find_free=false, max_segno=0, use_lock=false) at xlog.c:3545
3545  XLogFilePath(path, ThisTimeLineID, *segno, wal_segment_size);
 
(gdb) p path
$10 = "pg_wal/00000002", '0' <repeats 15 times>, "1\000 \212\022\251\322\"[\000\000\000\000\000\277 `\b\204\211\250\277\347e\250\277\005\000\000\000\003\000\000\000 NҬ\003\000\000\000\002\000\000\000\005\000\000\000;\000\000\000\000\000\000\000\030f\250\277\206\032`\b\000\000\000\000\350h\250\277\350h\250\277\350h\250\277\240.{\262d\000\000\000\363s\000\000\000\000\000\000\240\020[\264\003\000\000\000\000\000\000\000\003\000\000\000\240\362:\266\003\000\000\000\220\251t\267\003\000\000\000\240\324\032\270\003\000\000\000\220\213T\271\003\000\000\000 \361\003\272\003\000\000\000\020\250=\273\003\000\000\000 \323\343\273\322\"[29683\000\000\000\000\n", '\000' <repeats 15 times>, "\001\000\000\000\373\333y\b\005\000\000\000\000\000\000\000\001\000\000\000\270\240\250\277\310h\250\277\225\017`\b\363s\000\000\000\000\000\000d", '\000' <repeats 27 times>"\350"...
(gdb) n

7 、将临时文件重命名为 000000020000000000000001

3579  if (durable_link_or_rename(tmppath, path, LOG) != 0)
(gdb) p path
$11 = "pg_wal/00000002", '0' <repeats 15 times>, "1\000 \212\022\251\322\"[\000\000\000\000\000\277 `\b\204\211\250\277\347e\250\277\005\000\000\000\003\000\000\000 NҬ\003\000\000\000\002\000\000\000\005\000\000\000;\000\000\000\000\000\000\000\030f\250\277\206\032`\b\000\000\000\000\350h\250\277\350h\250\277\350h\250\277\240.{\262d\000\000\000\363s\000\000\000\000\000\000\240\020[\264\003\000\000\000\000\000\000\000\003\000\000\000\240\362:\266\003\000\000\000\220\251t\267\003\000\000\000\240\324\032\270\003\000\000\000\220\213T\271\003\000\000\000 \361\003\272\003\000\000\000\020\250=\273\003\000\000\000 \323\343\273\322\"[29683\000\000\000\000\n", '\000' <repeats 15 times>, "\001\000\000\000\373\333y\b\005\000\000\000\000\000\000\000\001\000\000\000\270\240\250\277\310h\250\277\225\017`\b\363s\000\000\000\000\000\000d", '\000' <repeats 27 times>"\350"...
(gdb) n

三、GDB跟踪-lsn位置在xlog文件尾或最后一个为SWITCH

1 、 lsn 位于文件尾,调用函数 XLogFileInit

Breakpoint 3, exitArchiveRecovery (endTLI=3, endOfLog=50331648) at xlog.c:5475
5475  InArchiveRecovery = false;
(gdb) n
5480  UpdateMinRecoveryPoint(InvalidXLogRecPtr, true);
(gdb) 
5486  if (readFile >= 0)
(gdb) 
5488   close(readFile);
(gdb) 
5489   readFile = -1;
(gdb) 
5498  XLByteToPrevSeg(endOfLog, endLogSegNo, wal_segment_size);
(gdb) 
5499  XLByteToSeg(endOfLog, startLogSegNo, wal_segment_size);
(gdb) 
5507  if (endLogSegNo == startLogSegNo)
(gdb) 
5525   bool  use_existent = true;
(gdb) 
5528   fd = XLogFileInit(startLogSegNo, &use_existent, true);
(gdb)

2 、 path 为 000000040000000000000003, 该文件不存在

Breakpoint 2, XLogFileInit (logsegno=3, use_existent=0xbfbd366f, use_lock=true) at xlog.c:3216
3216  XLogFilePath(path, ThisTimeLineID, logsegno, wal_segment_size);
(gdb) n
3221  if (*use_existent)
(gdb) p path
$1 = "pg_wal/00000004", '0' <repeats 15 times>, "3\000\000\000\000\000\346!`\bX6\275\277\060\000\000\000\a\000\000\000\030\333\177\t\364\257`\000\270\331\177\t\000\000\000\000\a\000\000\000\000\224M\000\000\000\000\000h3\275\277: `\b4\000\000\000\330\065\275\277\330\065\275\277\000\000\000\000h3\275\277L\274M\000\004\000\000\000\000\000\000\000?\000\000\000\a\000\000\000\b3\275\277\206\032`\b\000\000\000\000\330\065\275\277\330\065\275\277\330\065\275\277\373\210}\tX\025w\b\004\000\000\000\000\000\000\000\177\323a\bX\000\000\000\000\000\000\000\b", '\000' <repeats 19 times>, "\b\000\000\000\000\000\000\000\060", '\000' <repeats 11 times>, "recovering 00000\322\"[\000\000\270\004\246\277 `\b`6\275\277\360\253a\b\b", '\000' <repeats 11 times>...
(gdb) n
3223   fd = BasicOpenFile(path, O_RDWR | PG_BINARY | get_sync_bit(sync_method));
(gdb) 
3224   if (fd < 0)
(gdb) 
3226    if (errno != ENOENT)
(gdb) p fd
$2 = -1
(gdb) p errno
$3 = 2

3 、创建并打开临时文件,将 zbuffer.data 清 0 ,然后一页一页的将文件清 0

3243  snprintf(tmppath, MAXPGPATH, XLOGDIR "/xlogtemp.%d", (int) getpid());
(gdb)
3245  unlink(tmppath);
(gdb)
3248  fd = BasicOpenFile(tmppath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY);
(gdb)
3249  if (fd < 0)
(gdb)
3254  memset(zbuffer.data, 0, XLOG_BLCKSZ);
(gdb) p fd
$4 = 3
3269   for (nbytes = 0; nbytes < wal_segment_size; nbytes += XLOG_BLCKSZ)
(gdb)
3271    errno = 0;
(gdb)
3272    if (write(fd, zbuffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)

4 、进入 InstallXLogFileSegment 函数, 000000040000000000000003 文件 stat 失败,调用 durable_link_or_rename 重命名。

InstallXLogFileSegment (segno=0xbfbd0de0, tmppath=0xbfbd2de8 "pg_wal/xlogtemp.31765", find_free=true, max_segno=45, use_lock=true) at xlog.c:3550
3550  if (use_lock)
(gdb) n
3551   LWLockAcquire(ControlFileLock, LW_EXCLUSIVE);
(gdb)
3553  if (!find_free)
(gdb)
3561   while (stat(path, &stat_buf) == 0)
(gdb) p path
$5 = "pg_wal/00000004", '0' <repeats 15 times>, "3\000 \212\022\251\322\"[\000\000\000\000\000\277 `\b\370-\275\277W\n\275\277\005\000\000\000\003\000\000\000 NҬ\003\000\000\000\003\000\000\000\005\000\000\000;\000\000\000\000\000\000\000\210\n\275\277\206\032`\b\000\000\000\000X\r\275\277X\r\275\277X\r\275\277\240.{\262d\000\000\000\025|\000\000\000\000\000\000\240\020[\264\003\000\000\000\000\000\000\000\003\000\000\000\240\362:\266\003\000\000\000\220\251t\267\003\000\000\000\240\324\032\270\003\000\000\000\220\213T\271\003\000\000\000 \361\003\272\003\000\000\000\020\250=\273\003\000\000\000 \323\343\273\322\"[31765\000\000\000\000\n", '\000' <repeats 15 times>, "\001\000\000\000\373\333y\b\005\000\000\000\000\000\000\000\003\000\000\000(E\275\277\070\r\275\277\225\017`\b\025|\000\000\000\000\000\000"...
(gdb) n
3579  if (durable_link_or_rename(tmppath, path, LOG) != 0)
(gdb) p errno
$6 = 2
您可能感兴趣的文档:

--结束END--

本文标题: XLOG段文件跳号现象分析

本文链接: https://www.lsjlt.com/news/49708.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • XLOG段文件跳号现象分析
    一、原理 当执行promote 时,我们经常看到的结果是:生成一个新 XLOG 文件,名称为:时间线加 1 ,段文件名为之前的段文件号。那么做这个动作的时机是什么时候呢?是否只有这一种现象,会不会...
    99+
    2024-04-02
  • Linux文件执行中的锁定怪现象分析
    这篇文章将为大家详细讲解有关Linux文件执行中的锁定怪现象分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。linux下,一个可执行文件exe1正在执行中,rm &ndash;f可以将其删除,m...
    99+
    2023-06-13
  • VB.NET文件对象的示例分析
    这篇文章给大家分享的是有关VB.NET文件对象的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。VB.NET是一款由微软公司推出的基于.netframeworkSDK的一种语言。它的应用机制和Java相同,...
    99+
    2023-06-17
  • Oracle中相对文件号(RFN)和绝对文件号(AFN)的示例分析
    Oracle中相对文件号(RFN)和绝对文件号(AFN)的示例分析,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。大家都知道从Oracle8开始...
    99+
    2024-04-02
  • java指令重排现象两个阶段的示例分析
    这篇文章给大家分享的是有关java指令重排现象两个阶段的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。编译期指令重排解释型语言是在运行期间执行编译+运行动作,所以运行效率较编译型语言低。Java既可以作为...
    99+
    2023-06-29
  • React文件分段上传实现方法详解
    目录原理方案antd Upload文件分片MD5发送分片请求显示上传进度最近做了大文件(文件夹)分片上传的需求,记录一下。 原理 前端进行大文件分片上传的方案几乎都是利用Blob.p...
    99+
    2022-11-13
    React文件分段上传 React文件上传
  • 基于Apache组件分析对象池原理的实现案例分析
    目录一、设计与原理1、基础案例2、接口设计1.1 PooledObjectFactory 接口1.2 ObjectPool 接口1.3 PooledObject 接口3、运行原理二、...
    99+
    2024-04-02
  • pytorch教程resnet.py的实现文件源码分析
    目录调用pytorch内置的模型的方法解读模型源码Resnet.py包含的库文件该库定义了6种Resnet的网络结构每种网络都有训练好的可以直接用的.pth参数文件Resnet中大多...
    99+
    2024-04-02
  • JavaScript中实现大文件并行下载的示例分析
    小编给大家分享一下JavaScript中实现大文件并行下载的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在 JavaScript 中如何实现并发控制 这...
    99+
    2023-06-15
  • 怎么实现EXE文件解析远程代码执行漏洞的分析
    本篇文章为大家展示了怎么实现EXE文件解析远程代码执行漏洞的分析,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。下面的文章主要向大家阐述的是EXE文件解析远程代码执行漏洞的实际操作,以及对受影响系统的...
    99+
    2023-06-17
  • 基于python实现cdn日志文件导入mysql进行分析
    目录一、本文需求背景二、需求落地如下三、自定义查询一、本文需求背景 周六日出现CDN大量请求,现需要分析其请求频次与来源,查询是否存在被攻击问题。 本文以阿里云CDN日志作为辅助查询...
    99+
    2024-04-02
  • SpringBoot拦截器与文件上传实现方法与源码分析
    目录一、拦截器1、创建一个拦截器2、配置拦截器二、拦截器原理三、文件上传四、文件上传流程一、拦截器 拦截器我们之前在springmvc已经做过介绍了 大家可以看下【SpringMVC...
    99+
    2024-04-02
  • Java Mybatis框架Dao层的实现与映射文件以及核心配置文件详解分析
    目录Mybatis的Dao层实现传统开发方式代理开发方式MyBatis映射文件深入动态sql语句动态SQL之<if>动态SQL之<foreach>SQL片段抽...
    99+
    2024-04-02
  • 如何利用Python处理大数据中的对象文件,让数据分析更高效?
    在当今这个数据爆炸的时代,大数据处理已经成为了许多企业不可避免的任务。其中,大量的数据对象文件也是不可避免的存在。这些数据对象文件,比如Excel文件、CSV文件、JSON文件等,存储了大量的数据,这些数据往往需要经过提取、清洗、转换等处...
    99+
    2023-10-26
    对象 文件 大数据
  • 基于python怎么实现cdn日志文件导入mysql进行分析
    本篇内容主要讲解“基于python怎么实现cdn日志文件导入mysql进行分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“基于python怎么实现cdn日志文件导入mysql进行分析”吧!一、...
    99+
    2023-06-30
  • 利用pandas读取Excel文件,轻松实现数据导入与分析
    利用pandas读取Excel文件,轻松实现数据导入与分析 pandas是Python中用于数据分析的强大工具,它可以对各种格式的数据进行灵活高效的处理。在数据分析中,Excel是一种常用的数据格式,pandas提供了方便的接口...
    99+
    2024-01-19
    数据分析 Excel Pandas
  • Java Mybatis框架Dao层的实现与映射文件以及核心配置文件的示例分析
    Java Mybatis框架Dao层的实现与映射文件以及核心配置文件的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Mybatis的Dao层实现传统开发...
    99+
    2023-06-25
  • Python集成C#实现界面操作下载文件功能的示例分析
    这篇文章给大家分享的是有关Python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、这个功能是怎么样的我很熟悉用 C# & WinForm 的方式开发界面,现...
    99+
    2023-06-29
  • JavaScript基于Ajax实现不刷新在网页上动态显示文件内容的示例分析
    这篇文章主要介绍JavaScript基于Ajax实现不刷新在网页上动态显示文件内容的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!下面的JS代码是一个最基础的JS的ajax实...
    99+
    2024-04-02
  • SQLServer 错误 7903 表错误:在对象 ID O_ID,索引 ID I_ID,分区 ID PN_ID,列 ID C_ID 的 FileStream 目录中发现孤立文件“FILE”。 故障
    详细信息 Attribute 值 产品名称 SQL Server 事件 ID 7903 事件源 MSSQLSERVER 组件 SQLEngine 符号名称 DBCC2_FS_ORPHANED_FILE 消息...
    99+
    2023-11-05
    错误 孤立 分区
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作