当前位置:首页|资讯

CheckPoint之日志归档(3)

作者:david007Bili发布时间:2024-09-09

      postgresql会通过checkpoint对WAL日志进行清理.由于WAL不在是时间序列上的全量数据,这也会带来新的问题,就是无法再恢复到checkpoint之前的一致性状态(WAL已经不复存在).为实现可以恢复到任意时间点的功能,postgresql使用日志归档模块完成.

      日志归档就是在对WAL日志进行清理之间,通过将历史WAL日志保存到其他存储介质中,这既能避免当前主机的数据膨胀,也能保证数据库恢复到以前的一致性状态.

      归档功能开启方法为打开归档开关,设定好归档命令,配置归档参数.

1、archive_mode参数有3种模式:

off:关闭归档

on:开启归档,但不允许在recovery模式下进行归档

always:开启归档,且允许在recovery模式下进行归档

      backend进程启动时,在主函数PostmasterMain中会校验参数,如果开启归档,则必须保证wal_level不能是MINIMAL状态,因为该状态下有些操作不会记录日志.

      根据archive_mode判定是否可以进行归档代码如下: 

2、归档命令

      pg会启动一个辅助进程,作用是实时监控事务日志,发现能归档的日志则会通过用户设置的归档命令(archive_command)进行归档。

     如果archive_command没有设置,则日志归档操作没发真正执行,系统会告警报错,archive_command的设置方法为修改postgresql.conf配置文件中archive_command参数即可,示例如下:

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'  # Unix

      归档命令可以使用两个通配符来分别表示源文件的路径和命令,定义如下:

%p: 归档文件路径(绝对路径,包含文件名)

%f: 归档文件名

    归档命令可以很自由地被指定,如果要在本机存档,可以使用cp命令进行复制;如果要在远程机器归档,则可以使用rsync命令进行远程数据通过;当然,用户也可以实现自己的归档命令.

     在使用归档命令时,用户要保证归档命令的有效性,如果设置命令有错误或者无效将影响归档功能。那么WAL日志就会一直保留,checkpoint中过清理日志操作无法成功执行,从而导致日志堆积。

3、archive_timeout参数

       如果只在日志切换时归档,假如在日志段未满时宕机,则归档日志会缺失一部分,可能造成数据丢失。另外,如果业务写请求较少,日志可能长期不归档。此时,可以通过archive_timeout参数设置超时强制归档,提高归档频率。

      archive_timeout指定了日志归档的最大时间间隔,如果超过这个设定的时间而没有进行日志归档,则做一次日志切换,强制进行日志归档.

      该部分逻辑由CheckArchiveTimeout函数实现,调用时机如下:

1)、在CheckpointerMain完成检查点创建后做一次CheckArchiveTimeout()检查

2)、在CheckpointWriteDelay控制检查点速度中做一次CheckArchiveTimeout()检查

CheckArchiveTimeout实现关键代码如下所示:

4、调用命令手动归档日志

      调用select pg_switch_wal()手动切换WAL日志,从而触发日志归档.

5、日志切换归档

      当开启归档开关后,当WAL日志段写满达到阈值或者其他原因完成日志切换,就会触发通知日志归档进程进行归档操作。

1)、归档触发

      在XlogWrite函数中,探测发现WAL日志段已满,会将日志段刷入磁盘,保证归档日志数据完整性,同时唤醒归档进程开始归档操作.

2)、唤醒归档进程逻辑

      首先根据lsn号计算对应的wal文件名,然后通过XLogArchiveNotify通知归档进程进程归档操作.

      具体通知方法为,首先创建一个和要归档的日志段同名的.ready文件,归档进程通过该文件名判定归档操作进度(归档进程会监控该文件);其次,通过setlatch唤醒正在等待该锁的归档进程开始工作.

3)、归档进程收到通过开始进程归档操作.

      归档进程PgArchiverMain会循环调用pgarch_ArchiverCopyLoop函数进行实际归档操作.

      pgarch_ArchiverCopyLoop会循环查找WAL目录下的.ready文件并使用archive_command对其进行归档,归档成功完成后将.ready文件改为.done文件表示该任务已经成功结束.

      当WAL目录下有多个.ready文件时,会优先选择段号较小的日志文件进行归档,在pgarch_readyXlog函数中有详细的选择段文件的逻辑.

      下面是pgarch_ArchiverCopyLoop关键源码

     PostgreSQL 会通过 checkpoint 清理 WAL 日志,但可能导致无法恢复到 checkpoint 前的一致性状态,因此使用日志归档模块解决。

    归档功能开启需设置开关、命令和超时参数三部分。archive_mode 有 off、on、always 三种模式,backend 进程启动时会校验参数,开启归档时 wal_level 不能是 MINIMAL 状态。

    归档功能实际由辅助进程完成,日志段写满等情况会触发通知归档进程进行归档操作,包括归档触发、唤醒归档进程、归档进程收到通知开始操作等步骤,其中归档进程会优先选择段号较小的日志文件进行归档。



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1