[翻译]PG15新特性-加速WAL日志归档

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: [翻译]PG15新特性-加速WAL日志归档

PG15新特性-加速WAL日志归档PG15通过:一次扫描64个待归档的日志,将其放到一个数组中以供归档,当处理完这64个文件后,再进行下一次扫描。这样达到减少archive_status目录扫描次数提升性能的目的。


WAL归档


介绍PG15如何加速归档前,先看下PG14及老版本如何归档的。PG在pg_wal目录产生WAL段文件时,会在pg_wal/archive_status子目录产生相关的.ready文件。例如:

    $ ls -alrth pg_wal/
    drwx------ 3 postgres postgres  68 Dec  7 05:47 .
    drwx------ 21 postgres postgres 32 Dec 21 03:54 ..
    -rw------- 1 postgres postgres 16M Dec 21 04:38 0000000200000008000000E4
    -rw------- 1 postgres postgres 16M Dec 21 04:38 0000000200000008000000E5
    -rw------- 1 postgres postgres 16M Dec 21 04:38 0000000200000008000000E6
    -rw------- 1 postgres postgres 16M Dec 21 04:38 0000000200000008000000E7
    drwx------ 2 postgres postgres   6 Dec 21 04:38 archive_status
    -rw------- 1 postgres postgres 16M Dec 21 04:38 0000000200000008000000E8
    -bash-4.2$ ls -alrth pg_wal/archive_status/
    total 5.0K
    drwx------ 3 postgres postgres 68 Dec 7 05:47 ..
    -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E4.ready
    -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E5.ready
    -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E6.ready
    -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E7.ready
    drwx------ 2 postgres postgres 6 Dec 21 04:38 .

    这表示WAL文件0000000200000008000000E7准备好归档了,0000000200000008000000E8是当前使用的WAL文件,还没有准备好归档。

      postgres=# SELECT pg_walfile_name(pg_current_wal_lsn());
        pg_walfile_name    
      --------------------------
      0000000200000008000000E8
      (1 row)

      一旦WAL日志归档到backup位置(归档目标),状态改成.done:

        $ ls -alrth pg_wal/archive_status/
        total 5.0K
        drwx------ 3 postgres postgres 68 Dec 7 05:47 ..
        -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E4.done
        -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E5.done
        -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E6.done
        -rw------- 1 postgres postgres 0 Dec 21 04:38 0000000200000008000000E7.done

        PG使用这些状态文件了解哪些是待归档的日志文件。PG扫描目录pg_wal/archive_status/从而了解哪个是还没有归档的最老的WAL段文件。PG的归档进程每60秒(默认)被唤醒一次,并尝试执行内部函数pgarch_ArchiverCopyLoop()来处理每个挂起的WAL段文件;依次为每个WAL段文件执行archive_command。当WAL归档应以正确的顺序发生,并只针对剩余的WAL段文件。接下来要处理哪个WAL段文件由函数pgarch_readyXlog()决定。PG代码中注释可以说明整个流程:

          /*
          * pgarch_readyXlog
          *
          * Return name of the oldest xlog file that has not yet been archived.
          * No notification is set that file archiving is now in progress, so
          * this would need to be extended if multiple concurrent archival
          * tasks were created. If a failure occurs, we will completely
          * re-copy the file at the next available opportunity.
          *
          * It is important that we return the oldest, so that we archive xlogs
          * in order that they were written, for two reasons:
          * 1) to maintain the sequential chain of xlogs required for recovery
          * 2) because the oldest ones will sooner become candidates for
          * recycling at time of checkpoint
          *
          * NOTE: the "oldest" comparison will consider any .history file to be older
          * than any other file except another .history file.  Segments on a timeline
          * with a smaller ID will be older than all segments on a timeline with a
          * larger ID; the net result being that past timelines are given higher
          * priority for archiving.  This seems okay, or at least not obviously worth
          * changing.
          */

          问题

          pgarch_readyXlog()函数需要扫描pg_wal/archive_status/目录下的文件来决定哪个文件是下一个归档候选者。因此,对于每个要归档的WAL文件来说,实际上都会导致完整的目录扫描。如果pg_wal/archive_status/中有数千或者数百万个文件怎么办?这发生在大事务系统中,WAL归档无法在高峰时段赶上WAL生成,或者如果WAL归档在一段时间内失败了。一旦积累了大量的.ready状态文件,目录扫描本身就会花费更多时间。这样,WAL归档赶上的机会就变得非常渺茫了。PG14及之前版本唯一的解决方案是:尝试将wal_segment_size增大,以便产生更少梳理的文件。可以将默认的16MB增加到1GB来解决整个问题。当然,这是一个不太好的解决方法,如果需要recovery备份,就会带来明显的后果,比如大量数据丢失。


          PG15如何解决这个问题


          邮件列表中讨论了各种解决方案和补丁:https://www.postgresql.org/message-id/flat/CA%2BTgmobhAbs2yabTuTRkJTq_kkC80-%2Bjw%3DpfpypdOJ7%2BgAbQbw%40mail.gmail.com总结出两种方法:1)扫描目录并将结果保存到数组中,并为archive_command或模块提供相同的结果。即使这可以大大减少目录扫描次数,但是仍旧会扫描目录,复杂性O(n2)2)另一个更加巧妙的方法是预测下一个WAL段文件(基于WAL文件名格式)并尝试在目录中查看相同的文件。逻辑的主要部分中可以避免目录扫描。采取哪一种方法是一个非常困难的决定。权衡所有影响后,选则了第一种方法,即将WAL段文件名保存在一个数组种。主要是因为这个数组可以进一步改进依次将多个文件发送到archive_command或模块,这是另一个改进的地方。


          PG15种如何工作


          这个想法是:用.ready文件扫描archive_status目录,并将要归档的WAL文件列表累积到一个数组中。数组的大小可以在编译的时会使用常量来定义:


          /*
          * Maximum number of .ready files to gather per directory scan.
          */
          #define NUM_FILES_PER_DIRECTORY_SCAN 64

          因此,在处理完64个.ready文件后,再进行目录扫描。由于将时间线历史文件推送到归档非常重要,因此它将优先于WAL段文件。通过时间线切换时触发目录扫描来完成。总体而言,社区报告中性能提升了20倍或更多。


          更好地监控WAL归档


          PG15添加了一组新的wait_events,以便更好地观察和排除WAL归档、恢复、清理阶段的故障。

          ArchiveCleanupCommand 等待archive_cleanup_command完成.
          ArchiveCommand 等待archive_command完成.
          RecoveryEndCommand 等待recovery_end_command完成.
          RestoreCommand 等待restore_command完成.

          这些等待事件监控可以告诉我们在特定操作上花费的时间是多少。例如,等待事件“ArchiveCommand”告诉我们“archive_command”中指定的shell命令正在执行中。pg_gather这样的工具/脚本可以有效地利用这些等待来了解执行archive_command所花费的事件百分比以及archive_command的速度是否是WAL归档的瓶颈。

          原文

          https://www.percona.com/blog/speed-up-of-the-wal-archiving-in-postgresql-15/

          相关实践学习
          日志服务之使用Nginx模式采集日志
          本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
          目录
          相关文章
          |
          19天前
          |
          SQL Oracle 关系型数据库
          【赵渝强老师】Oracle的控制文件与归档日志文件
          本文介绍了Oracle数据库中的控制文件和归档日志文件。控制文件记录了数据库的物理结构信息,如数据库名、数据文件和联机日志文件的位置等。为了保护数据库,通常会进行控制文件的多路复用。归档日志文件是联机重做日志文件的副本,用于记录数据库的变更历史。文章还提供了相关SQL语句,帮助查看和设置数据库的日志模式。
          【赵渝强老师】Oracle的控制文件与归档日志文件
          |
          2月前
          |
          SQL 存储 关系型数据库
          美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
          老架构师尼恩在其读者交流群中分享了关于 MySQL 中 redo log、undo log 和 binlog 的面试题及其答案。这些问题涵盖了事务的 ACID 特性、日志的一致性问题、SQL 语句的执行流程等。尼恩详细解释了这些日志的作用、所在架构层级、日志形式、缓存机制以及写文件方式等内容。他还提供了多个面试题的详细解答,帮助读者系统化地掌握这些知识点,提升面试表现。此外,尼恩还推荐了《尼恩Java面试宝典PDF》和其他技术圣经系列PDF,帮助读者进一步巩固知识,实现“offer自由”。
          美团面试:binlog、redo log、undo log的底层原理是什么?它们分别实现ACID的哪个特性?
          |
          2月前
          |
          存储 消息中间件 大数据
          大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
          大数据-69 Kafka 高级特性 物理存储 实机查看分析 日志存储一篇详解
          39 4
          |
          2月前
          |
          存储 消息中间件 大数据
          大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
          大数据-70 Kafka 高级特性 物理存储 日志存储 日志清理: 日志删除与日志压缩
          41 1
          |
          2月前
          |
          存储 消息中间件 大数据
          大数据-68 Kafka 高级特性 物理存储 日志存储概述
          大数据-68 Kafka 高级特性 物理存储 日志存储概述
          30 1
          |
          2月前
          |
          存储 监控 固态存储
          如何监控和优化 WAL 日志文件的存储空间使用?
          如何监控和优化 WAL 日志文件的存储空间使用?
          |
          3月前
          |
          存储 关系型数据库 MySQL
          binlog、redolog、undo log底层原理及ACID特性实现分享
          在数据库管理系统中,日志机制是确保数据一致性、完整性和可靠性的关键组件。MySQL数据库中的binlog、redolog和undolog作为其核心日志系统,各自扮演着不同但同样重要的角色。本文将深入探讨这三种日志的底层原理以及它们如何分别实现ACID(原子性、一致性、隔离性、持久性)特性的不同方面。
          58 0
          |
          4月前
          |
          SQL Oracle NoSQL
          实时计算 Flink版操作报错合集之报错“找不到对应的归档日志文件”,怎么处理
          在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
          |
          4月前
          |
          SQL Oracle 关系型数据库
          "揭秘!一键解锁Oracle日志清理魔法,让海量归档日志无处遁形,守护数据库健康,告别磁盘空间告急噩梦!"
          【8月更文挑战第9天】随着Oracle数据库在企业应用中的普及,归档日志管理对保持数据库健康至关重要。归档日志记录所有更改,对数据恢复极为重要,但也可能迅速占用大量磁盘空间影响性能。利用Oracle提供的RMAN工具,可通过编写Shell脚本来自动清理归档日志。脚本包括设置环境变量、连接数据库、检查和删除指定时间前的日志,并记录执行情况。通过Cron作业定时运行脚本,可有效管理日志文件,确保数据库稳定运行。
          106 7
          |
          4月前
          |
          存储 缓存 分布式计算
          详解HBase中的“WAL”(Write-Ahead Log)
          【8月更文挑战第31天】
          169 0