【导读】WAL是一种什么操作?在数据库和消息队列中为什么用到这种技术?本文对WAL做了详细介绍。
Write Ahead Logging,简称WAL,也被翻译成预写式日志,是数据库技术中实现事务日志(Transaction Journal)的一种标准方法,可以实现单机事务的原子性,同时可以提高数据库的写入效率。
思考如下场景,如何确保原子性:写操作修改数据库中a和b的值,二者是一个事务,需要把a和b的最新值持久化到磁盘,假如保存完a的值,系统宕机了,重新启动后,a的值已经写入,但b待写入的值已经丢失,如何发现事务没有完成呢?如何保证事务的原子性呢?
可以为事务加锁,也为事务增加标志位,修改完磁盘数据后,标志位设置事务为完成,事务状态保存在磁盘中,假使保存事务状态的过程中宕机了,就把事务回滚掉。实现REDO和UNDO,就能实现原子性。
数据库中针对Crash和Recovery的解决方案是WAL。
WAL的核心思想是先写日志再写数据文件,修改数据文件必须发生在修改操作记录在日志文件之后。
本文的日志指事务的操作日志,本文提到的日志都是指事务日志,不再特殊声明。
我们看WAL怎么解决宕机和恢复的问题:
如此,保证了数据的恢复和事务的原子性。
上面提到的都是写操作,看一下使用WAL时的读操作。WAL中可能包含了未写入到数据库文件中的最新值,如果读最新值就需要从WAL中读取,如果WAL中未读到,从数据库读到的就是最新的数据。
检查点:写入到WAL文件中的操作记录并不一定会立刻应用到数据库文件上,这个过程是异步的,设计检查点来记录已经被应用到数据库文件上的操作序号,检查点后面的操作记录等待被应用到数据库文件上。
WAL的作用是解决宕机和恢复的问题,同时也有其他优点:
SQLite提到了WAL的几项缺点:
WAL几乎是数据存储(数据库只是数据存储的一个类别,只不过这个类别很大)的标配:
转自:大彬
lessisbetter.site/2020/01/02/wal-introduction/
- EOF -
Go 开发大全
参与维护一个非常全面的Go开源技术资源库。日常分享 Go, 云原生、k8s、Docker和微服务方面的技术文章和行业动态。
关注后获取
回复 Go 获取6万star的Go资源库
分享、点赞和在看
支持我们分享更多好文章,谢谢!