专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

PostgreSQL WAL日志详解 poster是什么意思中文

ins518 2024-11-05 11:11:02 技术文章 10 ℃ 0 评论


wal日志即write ahead log预写式日志,简称wal日志。wal日志可以说是PostgreSQL中十分重要的部分,相当于oracle中的redo日志。


当数据库中数据发生变更时:

change发生时:先要将变更后内容计入wal buffer中,再将变更后的数据写入data buffer;

commit发生时:wal buffer中数据刷新到磁盘;

checkpoint发生时:将所有data buffer刷新的磁盘。


可以想象,如果没有wal日志,那么数据库中将会发生什么?

首先,当我们在数据库中更新数据时,如果没有wal日志,那么每次更新都会将数据刷到磁盘上,并且这个动作是随机i/o,性能可想而知。并且没有wal日志,关系型数据库中事务的ACID如何保证呢?

因此wal日志重要性可想而知。其中心思想就是:先写入日志文件,再写入数据。


说到checkpoint,我们再来看看哪些情况会触发数据库的checkpoing:

1.手动执行CHECKPOINT命令;

2.执行需要检查点的命令(例如pg_start_backup 或pg_ctl stop|restart等等);

3.达到检查点配置时间(checkpoint_timeout);

4.max_wal_size已满。


其中1和2两点都和数据库的配置无关,我们暂时先不看,这里先介绍下checkpoint_timeout和max_wal_size两个参数。


checkpoint_timeout:

自动 WAL 检查点之间的最长时间,以秒计。合理的范围在 30 秒到 1 天之间。默认是 5 分钟(5min)。增加这个参数的值会增加崩溃恢复所需的时间。


postgres=> show checkpoint_timeout ;
 checkpoint_timeout 
--------------------
 25min
(1 row)

max_wal_size:

在自动 WAL检查点之间允许WAL 增长到的最大尺寸。这是一个软限制,在特殊的情况 下 WAL 尺寸可能会超过max_wal_size, 例如在重度负荷下、archive_command失败或者高的 wal_keep_segments设置。默认为 1 GB。增加这个参数可能导致崩溃恢复所需的时间。


postgres=> show max_wal_size ;
 max_wal_size 
--------------
 2662MB
(1 row)

和max_wal_size相对应的还有个min_wal_size,这里简单介绍下:

只要 WAL 磁盘用量保持在这个设置之下,在检查点时旧的 WAL文件总是被回收以便未来使用,而不是直接被删除。

postgres=> show min_wal_size;
 min_wal_size 
--------------
 512MB

可能对oracle熟悉的人会觉得wal日志和redo还是有些不同,没错,oracle中redo是固定几个redo日志文件,然后轮着切换去写入,因此我们常常会在io高的数据库中看到redo切换相关的等待事件。

而在pg中wal日志是动态切换,从pg9.6开始采用这种模式。和oracle不同的是,pg中这种动态wal切换步骤是这样的:单个wal日志写满(默认大小16MB,编译数据库时指定)继续写下一个wal日志,直到磁盘剩余空间不足min_wal_size时才会将旧的 WAL文件回收以便继续使用


但是这种模式有一个弊端就是如果在checkpoint之前产生了大量的wal日志就会导致发生checkpoint时对性能的影响巨大,因此pg中还有一个参数checkpoint_completion_target来进行调整。


checkpoint_completion_target:

指定检查点完成的目标,作为检查点之间总时间的一部分。默认是 0.5。

postgres=> show checkpoint_completion_target;
 checkpoint_completion_target 
------------------------------
 0.4
(1 row)

什么意思呢,假如我的checkpoint_timeout设置是30分钟,而wal生成了10G,那么设置成0.5就允许我在15分钟内完成checkpoint,调大这个值就可以降低checkpoint对性能的影响,但是万一数据库出现故障,那么这个值设置越大数据就越危险。


总结:

  1. 大多数检查点应该是基于时间的,即由checkpoint_timeout触发。
  2. 性能(不频繁检查点)与恢复所需时间(频繁检查点)之间需要抉择:
  3. 值在15-30分钟之间是比例合适的,但到1小时不是什么坏事。
  4. 在决定checkpoint_timeout后,通过估计WAL的数量选择max_wal_size。
  5. 设置checkpoint_completion_target以便内核将数据刷新到磁盘的时间足够(但不是太多)。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表