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

简介: [翻译]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日志并进行多维度分析。
          目录
          相关文章
          |
          16小时前
          |
          存储 运维 应用服务中间件
          [运维日志] Web 服务器日志依日期归档(Powershell 实现,附源代码)
          [运维日志] Web 服务器日志依日期归档(Powershell 实现,附源代码)
          78 0
          |
          16小时前
          |
          存储 Oracle 关系型数据库
          postgresql数据库|wal日志的开启以及如何管理
          postgresql数据库|wal日志的开启以及如何管理
          383 0
          |
          16小时前
          |
          存储 SQL Serverless
          Serverless 应用引擎常见问题之应用下的【应用事件】以及企业级特性下的【事件中心】没有日志如何解决
          Serverless 应用引擎(Serverless Application Engine, SAE)是一种完全托管的应用平台,它允许开发者无需管理服务器即可构建和部署应用。以下是Serverless 应用引擎使用过程中的一些常见问题及其答案的汇总:
          34 0
          |
          16小时前
          |
          监控 Java API
          JDK 9新特性深度探索:平台日志API和服务
          本文将深入探讨JDK 9中引入的平台日志API和服务。这一新特性为Java应用程序提供了更强大、灵活的日志记录功能,帮助开发者更好地监控和诊断应用程序的运行状况。本文将详细介绍平台日志API和服务的特性和优势,以及如何在项目中应用这一新特性来提升应用程序的稳定性和可维护性。
          |
          16小时前
          |
          Go
          Golang日志切割归档
          Golang日志切割归档
          33 0
          |
          12月前
          |
          存储 运维 Java
          [powershell运维] Web 服务器日志依日期归档
          本文记录了一个以 Jboss 服务器日志归档的 powershell 示范项目。该项目只需要略加修改,即可用于所有类似需要归档日志的场景。
          109 0
          |
          SQL 缓存 监控
          spring5新特性日志体系
          spring5新特性日志体系 主流的log技术名词 1.jul 2.log4j 3.jcl jcl源码分析: 虽然Log4JLogger是jcl的jar包中的类,但是该Log4JLogger类,依赖了
          97 0
          |
          Oracle 关系型数据库 Linux
          DM8重做日志文件和归档管理
          重做日志文件,用来保存redo日志,redo日志默认2个,循环使用,不断覆盖,联机日志由系统自动切换,不能手动切换,联机日志过小,会制造日志频繁切换,过大则浪费磁盘空间。
          DM8重做日志文件和归档管理
          |
          关系型数据库 PostgreSQL
          postgresql 的WAL日志解析工具 pg_waldump
          postgresql 的WAL日志解析工具 pg_waldump
          1307 0
          postgresql 的WAL日志解析工具 pg_waldump
          |
          消息中间件 容灾 关系型数据库
          核心特性—全局日志变更
          MySQL binlog是MySQL记录变更数据的“二进制日志”,它可以看做是一个消息队列,队列中按顺序保存了MySQL中详细的增量变更信息,通过消费队列中的变更条目,下游系统或工具实现了与MySQL的实时数据同步,这样的机制也称为CDC(Change Data Capture,增量数据捕捉)。
          107 0
          核心特性—全局日志变更

          热门文章

          最新文章