前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PostgreSQL WAL日志名解析

PostgreSQL WAL日志名解析

原创
作者头像
donghy
发布2022-09-17 15:47:53
8360
发布2022-09-17 15:47:53
举报
文章被收录于专栏:懒人的记录

日志名组成

在PG中日志名是一串数字,刚开始接触PG的朋友对名字都有些疑惑,在PG中日志名是由16进制命名总共24个字符由三部分组成:

代码语言:txt
复制
0000000100000001000000C4
00000001 //时间线ID
00000001 //LogId
000000C4 //logSeg

如何计算?

我们知道由三部分组成,那么又是如何计算呢?公式如下:

代码语言:txt
复制
WAL segment file name = timelineId +(uint32)LSN−1 / (16M ∗ 256) + (uint32)(LSN − 1 / 16M) % 256

我们算一个试一试.查看当前LSN位置

代码语言:txt
复制
postgres=# select pg_current_wal_lsn();
 pg_current_wal_lsn
--------------------
 1/C469AA30
(1 row)

这里的LSN是' 1/C469AA30' 我们转换为十进制数:

代码语言:txt
复制
postgres=# select x'1C469AA30'::bigint;
    int8
------------
 7590226480
(1 row)

利用公式计算:

代码语言:txt
复制
logSeg:
postgres=# select ((7590226480 - 1) / (16 * 1024 * 1024 )) % 256 ;
 ?column?
----------
      196
(1 row)
196是十进制数 转换为16 进制为 c4 
postgres=# select to_hex(196);
 to_hex
--------
 c4
(1 row)

LogId:
postgres=# select ((7590226480 - 1) / (16::bigint * 1024::bigint * 1024::bigint * 256::bigint) :: int8);
 ?column?
----------
        1
(1 row)
得出的LogId等于1

时间线ID:

postgres@coredumped  ~  pg_controldata|grep TimeLine
Latest checkpoint's TimeLineID:       1
Latest checkpoint's PrevTimeLineID:   1

算出来的值与通过函数查询的一致:

代码语言:txt
复制
postgres=# select pg_walfile_name('1/C469AA30');
     pg_walfile_name
--------------------------
 0000000100000001000000C4
(1 row)

通过源码分析

上述的公式也是在网站中看到,特意查看了下PG代码确认下正确性:

代码语言:txt
复制
// 这里是计算一个logSegNo
#define XLByteToPrevSeg(xlrp, logSegNo) \
      logSegNo = ((xlrp) - 1) / XLogSegSize 

//XLOG_SEG_SIZE 定义
#define XLOG_SEG_SIZE (16 * 1024 * 1024)

//这块是拼文件名地方
#define XLogFilePath(path, tli, logSegNo)   \
      snprintf(path, MAXPGPATH, XLOGDIR "/%08X%08X%08X", tli, 
              ¦(uint32) ((logSegNo) / XLogSegmentsPerXLogId),
              ¦(uint32) ((logSegNo) % XLogSegmentsPerXLogId))

LogId与logSeg 分别是LogSegNo除XLogSegmentsPerXLogId或者是对XLogSegmentsPerXLogId取模,那么XLogSegmentsPerXLogId又是什么呢?


//看到XLogSegmentsPerXLogId的定义我们可以自己计算下
#define XLogSegmentsPerXLogId   (UINT64CONST(0x100000000) / XLOG_SEG_SIZE)

postgres=# select x'100000000'::bigint / (16 * 1024 * 1024);
 ?column?
----------
      256
(1 row)
这个值就是256

总结

WAL日志命名感觉上并不像MySQL Binlog日志那么直观,有时候感觉会容易混乱,大家学习时可以多进行研究多做实验,这样对自己也是一种提高。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 日志名组成
  • 如何计算?
  • 通过源码分析
  • 总结
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档