PostgreSQL xlog文件名规范源码解析【转】
PostgreSQLxlog即WA LWriteAheadLog位于pg_xlog目录下,PostgreSQL完全或者PIPPointIn-TimeRecoveri恢复所依赖的日志。
<palign="center">
为什么会有WA L日志呢?这个跟目前主流的数据库如OraclMySQL等一样,保证事务的耐久性。即任何已经commit事务,必需是耐久的
如果我把redo日志先于数据写出到磁盘,那么事务总是可以恢复的虽然时间有时候可能会久点。为什么日志先写,主要是因为写日志到磁盘比写数据到磁盘要快。
日志是连续IO刷出,而数据文件则一般都是随机IO
另外,细心的同学可能会发现PostgreSQL日志文件名很长,而且大小是16M目前PG默认xlogsegmentsize16M这个只能在源码编译时设定,假设我设置成64M
那么编译时configur带参数“--with-wal-segsize=64”即可。
另外xlog文件名可以分为二部分,以”000000010000000000000002”为例,分解为以下两个部分:
000000010000000000000002
其中第一个部分“00000001”为TimeLineId即通常所说的TLI用来标识数据库状态的每做一次恢复后,都会增加,主要为了将恢复后的数据库跟之前的数据库区别开来,
如PointIn-TimeRecoveri通常的关闭和起动数据库,并不会改变此值。PG用一个32位来标示TimeLineId源码定义如下:
这个有点类似于Oracl中Incarnat概念。
第二部分为“0000000000000002”为xlogsegno用64位来表示。源码定义为:
这其实已经是64位系统所能表示的最大值了这是理论上的xlogsgno最大值,即”FFFFFFFFFFFFFFFF”事实上文件号到达不了这个值。下面我详细来说明。
首先让我来理解日志流的内存寻址表示方法。PostgreSQL中,日志其实是用内存偏移地址来表示的源码定义为:
PG用了一个64位的地址表示日志的位置。很多同学认为,这很容易用完64位,那事实上是这样子吗?可以算一下:
假设我一天的日志量产生为10T即2^40次方;那么可以使用的年数为:2^64/2^24/365=4596.49这显然是足够了
讲到这里,很多同学已经急了这跟日志的文件名有什么关系呢?
答案是肯定的上面所讲的日志文件第二部分xlogsegno还可以再拆分两个32位。高32位表示xlog序列号,低32位来表示此xlog包括的segment号。
Xlogsegment号源码定义如下:
文件名定义源码:
假设xlogsegment大小为16M那么一个xlog所对应的segment个数为:2^32/2^24=2^8=256所以最大的xlog文件名应该为“00000001FFFFFFFF000000FF”而不是上面所提到理论最大值“00000001FFFFFFFFFFFFFFFF”
另外,PG数据库初始化时,xlog第一个位置会在XLOG_SEG_SIZE逻辑偏移量处开始,所以在16M大小的情况下,最小文件号为”00000001FFFFFFFF00000001”而不是“00000001FFFFFFFF00000000”从”0“处开始是非法的以下为源码中定义非法 xlogrecordpointor
下面我可以一个实验,来验证上面的过程:
1. 首先将当前xlog位置重置到离最大值还差一个xlog
<palign="center">
2.做checkpoint和switchlogfile
<palign="center">
首先报错,后面实例被终止,最后xlog被循环,从最小值开始。经历了FFFFFFFF000000FF-->0000000000000001
后台日志过程:
PostgreSQLxlog文件名规范源码解析--技术员007 ଘ(੭ˊᵕˋ)੭
https://007.gangguana.com/a/b1f677bc6b31555a2248cf9bf0e70d55.shtml
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2021-02-19 git使用命令
2016-02-19 scp命令报错-bash: scp: command not found