PostgreSQL-WAL日志介绍(二)

1. 概述

1.1 检查点

随着时间的推移,数据库的事务会不断增多,将会带来以下两个问题:占用大量的磁盘空间;故障恢复时需要回放所有WAL日志,导致故障恢复的时间很长,降低了数据库的可用性。因此,检查点(CheckPoint)是一种关键的机制,用于确保数据库的持久性,以及控制WAL日志的连续增长。一方面,在该检查点之前的WAL日志可以被删除,释放磁盘空间;另一方面,当进行故障恢复时,可以从这个检查点对事务日志进行回放,有效降低故障恢复的时间。

检查点的目的:确保数据库在发生故障或崩溃时可以进行一致的恢复。它通过以下方式实现:

(1)收集脏页并将其刷入磁盘:将共享缓存中的脏页(已被修改但尚未写入磁盘的数据页)刷入到磁盘上的数据文件中,以确保数据的持久性。

(2)重置WAL日志:删除WAL日志中已经不再需要的部分,以限制WAL文件的大小和增长。

检查点的触发:

  • 根据时间间隔:可以通过配置参数checkpoint_timeout来定期触发
  • 根据WAL日志大小:当WAL日志文件大小超过max_wal_size时会触发检查点
  • 手动触发:用户可以通过手动执行CHECKPOINT命令来创建检查点。
  • 数据库关闭及启动时,也会自动触发CHECKPOINT命令。

1.2 日志清理

由于WAL日志是连续线性增长的,如果不做日志清理,则会发生wal日志数据膨胀。

何时做日志清理:

  1. CheckPoint即将结束时,会对WAL日志进行清理,将之前的日志段删除
  2. 数据库启动或重启,触发检查点时
  3. 从前一个检查点发生过后的时间超过checkpoint_timeout设置的间隔时
  4. 在版本9.4或更早版本中,自上一个检查点以来,超过使用checkpoint_segments设置的WAL段文件数量时
  5. 在9.5或更高版本中,pg_xlog(版本10或更高版本,pg_wal)中WAL段文件的总大小已超过参数max_wal_size的值时
  6. PGSQL服务在smart和fast模式下停止
  7. 手动执行checkpoint

以下几个参数在控制wal日志文件的保留和清理方面有重要作用:

wal_keep_segments:决定了要保留的wal日志段的数量。每个wal日志段的大小由wal_segment_size决定(通常为16MB)。wal_keep_segments设置了一个阈值,当wal日志段的数量接近这个阈值时,系统会开始考虑清理旧的wal日志段。

max_wal_size和min_wal_size:这两个配置项用于控制wal日志的大小。min_wal_size指定了系统允许的最小日志量,而max_wal_size指定了系统允许的最大日志量。系统会尽量将wal日志的大小保持在这两个限制之间。

1.3 日志归档

清理日志虽然解决了日志膨胀的问题,但是也带来了新的问题,就是无法再恢复检查点之前的一致性状态。即只有将数据库创建之后生成的所有wal日志全都保存起来,才能从数据库的初始状态恢复到任意时刻的一致性状态。因此,数据库可以考虑将这些wal日志保存至其他存储介质,既能避免当前主机的数据膨胀,也能保障数据库恢复到以前的一致性状态,这就是日志归档功能。

日志归档的目的是能够通过归档日志对数据库进行恢复。

每当wal日志中的一个日志段(日志文件)已满,需要切换到下一个日志段时,就可以通过日志归档进程将这个日志归档,触发日志段切换的进程会向Postmaster进程发出通知,然后Postmaster进程会检查日志归档进程是否已经启动,如果存在日志归档进程,则Postmaster进程会将这个通知再转发给日志归档进程。产生日志切换的进程会在通知Postmaster之前现在sys_wal/archive_status下生成一个.ready文件,这个文件和待归档的日志同名。日志归档进程只关心这个文件是否存在,不关心文件内容。实际上.ready文件的存在是一种进程间的通信机制,日志归档进程会监控pg_wal/archive_status目录下的.ready文件,一旦发现有了新的.ready文件出现,它就对pg_wal下的同名日志段依照archive_command参数中的归档命令进行归档。在.ready很多的情况下,日志归档进程会优先选择段号较小的日志文件,因为日志清理时是按照日志段编号的顺序进行清理的,所以日志段号小的事务日志优先归档之后就可以由日志清理模块进行清理了。对日志进行归档后,日志归档进程会将.ready文件修改为.done文件,代表该日志已经归档完成。

相关推荐
毋若成17 分钟前
【搭建JavaEE】(3)前后端交互,请求响应机制,JDBC数据库连接
数据库·java-ee·交互
m0_7482417020 分钟前
C#数据库操作系列---SqlSugar完结篇
网络·数据库·c#
天天向上杰1 小时前
简识MySQL中ReadView、RC、RR的关系
数据库·mysql
久绊A1 小时前
理解CPU负载与使用率
服务器·网络·数据库·cpu
你疯了抱抱我1 小时前
Oracle知识点1:如何修改密码并登录sys/system账号
数据库·oracle
羊小猪~~3 小时前
MYSQL学习笔记(二):基本的SELECT语句使用(基本、条件、聚合函数查询)
数据库·笔记·sql·学习·mysql·考研·数据分析
然然阿然然3 小时前
2025.1.15——二、字符型注入
网络·数据库·sql·学习·网络安全
!!!5254 小时前
MyBatis-增删改查操作&一些细节
java·数据库·spring boot·mybatis
然然阿然然4 小时前
2025.1.15——六、SQL结构【❤sqlmap❤】
数据库·sql·学习·安全·web安全·网络安全
霍格沃兹测试开发学社测试人社区5 小时前
三大智能体平台对比分析:FastGPT、Dify、Coze 哪个更适合你?
大数据·软件测试·数据库·人工智能·测试开发