设为首页 收藏本站
查看: 1212|回复: 0

[经验分享] postgresql集群方案hot standby初级测试(四)——xlog详细解释header

[复制链接]

尚未签到

发表于 2016-11-21 07:27:23 | 显示全部楼层 |阅读模式
  xlog日志header部分详解
  前些天,做了些实验,也确实能够证明手动同步xlog数据是可行性的,为了更深入的研究,我觉得研究下xlog的源码,并且打开xlog的二进制文件,读一读它里面的内容。
  

  本文来自:http://blog.csdn.net/lengzijian/article/details/7836402
  

  首先来看下xlog日志的结构图:
   DSC0000.png

  从上到下观察下:
  xlog日志文件命名:
  文件名 = 时间线 + 日志文件号(logid) + 段号(segmented)
      分为三部分,每个部分由8个16进制字符组成,时间线由1开始,日志文件号和段号由0开始,所以在系统中第一个事务日志文件名为:000000010000000000000000
  
     一个xlog文件日志备有256个段组成,每个段大小为16M,当最近的文件名有000000010000000000000000变为000000010000000100000000时,实际增加了256个段文件,但是逻辑上只增加了一个xlog日志文件。
  
  每一个段文件又分为很多页面,每个一面的大小为一个块的大小:
  include/pg_config.h:
  #defineXLOG_BLCKSZ 8192 //块大小
  //页面个数 = 16M / 8192bit = 2048
  
  对于每一个日志页面,需要在器头部写一个头部信息XLogPageHeaderData,数据结构如下:
  include/access/xlog_internal.h
  
  typedef struct XLogPageHeaderData
  {
   uint16 xlp_magic; /* 校验位 */                                                
   uint16 xlp_info; /* 标志位 */
   TimeLineID xlp_tli; /* 页面第一条记录的时间序列 */
   XLogRecPtr xlp_pageaddr; /* XLOG 页面首地址 */
  } XLogPageHeaderData;
  

  其中标志位xlp_info只使用最低两位“01”或者“10”或者11:
  “01”表明该页的第一个XLOG记录着上一个页的最后一个XLOG记录,这样的记录会接在一个XLogContRecord结构体之后;
  “10”表明该页的头部是一个长头部,既该页是XLOG段文件的首页;
  

  这样头部标志位会有三种状态:
  /* 如果记录跨越两个页面,这只该标志位到新的页面 */
  #define XLP_FIRST_IS_CONTRECORD 0x0001                                         
  /*这里就是之前说过的表示该页是xlog段文件的首页 */
  #define XLP_LONG_HEADER 0x0002
  /* 表示既是首页也是contrecore*/
  #define XLP_ALL_FLAGS                0x0003
  

  长头部结构体如下:
  typedef struct XLogLongPageHeaderData                                                   
  {
   XLogPageHeaderData std; /* 头部信息 */
   uint64 xlp_sysid; /* pg_control中的系统标识符 */
   uint32 xlp_seg_size;   /* 校验位,段的尺寸*/
   uint32 xlp_xlog_blcksz; /* 校验位,块的尺寸 */
  } XLogLongPageHeaderData;
  
      要注意的地方,对于一条很长的xlog日志,当页面没有足够的空间存储时,postgreseql允许把多余的数据存储到下一个页面,即同一条日志写到了两个文件档中。一种数据除外,头部数据是不允许存到两个页面当中的。
      当出现一条日志存放到两个页面时,需要用XLogContRecord来记录该页除了本页面存储的内容外,剩余的存储数据信息:
  typedef struct XLogContRecord                                                           
  {
   uint32 xl_rem_len; /* 记录中剩余信息的总长度*/
  } XLogContRecord;
  
      使用xlogdump(之后做一篇详细介绍xlogdump的文章)工具来观察下页面头信息(也可以观察源码xlogdump.c文件的readXLogPage函数),之后详细讲解xlogdump用法:
  打印信息如下:
  [page:0, xlp_info:3, xlp_tli:1, xlp_pageaddr:0/4C000000] XLP_FIRST_IS_CONTRECORD XLP_LONG_HEADER
  #第一页
  函数方法为:
  static bool                                                                              
  readXLogPage(void)
  {
   size_t nread = read(logFd, pageBuffer, XLOG_BLCKSZ);
  
   if (nread == XLOG_BLCKSZ)
   {
   logPageOff += XLOG_BLCKSZ;
   if (((XLogPageHeader) pageBuffer)->xlp_magic != XLOG_PAGE_MAGIC)
   {
   printf("Bogus page magic number %04X at offset %X\n",
    ((XLogPageHeader) pageBuffer)->xlp_magic, logPageOff);
   }
  
   /*
   * FIXME: check xlp_magic here.
   */
   if (!enable_stats)
   {
   printf("[page:%d, xlp_info:%d, xlp_tli:%d, xlp_pageaddr:%X/%X] ",
    logPageOff / XLOG_BLCKSZ,
    ((XLogPageHeader) pageBuffer)->xlp_info,
    ((XLogPageHeader) pageBuffer)->xlp_tli,
    ((XLogPageHeader) pageBuffer)->xlp_pageaddr.xlogid,
    ((XLogPageHeader) pageBuffer)->xlp_pageaddr.xrecoff);
  
   if ( (((XLogPageHeader)pageBuffer)->xlp_info & XLP_FIRST_IS_CONTRECORD) )
   printf("XLP_FIRST_IS_CONTRECORD ");
   if ((((XLogPageHeader)pageBuffer)->xlp_info & XLP_LONG_HEADER) )
   printf("XLP_LONG_HEADER ");
  #if PG_VERSION_NUM >= 90200
   if ((((XLogPageHeader)pageBuffer)->xlp_info & XLP_BKP_REMOVABLE) )
   printf("XLP_BKP_REMOVABLE ");
  #endif
  
   printf("\n");
   }
  
   return true;
   }
   if (nread != 0)
   {
   fprintf(stderr, "Partial page of %d bytes ignored\n",
   (int) nread);
   }
   return false;
  }
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-303111-1-1.html 上篇帖子: PostgreSQL服务过程中的那些事二:Pg服务进程处理简单查询梗概 下篇帖子: postgresql集群方案hot standby初级测试(三)——蛋疼测试——手动同步数据
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表