暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL学习笔记(4)之WAL日志

北重楼 2021-04-02
1324

最近刚好听这曲子



今天记录下PostgreSQL的wal机制

先看下进程

关于持久性的概念

持久性是指,事务提交后,对系统的影响必须是永久的,即使系统意外宕机,也必须确保事务提交时的修改已真正永久写入到永久存储中。

简单来讲,我往银行存了100块钱,这个存钱流程走完了之后,银行必须保证我存的100块钱一直都在,能查询到,能取出来。

持久性如何实现

最简单的实现方法,当然是在事务提交后立即刷新事务修改后的数据到磁盘。但是磁盘和内存之间的IO操作是最影响数据库系统影响时间的,一有事务提交就去刷新磁盘,会对数据库性能产生较大影响。

WAL机制的引入,即保证了事务持久性和数据完整性,又尽量地避免了频繁IO对性能的影响。

WalWriter进程

WalWriter进程是一个后端进程,它负责确保WAL文件被正确写入磁盘,并且它的行为可以postgresql.conf中设置以下参数进行配置

    #------------------------------------------------------------------------------
    # WRITE-AHEAD LOG
    #------------------------------------------------------------------------------


    # - Settings -


    #wal_level = replica # minimal, replica, or logical
    # (change requires restart)
    #fsync = on # flush data to disk for crash safety
    # (turning this off can cause
    # unrecoverable data corruption)
    #synchronous_commit = on # synchronization level;
    # off, local, remote_write, remote_apply, or on
    #wal_sync_method = fsync # the default is the first option
    # supported by the operating system:
    # open_datasync
    # fdatasync (default on Linux)
    # fsync
    # fsync_writethrough
    # open_sync
    #full_page_writes = on # recover from partial page writes
    #wal_compression = off # enable compression of full-page writes
    #wal_log_hints = off # also do full page writes of non-critical updates
    # (change requires restart)
    #wal_init_zero = on # zero-fill new WAL files
    #wal_recycle = on # recycle WAL files
    #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
    # (change requires restart)
    #wal_writer_delay = 200ms # 1-10000 milliseconds
    #wal_writer_flush_after = 1MB # measured in pages, 0 disables
    #wal_skip_threshold = 2MB


    #commit_delay = 0 # range 0-100000, in microseconds
    #commit_siblings = 5                    # range 1-1000
    wal_level
    控制wal存储的级别。wal_level确定有多少信息被写入到WAL。默认值是replica,它添加了WAL归档信息,包括只读服务器(流复制)所需的信息。还可以将其设置为minimal,即只写入从崩溃或立即关闭中恢复所需的信息。设置为Logical允许在逻辑解码场景中完成WAL流。

    fsync
    这个参数直接控制日志是否先写到磁盘。默认值为ON(先写),这意味着系统应该通过发出wal_sync_method设置的fsync指令,来确保更改确实被刷新到磁盘。虽然关闭fsync通常可以提高性能,其直接隐患是无法保证在系统崩溃时最近的事务能够得到恢复,也就无法保证相关数据的真实与正确性

    synchronous_commit
    此参数用于配置系统是否等待WAL完全完成后再将状态信息返回给用户事务。默认值为ON,表示必须等待WAL完成后才能返回事务状态信息;配置OFF可以更快地反馈事务状态,提升性能。

    wal_sync_method
    这个参数控制WAL写入磁盘的fsync方法。默认值是fsync。可用的值包括open_datasync、fdatasync、fsync_writethrough、fsync、以及open_sync.open_datasync和open_sync,一般采用默认值即可,对于裸设备或文件系统的可选配置,在实际的使用中所带来的方便相对fsync很有限。

    full_page_writes
    指示是否将整个页面写入WAL,参数表明是否将整个page写入WAL。postgresql中数据处理过程中的位置只有内存和WAL中,在内存中的整个page中己包含更新提交的也包含没有提交的,如果不将整个page写入WAL中,在介质恢复的时候WAL中记录的数据不足以实现完整的恢复(说白了就是无法实现介质恢复时事务的回滚),写入整个page。
    说到这里似乎更明白了,postgresql中不存在类似oracle的undo文件,postgresql将前滚和回滚所需的数据都写入到了WAL。不管是否写入整个page,对数据库的PITR不影响(文档也说明了),因为更新提交肯定要写入了WAL中。。

    wal_buffers
    指示了用于存储WAL数据的内存空间量。系统默认值为64K。此参数还受wal_writer_delay和commit_delay这两个参数的影响。

    wal_writer_delay
    WalWriter进程的写入间隔。默认值是200毫秒。如果时间过长,可能会导致WAL缓冲区内存不足;如果时间太短,会导致WAL不断写入,增加磁盘I/O负担。

    wal_writer_flush_after
    当脏数据超过这个阈值时,它将被刷新到磁盘。

    commit_delay
    指示在WAL buffer中存储已提交的数据的时间。默认值为0毫秒,表示没有延迟;
    当它被设置为非零值时,在事务提交后,事务将不会被立即写入到WAL中,但它仍然存储在WAL buffer中,等待WalWriter进程定期写入磁盘。

    commit_siblings
    当事务发出提交请求时,如果数据库中的事务数量大于commit_sibling的值,事务将等待一段时间(commit_delay值);否则,事务将直接写入到WAL。系统默认值是5,这个参数还确定了commit_delay的有效性。


    WAL如何工作

    WAL机制实际是在这个写数据的过程中加入了对应的写WAL log的过程,步骤一样是先到Buffer,再刷新到Disk。

    Change发生时:

    •  先将变更后内容记入WAL Buffer

    •  再将更新后的数据写入Data Buffer

    Commit发生时:

    •  WAL Buffer刷新到Disk

    •  Data Buffer写磁盘推迟

    Checkpoint发生时:

    •  将所有Data Buffer刷新到磁盘

    Change时:


    Commit和Checkpoint时:


    非学,无以致疑,非问,无以广识~


    文章转载自北重楼,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

    评论