zoukankan      html  css  js  c++  java
  • PostgreSQL的WAL机制(转)

    转发来源:

    https://www.jianshu.com/p/a37ceed648a8

    https://www.cnblogs.com/daduxiong/archive/2010/09/30/1839533.html

    WAL:Write-Ahead Logging

    为什么进入WAL

    持久性是指,事务提交后,对系统的影响必须是永久的,即使系统意外宕机,也必须确保事务提交时的修改已真正永久写入到永久存储中。最简单的实现方法,当然是在事务提交后立即刷新事务修改后的数据到磁盘。但是磁盘和内存之间的IO操作是最影响数据库系统影响时间的,一有事务提交就去刷新磁盘,会对数据库性能产生不好影响。

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

    WAL的概念就是对数据文件的改变(包括表和索引)必须先写入日志,即日志记录刷新到永久储存之后,才能被写。遵循这个过程,就不需要在每个事务提交时都刷新数据页到磁盘,因为在宕机时可以用日志来恢复数据库:任何没有应用到数据页上的改动都可以根据日志记录重做。

    WAL如何工作?

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

    Change发生时:

    •  先将变更后内容记入WAL Buffer
    •  再将更新后的数据写入Data Buffer

    Commit发生时:

    •  WAL Buffer刷新到Disk
    •  Data Buffer写磁盘推迟

    Checkpoint发生时:

    •  将所有Data Buffer刷新到磁盘

    Change时:

    Commit和Checkpoint时

     WAL的好处?

    使用WAL可以显著地减少写磁盘的次数,因为只需要把日志文件刷新到磁盘就可以保证事务被提交,而不需要把事务改动过的每一个数据文件都刷新到磁盘。日志文件是连续写的,所以同步log的花销远小于刷新数据页的花销。特别是服务器要处理涉及数据存储不同部分的大量小事务时更是这样。另外,当服务器在处理大量并行小事务时,log文件一次fsync就可以提交多个事务。

    WAL还使得在线备份和时间点恢复成为可能。通过归档WAL数据,我们可以恢复到WAL数据覆盖范围内的任何时间点:只需install一份数据库的物理备份,并恢复WAL日志到所需时间即可。更重要的是,这个物理备份并不必须是一个数据库状态的瞬时快照—如果一段时间的快照,那把WAL日志也恢复成那一段时间的即可。

    WAL的配置参数:

    • fsync:该参数直接控制日志是否先写入磁盘。默认值是ON(先写入)。开启该值时表明,更新数据写入磁盘时系统必须等待WAL的写入完成。可以配置该参数为OFF,更新数据写入磁盘完全不用等待WAL的写入完成,没有了等待的时间,显然接下来的工作能够更早的去做,节省了时间,提高了性能。其直接隐患是无法保证在系统崩溃时最近的事务能够得到恢复,也就无法保证相关数据的真实与正确性。
    • synchronous_commit:参数表明是否等待WAL完成后才返回给用户事务的状态信息。默认值是ON,表明必须等待WAL完成后才返回事务状态信息。配置OFF值能够更快的反馈回事务状态。因参数只是控制事务的状态反馈,因此对于数据的一致性不存在风险。但事务的状态信息影响着数据库的整个状态。该参数可以灵活的配置,对于业务没有严谨要求的事务可以配置为OFF,能够为系统的性能带来不小的提升。
    • wal_sync_method:WAL写入磁盘的控制方式,默认值是fsync。可选用值:open_datasync,fdatasync,fsync_writethrough,fsync,open_sync。
    • full_page_writes:表明是否将整个page写入WAL。
    • wal_buffers:用于存放WAL数据的内存空间。系统默认值是64K,执行一个大的事务肯定受到影响,应该适当的增大该参数。类似oracle中的log buffer。该参数还受以下几个参数影响。
    • wal_writer_delay:WAL writer进程的间歇时间。默认值是200ms。准确的配置应该根据自身系统的运行状况。如果时间过长可能造成WAL buffer的内存不足;反之过小将会引起WAL的不断的写入,对磁盘的IO也是很大考验。
    • commit_delay:表示了一个已经提交的数据在WAL buffer中存放的时间,单位ms,默认值是0,不用延迟。非0值表示可能存在多个事务的WAL同时写入磁盘。如果设置为非0,表明了某个事务执行commit后不会立即写入WAL中,而仍存放在WAL buffer中,这样对于后面的事务申请WAL buffer时非常不利,尤其是提交事务较多的高峰期,可能引起WAL buffer内存不足。如果内存足够大,可以尽量延长该参数值,能够使数据集中写入这样降低了系统的IO,提高了性能。同样如果此时崩溃数据面临着丢失的危险。个人建议采用默认值,同时将WAL文件存放在IO性能好的磁盘上。
    • commit_siblings:该参数非常有意思,该参数还决定了commit_delay的有效性。系统默认值是5。表示当一个事务发出提交请求,此时数据库中正在执行的事务数量大于5,则该事务将等待一段时间(commit_delay的值),反之,该事务则直接写入WAL。
  • 相关阅读:
    数据结构课后
    idea 使用java 链接sqlservice 2008
    超链接 a href 提交表单通过post方式
    课程主页之课程接口
    课程主页之课程表数据
    课程表分析
    课程前端简单页面
    前台的登录注册
    ORM常用字段及参数与查询 -刘
    Celery配置与使用
  • 原文地址:https://www.cnblogs.com/yickel/p/11143093.html
Copyright © 2011-2022 走看看