`

postgresql 预写式日志(Write Ahead Long)

 
阅读更多
在网站中看到一篇转载次数非常高的文章,好多的日本网站也有。

文章的英文是postgresql的文章。该文章以postgresql 7.3版本为基础。相对于现在的新版本,其中没有同步和异步的部分,同步与异步的设置在特定情况下以牺牲数据完整性风险为前题,能大幅提高数据库的处理性能。

尽管是篇中文的翻译,但是对于了解postgresql的日志管理有很大的帮助。原文名称:PostgreSQL数据库学习手册之预写式日志

直接看内容:



Table of Contents

  11.1. 一般性描述

  11.1.1. 从 WAL 中获取的直接好处

  11.1.2. 更多好处

  11.2. 实现

  11.3. WAL 配置

  作者: Vadim Mikheev 和 Oliver Elphick

  11.1. 一般性描述

  预写式日志 (WAL) 是一种实现事务日志的标准方法.有关它的详细描述可以在 大多数(如果不是全部的话)有关事务处理的书中找到.简而言之,WAL 的中心思想是对数据文件 的修改(它们是表和索引的载体)必须是只能发生在这些修改已经 记录了日志之后 --也就是说,在日志记录冲刷到永久存储器之后. 如果我们遵循这个过程,那么我们就不需要在每次事务提交的时候都把数据页冲刷到磁盘,因为我们知道在出现崩溃的情况下, 我们可以用日志来恢复数据库:任何尚未附加到数据页的记录都将先从日志记录中重做(这叫向前滚动恢复,也叫做 REDO) 然后那些未提交的事务做的修改将被从数据页中删除 (这叫向后滚动恢复 -UNDO).

  11.1.1. 从 WAL 中获取的直接好处

  使用 WAL 的第一个明显的好处就是显著地减少了磁盘写的次数.因为在日志提交的时候只有日志文件需要冲刷到磁盘; 在多用户环境里,许多事务的提交可以用日志文件的一次 fsync()来完成.而且,日志文件是顺序写的, 因此同步日志的开销要远比同步数据页的开销要小.

  另外一个好处就是数据页的完整性.实际情况是,在 WAL 之前,PostgreSQL 从来不能保证 在崩溃的情况下数据页的完整性.在 WAL之前,在写的过程中的任何崩溃都可能导致:

  1.  索引记录指向一个不存在的表的行

  2.  索引记录在分裂操作中丢失

  3.  完全崩溃了的表和索引页的内容,因为数据页只写了一部分

  索引的问题(问题 1 和 2)可能已经通过额外的 fsync() 调用修补好了,但是如果没有 WAL,那么没有很明显的 处理第三种情况的方法;WAL 在日志里保存整个 数据页的内容 -- 如果那些内容在崩溃后的恢复中需要确保数据页的完整性的话.

  11.1.2. 更多好处

  UNDO 操作还没有实现。 这就意味着由退出的事务做的修改将仍然占据磁盘空间, 因此我们仍然需要一个永久的 pg_clog 文件保存事务的状态,因为我们不能回收事务标识符.一旦实现了 UNDO, 那么 pg_clog 就不再要求是永久的了; 我们就有可能在关闭的时候删除pg_clog. (不过,这方面的紧迫性已经随着我们对 pg_clog 采取分段存储的方法而降低了 --- 我们不再需要永久保留pg_clog 记录.)

  有了 UNDO,我们还可能实现 savepoints,这样就允许非法事务操作的部分回卷(因为误敲了命令导致的分析器错误, 插入了重复的主键/唯一键字等等)同时还能够继续或提交该事务在发生错误之前的合法操作.目前,任何错误都将使整个事务成为非法并且 要求事务退出.

  WAL 还提供了数据库在线备份和恢复(backup and restore (BAR))的新方法. 要使用这个方法,我们可能要经常性地把数据文件保存到另外一个磁盘,磁带或者另外一台主机并且还要备份 WAL 日志文件. 那么数据库文件拷贝和日志归档文件就可以用于象灾难恢复中那样恢复数据.每次做完新数据库文件以后,这个老的日志文件就可以删除了. 实现这个设施可能需要记录数据文件和索引创建和删除的日志;同时还需要开发一种方法来拷贝数据文件(操作系统拷贝命令是不合适的).

  认识这些事情的好处的一个困难是它们要求在相当可观的时间段内 保存 WAL 日志(也就是说,如果需要事务的 UNDO, 那么和可能的最长的事务的时间一样长).目前的 WAL格式的体积相当大,因为它包括多个磁盘页的镜像. 目前这还不是一个严重的问题,因为这些日志只需要保留一到两个检查点的时间间隔;但是为了实现这些东西,以后我们可能需要某种压缩的 WAL 格式.

  11.2. 实现

  在版本 7.1 以后,WAL 是自动打开的. 除了要求一些额外的磁盘空间存放 WAL 日志以及一些必要的调节以外(参阅Section 11.3) ,对管理员没有什么其他要求,

  WAL 日志存放在 $PGDATA/pg_xlog 目录里,它是作为一个文件段的集合存储的,每个段 16 MB 大. 每个段分割成 8 KB的页.日志记录头在 access/xlog.h 里描述;日志内容取决于 它记录的事件的类型.段文件的名字是自然数,从0000000000000000开始.目前这些数字不能循环使用, 不过要把所有可用的数字都用光也需要非常长的时间.

  WAL 的缓冲区和控制结构在共享内存里, 并且由后端操纵;它们是用轻量的锁保护的.对共享内存的需求 由缓冲区数量决定.缺省的 WAL 缓冲区大小是 8 个 8 KB 的缓冲区,也就是 64KB.

  日志位于和主数据库文件不同的另外一个磁盘上会比较好. 你可以通过把pg_xlog目录移动到另外 一个位置( postmaster 当然得关闭),然后在 $PGDATA 里原来的位置创建一个 指向新位置的符号链接来实现.

  WAL 的目的是确保在数据库记录被修改之前, 先写了日志,但是这个目的有可能被那些向内核谎报成功写的磁盘驱动器破坏,这时候,它们实际上只是缓冲了数据而并未把数据 存储到磁盘上.这种情况下的电源失效仍然可能导致不可恢复的数据崩溃;管理员应该确保保存 PostgreSQL 的 日志文件的磁盘不会做这种虚假汇报.

  11.2.1. 用 WAL 进行数据库恢复

  在完成一个检查点并且日志文件冲刷了之后,检查点的位置保存在了文件 pg_control 里.因此在需要做恢复的时候, 后端首先读取pg_control 和检查点记录; 然后它通过从检查点记录里标识的日志位置开始向前扫描.因为数据页的所有内容都保存在检查点之后的第一个页面修改的日志里, 所以自检查点以来的所有变化都将被恢复到一个一致的状态.

  用 pg_control 获取检查点位置可以加快恢复 进程的速度,但是为了处理 pg_control 可能 的损坏,我们实际上应该实现对现存的日志段的反向读取顺序 -- 从最新到最老 -- 这样才能找到最后的检查点.这些还没有实现.

  11.3. WAL 配置

  有几个与 WAL 相关的参数会影响数据库性能. 本节讨论它们的使用.参阅 Section 3.4 获取配置参数的细节.

检查点(Checkpoints)是事务的顺序的点, 我们保证在该点之前的所有日志信息都更新到数据文件中去了.在检查点时,所有脏数据页都冲刷到磁盘并且向日志文件中写入一条 特殊的检查点记录.结果是,在发生崩溃的时候,恢复器就知道应该从日志中的哪条记录(称做 redo 记录)开始做 REDO 操作, 因为在该记录前的对数据文件的任何修改都已经在磁盘上了.在完成检查点处理之后,任何在 undo 记录之前写的日志段都不再 需要,因此可以循环使用或者删除.(到基于 WAL 的 BAR(备份和恢复)实现的时候,这些日志在 循环利用或者删除之前将先归档.)

  postmaster 每隔一段时间就排生一个特殊的进程以创建下一个检查点. 每隔 CHECKPOINT_SEGMENTS 个日志段就创建一个检查点, 或者每隔CHECKPOINT_TIMEOUT 秒创建一个. 以先到为准.缺省设置分别是 3 个段和 300 秒. 我们也可以用 SQL 命令CHECKPOINT 强制一个检查点.

  减少 CHECKPOINT_SEGMENTS 和/或CHECKPOINT_TIMEOUT 会令检查点更频繁一些. 这样就允许更快的崩溃后恢复(因为需要重做的工作更少).不过,我们必须在这个目地和更频繁地冲刷脏数据页所带来的额外开销之间 取得平衡.另外,为了保证数据页的一致性,在每个检查点之后的第一次数据页的变化会导致对整个页面内容的日志记录.因此,检查点时间间隔 短了会导致输出到日志中的数据的增加,会抵销一部分缩短间隔的目标,并且怎么着都会产生更多的磁盘 I/O.

  至少会有一个 16MB 的段文件,而且通常不会超过 2 *CHECKPOINT_SEGMENTS + 1 个文件。你可以用这些信息来估计 WAL 需要的空间。通常,如果一个旧的日志段文件不再需要了,那么它将得到循环使用(重命名为顺序的下一个可用段)。 如果由于短期的日志输出峰值,导致了超过 2 *CHECKPOINT_SEGMENTS + 1 个段文件, 那么到系统再次回到这个限制之内的时候,多于的段文件会被删除,而不是循环使用。

  有两个常用的 WAL 函数: LogInsert 和 LogFlush. LogInsert 用于向共享内存中的 WAL缓冲区里加一条新的记录.如果没有空间存放 新记录,那么LogInsert 就不得不写出 (向内核缓存里写)一些填满了的WAL缓冲.我们可不想这样,因为 LogInsert 用于 每次数据库低层修改(比如,记录插入),都要花在受影响的数据页上持有一个排它锁的时间,因为该操作需要越快越好;更糟糕的是, 写 WAL 缓冲可能还会强制创建新的日志段, 它花的时间甚至更多.通常,WAL缓冲区应该由 一个 LogFlush 请求来写和冲刷, 在大部分时候它都是发生在事务提交的时候以确保事务记录被冲刷到永久存储器上去了.在那些日志输入量比较大的系统上, LogFlush 请求可能不够频繁,这样就不能避免 WAL 缓冲区被 LogInsert写.在这样的系统上,我们应该通过修改 postgresql.conf 的 WAL_BUFFERS 参数值来增加 WAL 缓冲区的数量.缺省的WAL 缓冲区数量是 8. 增加这个数值将有对应的共享内存使用量的增加.

  检查点是开销相当昂贵的操作,因为它们用操作系统的sync() 调用强制所有脏的内核缓冲 刷新到硬盘上。繁忙的服务器可能会很快就把检查点段文件填满,导致额外的检查点。如果这样的强制检查点发生的频率比 CHECKPOINT_WARNING秒要频繁,那么将在服务器日志里输出一条信息,建议你增加 CHECKPOINT_SEGMENTS。

  COMMIT_DELAY定义了后端在使用 LogInsert 向日志中写了一条已提交 的记录之后,在执行一次 LogFlush 之前休眠的毫秒数.这样的延迟可以允许其它的后端把它们提交的记录追加 到日志中,这样就可以用一次日志同步把所有日志冲刷到日志中.如果没有打开fsync或者当前少于 COMMIT_SIBLINGS 个其它后端处于活跃事务状态的时候则不会发生休眠;这样就避免了在其它事务一时半会不会提交的情况下睡眠. 请注意在大多数平台上,休眠要求的分辩率是十毫秒, 所以任何介于 1 和 10000微秒之间的非零 COMMIT_DELAY 的作用都是一样的. 适用这些参数的比较好的数值还不太清楚;我们鼓励你多做试验.

  WAL_SYNC_METHOD 参数决定PostgreSQL 如何 请求内核强制将 WAL 更新输出到磁盘.只要满足可靠性,那么 所有选项应该都是一样的,但是哪个最快则可能和平台密切相关. 请注意如果你关闭了 FSYNC,那么这个参数 就无所谓了.

  把 WAL_DEBUG 参数设置为任何非零值都会导致 每次 LogInsert 和 LogFlush WAL 调用都被记录到标准错误.目前,这个非零值是多少 没有什么区别.这个选项以后可能会被更通用的机制取代.



感谢中文提供者带来的方便。
分享到:
评论

相关推荐

    PostgreSQL WAL日志解析工具: wal2json

    在 PostgreSQL 中,Write-Ahead Log (WAL) 是一种重要的数据持久化机制,用于确保事务的原子性和一致性。WAL 记录了数据库的所有更改,以备在系统崩溃或需要恢复时使用。而 `wal2json` 是一个专门针对 PostgreSQL ...

    PostgresChina2018赖思超PostgreSQL10hash索引的WAL日志修改版final.pdf

    - 赖思超作为参与者之一,可能在此次会议上发表了关于PostgreSQL 10版本中Hash索引的WAL(Write-Ahead Logging)日志修改的演讲或讨论。 二、Hash索引的新特性 - PostgreSQL 10版本引入了Hash索引的WAL日志支持,...

    Internals Of PostgreSQL Wal.pdf

    PostgreSQL的WAL(Write-Ahead Logging)是数据库中一个关键的内部机制,用于确保事务的持久性和一致性。WAL机制是许多数据库系统中用来增强数据安全性的标准做法,与Oracle数据库中的REDO日志功能相似。在学习...

    PostgreSQL高可靠性(HA)與預寫式日誌(WAL)

    在确保数据安全性方面,PostgreSQL 引入了一项关键技术——预写式日志(Write-Ahead Logging,简称WAL),这对于实现高可靠性至关重要。WAL 是数据库系统中用于持久化和故障恢复的一个关键机制,其主要目标是在系统...

    MySQL和PostgreSQL的比较

    在备份与恢复方面,MySQL采用写前日志(write-ahead logging)方式,支持在线和离线的完全备份及崩溃和事务恢复,热备份需第三方软件支持。PostgreSQL同样支持在线与离线备份、崩溃、时间点和事务恢复,且能实现热...

    PostgreSQL数据库列式存储cstore_fdw插件CStoreProcessUtility函数图.eddx

    PostgreSQL数据库的列式存储cstore_fdw 钩子函数CStoreProces的函数架构思维导图,详细分析请见我的博客:https://rng-songbaobao.blog.csdn.net/

    postgresql replication源码解析。

    逻辑解码可以将数据从预写式日志的内部表示转换到复制槽想要的消费者的格式。 复制槽是逻辑复制的概念之一,一个槽代表一连串的修改,这些修改可以以它们在原始服务器上制作的顺序在客户端上重放。 输出插件是指将...

    postgresql中文手册

    postgresql8.2.3中文手册 目录 前言 何为 PostgreSQL?...27. 可靠性和预写式日志 28. 回归测试 IV. 客户端接口 29. libpq - C库 30. 大对象 31. ECPG - 在C里嵌入SQL 32. 信息模式 V. 服务器端编程

    postgresql日志部分代码分析

    本文将深入探讨PostgreSQL的日志体系,包括XLOG(事务日志)、CLOG(事务提交日志)和SUBTRANS(子事务日志)。 1. **XLOG(事务日志)**: - XLOG记录了事务对数据库进行的所有修改,以及事务的最终状态。这使得...

    PostgreSQL数据库对象名大小写敏感的解决方法

    ### PostgreSQL数据库对象名大小写敏感的解决方法 在IT领域,特别是数据库管理中,了解不同数据库管理系统(DBMS)对大小写敏感性的处理方式至关重要。本文将深入探讨PostgreSQL数据库对象名大小写敏感的问题,以及...

    java实时同步postgresql变更数据,基于WAL日志

    本文将深入探讨如何使用Java实现实时同步PostgreSQL数据库中的数据变化,基于Write-Ahead Log (WAL) 日志机制。PostgreSQL是一种功能强大的开源关系型数据库系统,它支持多种高级特性,包括WAL,这一特性使得数据库...

    PostgreSQL 8.2.3 中文文档

    可靠性和预写式日志 28. 回归测试 IV. 客户端接口 29. libpq - C库 30. 大对象 31. ECPG - 在C里嵌入SQL 32. 信息模式 V. 服务器端编程 33. 扩展 SQL 34. 触发器 35. 规则系统 36. 过程语言 37. PL...

    PostgreSQL数据库介绍

    - **预写式日志(Write-Ahead Logging, WAL)**:这是一种重要的事务管理机制,确保在发生故障时能够恢复未提交的事务。WAL通过先将事务的更改记录到日志中再应用到数据库中,确保了数据的一致性和完整性。 #### 高...

    顶级PostgreSQL DBA日常工作分享

    1. WAL(Write-Ahead Logging)机制:PostgreSQL使用预写日志进行事务的持久化,确保数据的完整性,DBA需要理解和管理WAL文件。 2. 触发器和存储过程:了解并编写触发器和存储过程,以便在数据库层面对数据进行有效...

    PostgreSQL中文手册9.2

    PostgreSQL中文学习手册 PostgreSQL PostgreSQL PostgreSQL学习手册 学习手册 学习手册 (数据表 数据表 ) 4 一、表的定义: 一、表的定义: 一、表的定义: . 4 PostgreSQL PostgreSQL PostgreSQL学习手册 学习手册...

    ubuntu12.04 配置postgresql

    在Ubuntu 12.04环境下配置PostgreSQL的过程主要包括以下几个步骤: 1. **检查系统环境**:首先确保操作系统是英文环境且字符集为UTF-8。这是为了保证PostgreSQL数据库的正常运行,因为UTF-8编码能支持多种语言,是...

    PostgreSQL博客1

    1. **WAL日志(Write-Ahead Log)**:记录所有改变数据库状态的操作,用于恢复和持久化数据。 2. **表空间**:可以有多个,包含数据库的物理文件,如表、索引等。 3. **控制文件**:存储数据库集群的元数据信息。 *...

    PostgreSQL数据库.rar

    1. **存储系统**:PostgreSQL采用WAL(Write-Ahead Logging)日志记录方式确保数据一致性,通过堆表、索引和TOAST(The Oversized-Attribute Storage Technique)机制来高效管理数据。 2. **查询解析器**:接收SQL...

    基于PostgreSQL WAL日志解析的WalMiner设计源码

    WalMiner是一个利用C语言开发的PostgreSQL WAL日志解析工具,能够从WAL日志中提取执行的SQL语句并生成相应的undo SQL。它不依赖于PostgreSQL的logical日志级别,提供了更灵活的解析方式。该项目包含72个文件,其中19...

    Postgresql修炼之道 pdf

    5. 高级特性:包括但不限于表分区、异步复制、流复制、写前日志(WAL)机制、表空间、物化视图等,这些特性使Postgresql能够应对大规模数据操作和保证数据的安全性与一致性。 6. Postgresql与编程语言的结合:...

Global site tag (gtag.js) - Google Analytics