什么是WAL
WAL全名为Write-Ahead Logging,是一种在数据库系统中用于保证数据持久性和恢复性的技术。在数据库操作中,数据的写入操作不是直接写入到磁盘中,而是先写入一个WAL日志文件,然后再写入到磁盘中。
这种方式可以有效地减少磁盘的IO操作,从而提高了数据库的性能,同时也可以降低数据丢失的风险。当数据库系统异常崩溃时,可以通过读取WAL日志文件,将数据回滚到崩溃前的状态,以确保数据的完整性。
WAL技术通常被应用在高吞吐量、高并发的数据库系统中,如PostgreSQL、MySQL等。它的主要优点包括:
提高系统写入性能:在数据写入磁盘之前,先将数据写入WAL日志文件,从而减少了磁盘的IO操作,提高了写入性能。
保证数据持久性:WAL日志文件可以确保在系统异常崩溃时,数据能够被恢复并回滚到之前的状态。
支持高并发:WAL技术可以支持多个并发事务的写入操作,从而提高了系统的并发性能。
可以实现数据备份和恢复:通过备份WAL日志文件,可以实现数据库数据的备份和恢复,从而确保数据的安全性。
总之,WAL技术是数据库系统中非常重要的一种技术,它可以提高系统的写入性能、保证数据的持久性和恢复性,同时也可以支持高并发和数据备份恢复。虽然WAL技术的实现需要付出额外的成本,但是对于高吞吐量、高并发的系统,它的优势是非常明显的。
WAL如何实现事务?
WAL(Write-Ahead Logging)是一种在数据库系统中用于保证数据持久性和恢复性的技术,也是实现事务的关键之一。WAL实现事务的方式如下:
事务的开始:当一个事务开始时,数据库会在WAL日志文件中记录一个Start Transaction(开始)的日志记录。该记录会指明事务的ID,以及该事务操作的数据库对象。
事务的执行:在事务执行过程中,数据库会在WAL日志文件中记录各种操作,如插入、更新、删除等。这些日志记录称为Update Record(更新记录)。
事务的提交:当事务提交时,数据库会在WAL日志文件中记录一个Commit Transaction(提交)的日志记录。该记录表明该事务已经完成,并且日志记录已经全部写入磁盘中,从而保证了数据的持久性和恢复性。
事务的回滚:如果一个事务需要回滚(Rollback),则数据库会在WAL日志文件中记录一个Rollback Transaction(回滚)的日志记录。该记录表明该事务已经回滚,并且相关的日志记录都要进行删除。
通过WAL技术,能够确保事务的ACID属性(Atomicity、Consistency、Isolation、Durability),从而保证了数据的完整性和一致性。另外,在性能方面,WAL技术的高性能写入操作可以有效地提高系统的吞吐量和并发性。
总之,WAL技术是一种强大的事务处理技术,可以保证数据库系统的数据持久性和恢复性,同时提高系统的性能和并发性。
WAL如何解决宕机恢复?
WAL(Write-Ahead Logging)是一种在数据库系统中用于保证数据持久性和恢复性的技术。当系统发生宕机或者其他故障时,WAL技术可以用来恢复系统数据的一致性。下面是WAL如何解决宕机恢复的过程。
恢复检查点:当数据库运行时,系统会定期创建一个检查点(Checkpoint)来记录数据库系统当前的状态。检查点是一个保存在磁盘上的WAL日志文件。在宕机恢复时,系统会首先找到最近的检查点,并且从该点开始进行恢复过程。
回退更新:恢复从检查点开始的所有已提交的事务,这个过程称为重做(Redo)。即,将所有已经写入磁盘但未提交的更新操作记录均被重复执行,以确保已提交的事务的持久性。执行这些重做必须要确定当前磁盘上缺失的页面,这可以通过检查WAL日志文件中的记录来实现。
数据库回滚:通过读取WAL日志文件中已提交的事务信息,数据库系统可以执行相反的操作来回退未提交的事务(Undo),以此来保证数据的一致性和完整性。在此期间,如果数据库中有未完成的事务,这些事务将被回滚到它们启动的时刻。
日志截断:在恢复过程结束时,数据库系统会继续记录新的事务日志,并且在WAL日志文件中删除以前已经提交并且进行过重做的日志记录,这个过程称为日志截断。通过日志截断,可以降低WAL日志文件的大小,以提高性能。
总之,WAL技术可以在系统宕机后通过检查WAL日志记录并重做已写入磁盘的操作,来保证数据的一致性和完整性。它是保障数据库持久性和恢复性最为重要的机制之一。
使用WAL为什么能提高数据库性能?
使用WAL(Write-Ahead Logging)可以提高数据库的性能,具有以下几个方面的原因:
减少磁盘IO操作:WAL技术通过将数据先写入WAL日志文件,减少了磁盘的IO操作次数。这种方式可以使得多个事务可以轻易的聚合并在一起进行写入,减少随机写入的频率,从而大幅降低了写入的时间和提高性能。
提高系统并发性:WAL技术使用了多版本控制的机制来保证数据的一致性,从而使得多个事务之间可以并发执行,提高了系统的并发性能
WAL的缺点是什么?
WAL(Write-Ahead Logging)是一种在数据库系统中用于保证数据持久性和恢复性的技术,它虽然在一定程度上提高了数据库的性能和可靠性,但也存在一些缺点和不足之处,如下所述:
存储空间占用:WAL技术会产生大量的日志数据,导致需要占用大量的硬盘空间,并且会造成一定的写入性能浪费。
增加系统复杂度:WAL技术需要对事务和日志进行管理,增加了系统的复杂度和开发难度。
系统性能下降:由于需要进行日志的追加和读取,WAL技术会造成一定的写入和读取性能下降,特别是在高并发场景下,还会增加锁竞争的情况。
可移植性差:WAL技术只有在特定的数据库系统中才能使用,而且不同的数据库系统实现方式不同,因此在不同的数据库系统之间,WAL技术的可移植性比较差。
总结来说,WAL技术虽然有其优点,但是在面对一些复杂并发场景或者需要考虑空间占用问题时,需要权衡是否使用WAL,或者是否需要通过其他方式对其不足的部分进行改进和适配。
设计并实现WAL
功能点:
Write: 创建文件,append方式写入数据(Record), Flush方式(fsync), 文件按大小分割,序号,提前创建好tmp文件,加速切换时速度
Load: 从某个序号后加载重放日志
恢复损坏的record: 最后flush前在文件末尾可能有部分损坏,要能识别有问题的record
snapshot也可以保存到wal中
优化,压缩,磁盘page
ETCD WAL实现
接口:Create(lg *zap.Logger, dirpath string, metadata []byte) (*WAL, error)
- dirpath = /path/to/dir
- 删除dirpath
- tmpdirpath=/path/to/dir.tmp
- 删除tmpdirpath
- 创建tmpdirpath
- 第一个wal文件 f=/path/to/dir.tmp/0000-0000.wal
- 创建f CREATE|WRITE
- 锁定f
- seek到文件末尾
- 预分配Preallocate 64MB空间
- 创建WAL内存对象:type WAL struct, fd, fsync,encoder/decoder locks等都保存进去
- 创建encoder,负责record的序列化,page写入,缓冲突区,size|data crc等
- 写入meta
- 写入第一个snapshot
- 重命名tmpdirpath为dirpath
- 打开父目录/path/to/, 调用fsync.把重命名的目录ITEM刷到磁盘上
- 如果上边有步骤失败,就删除dirpath和tmpdirpath
type WAL struct {
lg *zap.Logger
dir string // the living directory of the underlay files
// dirFile is a fd for the wal directory for syncing on Rename
dirFile *os.File
metadata []byte // metadata recorded at the head of each WAL
state raftpb.HardState // hardstate recorded at the head of WAL
start walpb.Snapshot // snapshot to start reading
decoder Decoder // decoder to Decode records
readClose func() error // closer for Decode reader
unsafeNoSync bool // if set, do not fsync
mu sync.Mutex
enti uint64 // index of the last entry saved to the wal
encoder *encoder // encoder to encode records
locks []*fileutil.LockedFile // the locked files the WAL holds (the name is increasing)
fp *filePipeline
}