小资说库第11期 什么是WAL日志?WAL日志存在的理由是什么?

网友投稿 1241 2022-05-28

我在想,这节的标题叫“通过什么机制可以保证事务持久化的可靠性?”是否更合适。但是鉴于大家听到WAL日志这个概念比较多,我还是决定把标题写成现在的样子。

什么是WAL日志

预写式日志(Write-ahead logging,缩写 WAL)是关系数据库系统中用于提供原子性和持久性(ACID属性中的两个)的一系列技术。

为什么要使用WAL日志的生动说明

https://blog.csdn.net/WinWill2012/article/details/71719106

预写日志(WAL,Write Ahead Log)是关系数据库系统中用于提供事务原子性和持久性(ACID属性中的两个)的一系列技术。简单来说就是,做一个操作之前先将这件事情记录下来。

举个例子:很多人都会有自己的备忘录,记录自己干了哪些事,这里的WAL日志就好比备忘录,记录了你做了哪些操作。

为什么要使用WAL呢?比如你的备忘录里面有如下记录:

【小资说库】第11期 什么是WAL日志?WAL日志存在的理由是什么?

2015.12.25 理发

2015.12.28 整容

2015.12.31 修指甲

如果某一天你忘记了自己是如何变成现在这个样子的,那你可以去翻看你的备忘录,然后按照备忘录的记录依次执行,你就能找到答案。

为什么要使用WAL呢?上面的解释比较秀逗,本节说一下真正的原因:真正的执行操作可能数据量会比较大,操作比较繁琐,并且写数据不一定是顺序写,所以如果每一次操作都要等待结果flush到可靠存储(比如磁盘)中才执行下一步操作的话,效率就太低了。换一种思路,如果我们在做真正的操作之前,先将这件事记录下来,持久化到可靠存储中(因为日志一般很小,并且是顺序写,效率很高),然后再去执行真正的操作。这样执行真正操作的时候也就不需要等待执行结果flush到磁盘再执行下一步,因为无论在哪一步出错,我们都能够根据备忘录重做一遍,得到正确的结果。

为什么需要WAL日志的技术解释

PostgresSQL“可靠性和预写式日志”一节对WAL日志存在的理由给出了很好的说明。摘抄和整理如下,更详细地可以访问链接进行了解。

一句话总结就是,计算机主存和磁盘盘片间存在多层高速缓存,不仅写的慢,而且加大了将数据直接写到盘片(实现永久存储)这一过程中因失去电力、操作系统失败以及硬件失败等带来的数据丢失风险。

http://www.postgres.cn/docs/10/wal.html

可靠性是任何严肃的数据库管理系统的重要属性。可靠性的一个重要方面就是:一个已提交事务记录的所有数据应该被存储在一个非易失的区域, 这样就不会因为失去电力、操作系统失败以及硬件失败(当然,除了非易失区域自身失效之外)等原因导致的数据丢失。 向计算机的永久存储(磁盘驱动器或者等效的设备)成功写入数据通常可以满足这个要求。 实际上,即使计算机受到致命损坏,只要磁盘驱动器幸存下来,那么它们就可以被移动到另外一台具有类似硬件的计算机上, 而所有已经提交的事务将保持原状。

周期地强制数据进入磁盘盘片看上去像一件简单的操作,但实际上并非如此。 因为磁盘驱动器比内存和CPU要慢很多,在计算机的主存和磁盘盘片之间存在多层的高速缓存。

首先存在的就是操作系统的高速缓存,该缓存经常缓冲常用的磁盘块且经常合并对磁盘的写入。 幸运的是,所有操作系统都给予应用一种强制从高速缓存写入磁盘的方法,PostgreSQL则使用了那个特性(参阅wal_sync_method参数调节如何完成之)。

然后就是磁盘驱动器的控制器上可能还有一个高速缓存;这在RAID控制卡上是特别常见的。有些高速缓存是直写式的,即写入动作在到达的时候就立刻写入到磁盘上。其它是回写式的, 即发送给驱动器的数据在稍后的某个时间写入驱动器。这样的高速缓存可能会称为可靠性灾难,因为磁盘控制器高速缓存的内存是易失性的,在发生电力失败的情况下会丢失其内容。 好一些的控制器卡有后备电池单元(BBU), 即这种卡上面有电池可以在系统电力失败的情况下提供电力。 在电力恢复之后,这些数据将会被写入磁盘驱动器。

最后,大多数磁盘驱动器都有高速缓存。有些是直写的,有些是回写的, 和磁盘控制器一样,回写的磁盘高速缓存也存在数据丢失的问题。 消费级别的IDE和SATA驱动器尤其可能包含回写式高速缓存,在掉电的情况下很容易丢失数据。很多固态驱动器(SSD)也具有易失性回写式高速缓存。

这些高速缓存通常可以被禁用,但是不同的操作系统和驱动器类型有不同的做法:

l   在Linux上,可以使用hdparm -I查询IDE和SATA驱动器,如果在Write cache之后有一个*则表示写高速缓存被启用。可以用hdparm -W 0来关闭写高速缓存。可以使用sdparm查询SCSI驱动器。使用sdparm --get=WCE来检查写高速缓存是否被启用,而sdparm --clear=WCE可以用来禁用它。

l   在FreeBSD上,IDE驱动器可以使用atacontrol查询,而写高速缓存可以用/boot/loader.conf中的hw.ata.wc=0关闭。SCSI驱动器可以使用camcontrol identify查询,而写高速缓存的查询和更改都可以使用sdparm。

l   在Solaris上,磁盘的写高速缓存被format -e控制(Solaris的ZFS文件系统对于开启的磁盘写高速缓存是安全的,因为它会发出它自己的磁盘高速缓存刷写命令)。

l   在Windows上,如果wal_sync_method是open_datasync(默认值),写高速缓存可以通过取消选中My Computer\Open\disk drive\Properties\Hardware\Properties\Policies\Enable write caching on the disk禁用。另一种方法可以通过设置wal_sync_method为fsync或fsync_writethrough来阻止写高速缓存。

l   在macOS上,通过设置wal_sync_method为fsync_writethrough可以阻止写高速缓存。

数据库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:放苹果
下一篇:Windows Server 存储空间之存储分层和缓存管理
相关文章