上次我在博客中写道新的细胞膜归档模块/库特性可以在PostgreSQL 15,非常变革在PostgreSQL今天犯下如何存档。PostgreSQL 15有更多的改进与WAL存档,这是值得讨论。在这个博客中,我想强调其中的一些解决好业务挑战许多PostgreSQL的用户。
细胞膜的基本知识存档
我们首先讨论的问题之一,存在于PostgreSQL 14及以上。
当Postgresql生成WAL pg_wal目录中的部分文件,它还产生关联时文件pg_wal/archive_status子目录。
例如,
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
美元
ls
- - - - - -
alrth
pg_wal
/
drwx
- - -
- - -
- - -
3
postgres
postgres
68年
12月
7
05年
:
47
。
drwx
- - -
- - -
- - -
21
postgres
postgres
32
12月
21
03
:
54
。
。
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
16米
12月
21
04
:
38
0000000200000008000000 e4
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
16米
12月
21
04
:
38
0000000200000008000000 e5
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
16米
12月
21
04
:
38
0000000200000008000000 e6
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
16米
12月
21
04
:
38
0000000200000008000000 e7
drwx
- - -
- - -
- - -
2
postgres
postgres
6
12月
21
04
:
38
archive_status
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
16米
12月
21
04
:
38
0000000200000008000000 e8
- - - - - -
bash
- - - - - -
4.2
美元
ls
- - - - - -
alrth
pg_wal
/
archive_status
/
总
5.0 k
drwx
- - -
- - -
- - -
3
postgres
postgres
68年
12月
7
05年
:
47
。
。
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e4.ready
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e5.ready
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e6.ready
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e7.ready
drwx
- - -
- - -
- - -
2
postgres
postgres
6
12月
21
04
:
38
。
|
这表明细胞膜部分文件0000000200000008000000 e7准备存档,0000000200000008000000 e8是当前细胞膜部分文件没有准备存档。
|
1
2
3
4
5
|
postgres
=
#选择pg_walfile_name (pg_current_wal_lsn ());
pg_walfile_name
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
0000000200000008000000 e8
(
1
行
)
|
一旦犯下存档备份位置(归档目的地),状态的变化.done
|
1
2
3
4
5
6
7
|
美元
ls
- - - - - -
alrth
pg_wal
/
archive_status
/
总
5.0 k
drwx
- - -
- - -
- - -
3
postgres
postgres
68年
12月
7
05年
:
47
。
。
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e4.done
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e5.done
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e6.done
- - - - - -
rw
- - -
- - -
- - -
- - - - - -
1
postgres
postgres
0
12月
21
04
:
38
0000000200000008000000 e7.done
|
PostgreSQL使用这些状态文件理解什么是WAL等待文件归档。
PostgreSQL扫描的目录pg_wal/archive_status/了解古老WAL段文件尚未归档。
PostgreSQL的文档过程醒来每60秒(默认),并试图解决所有悬而未决的WAL段通过执行一个内部函数pgarch_ArchiverCopyLoop();
这反过来执行archive_command为每个WAL段文件。但细胞膜归档应该发生在正确的顺序,只剩下WAL段文件。
细胞膜的决策文件处理下一个是由功能决定的pgarch_readyXlog()。下面的评论在PostgreSQL代码可以告诉整个故事。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20.
21
22
|
/
*
*
pgarch_readyXlog
*
*
返回
的名字
的
的
最古老的
xlog
文件
那
有
不
然而,
被
存档
。
*
没有
通知
是
集
那
文件
存档
是
现在
在
进步
,
所以
*
这
将
需要
来
是
扩展
如果
多个
并发
档案
*
任务
是
创建
。
如果
一个
失败
发生
,
我们
将
完全
*
再保险
- - - - - -
复制
的
文件
在
的
下一个
可用
机会
。
*
*
它
是
重要的
那
我们
返回
的
最古老的
,
所以
那
我们
存档
xlogs
*
在
订单
那
他们
是
写
,
为
两个
原因
:
*
1
)
来
维护
的
顺序
链
的
xlogs
要求
为
复苏
*
2
)
因为
的
最古老的
的
将
早
成为
候选人
为
*
回收
在
时间
的
检查点
*
*
请注意
:
的
“古老的”
比较
将
考虑
任何
.history
文件
来
是
老
*
比
任何
其他
文件
除了
另一个
.history
文件
。
段
在
一个
时间轴
*
与
一个
小
ID
将
是
老
比
所有
段
在
一个
时间轴
与
一个
*
更大的
ID
;
的
净
结果
被
那
过去的
时间线
是
鉴于
更高的
*
优先级
为
存档
。
这
似乎
好吧
,
或
在
至少
不
很明显
价值
*
改变
。
*
/
|
这个问题
但这个函数pgarch_readyXlog()需要扫描文件pg_wal/archive_status/决定哪些是下一个人选存档。所以有效地每个细胞膜文件存档完整的目录扫描结果。
如果有成千上万的文件pg_wal/archive_status/吗?这发生在一个高交易系统,细胞膜存档不能赶上犯下一代在高峰时间或者WAL拱形失败一段时间。曾经有一个巨大的数量的时积累状态文件,目录扫描自己将开始采取更多的时间。有效的机会WAL拱形赶上变得非常微弱的迹象。
如果这发生在PG14以上,唯一的解决办法是增加wal_segment_size一个更大的价值,所以会产生一个较小的文件数量。我们有客户的情况我们增加了wal_segment_size从默认16 mb 1 gb来解决这个问题。当然,那是一个肮脏的解决方案,那么明显的后果就像巨大的如果需要恢复备份数据丢失。
PostgreSQL 15是如何解决这个问题
讨论了多个解决方案和补丁与所有的可能性。如果你想看看完整的细节,您可以参考邮件列表中的线程:
聚合的讨论分为两种方法:
- 扫描目录,保存在数组并提供相同的结果archive_command或模块。尽管这可以大大减少扫描目录,该目录扫描仍然发生,和相关的O (n ^ 2)复杂性的存在。
- 更聪明的方法是预测未来细胞膜部分文件(根据细胞膜文件名格式)并试图看到相同的目录中。目录扫描可以避免逻辑的重要组成部分。
这是一个非常困难的决定应采取的方法。权衡所有的影响之后,第一种方法,拥有数组中的细胞膜部分文件名,选择,主要是因为这个数组可用于进一步提高发送多个文件archive_command或模块,这是需要改进的另一个主要领域。
PostgreSQL 15中它是如何工作的
时的想法是扫描archive_status目录文件和积累犯下的列表文件归档到一个数组的数组大小可以控制在编译时使用一个常数定义。
|
1
2
3
4
|
/
*
*
最大
数量
的
时
文件
来
收集
每
目录
扫描
。
*
/
#定义NUM_FILES_PER_DIRECTORY_SCAN 64
|
所以一个目录扫描将在64年后完成时文件处理。
因为它是非常重要的时间历史存档,它将优先在WAL段。这是通过尤其是触发一个目录扫描每当有时间轴开关。
总的来说,20 x社区的报告或更多的性能改进
更好的监测WAraybet雷竞技竞猜在线官网L存档
一套新的wait_events添加在PostgreSQL 15更好的可观察性和故障排除WAL存档,恢复和清理阶段。
| ArchiveCleanupCommand | 等待archive_cleanup_command完成。 |
| ArchiveCommand | 等待archive_command完成。 |
| RecoveryEndCommand | 等待recovery_end_command完成。 |
| RestoreCommand | 等待restore_command完成。 |
这个等待事件监视可以告诉我们的时raybet雷竞技竞猜在线官网间花在具体行动。例如,等待事件“ArchiveCommand”告诉我们,“archive_command”中指定的shell命令正在执行中。
工具/脚本等pg_gather可以有效地利用这些等待理解比例的时间花在执行什么archive_command和archive_command的速度是否瓶颈WAL存档。

由于社区!我要感谢伟大的贡献,即罗伯特•哈斯的提交者/协调员的改进,Dipesh潘迪特,他的工作显示前进道路上,最后,内森博萨尔特,谁让数组方法和Dilip库马尔。
由于藤井正雄等事件补丁。
感谢那些参与讨论和评论:迈克尔•Paquier Bharath Rupireddy, Andres Freund,安德烈鲍罗廷Dilip Kumar斯蒂芬·弗罗斯特Kyotaro Horiguchi, Jeevan Ladhe,和许多其他人。





