数据库存储引擎如何保证事务 ACID?


数据库存储引擎会在事务提交后立即将更改写入磁盘吗?让我们来探讨一下:

WAL(Write Ahead Log:预写日志):
存储引擎用来提供原子性A和持久性D(ACID )的一种日志。
出于性能原因,每当事务提交时,存储引擎不会直接更改数据文件。相反,它通过将更改附加到日志文件来持久化更改,然后发出提交成功的信号。
这个过程称为预写write-ahead ,因为对数据文件的实际更改是在稍后批处理的,存储引擎只是提前写入日志文件以保证事务数据持久化。

如果这过程中间数据库崩溃,恢复过程会重做redo预写日志WAL中记录的更改操作, 这就是为什么WAL也被称为重做redo日志。

WAL 的另一个用途是变化数据捕获(CDC),因为它已经记录了所有的数据变化。例如 PostgreSQL 使用 WAL 进行逻辑复制。


事务日志Transaction log
但是,有一些数据库中WAL 是专门用于加速写入并减少初始 IO,而实现ACID 有一种专门的另外的事务日志Transaction log
事务日志也仅仅是一个只能追加的日志,它作为已提交事务的历史记录并保留着这些操作记录的顺序。

MSSQL事务日志~= Oracle重做日志~ PostgreSQL WAL

事务日志 包括:

  • undo撤消日志
  • redo重做日志

这两个实现事务边界 ACID的A、C、I属性
事务日志可以保存在内存中,但必须在提交时同步到磁盘中 ,这样才能实现ACID的D持久属性。

事务日志作用:

  • 出于性能考虑,将数据缓冲区写入磁盘会被延迟并重新排序,因为随机写入速度较慢。WAL用于加速写入
  • 崩溃后丢失的更改可以从重做日志中回滚,以恢复磁盘上的状态。
  • 磁盘上的状态可以有未完成或未提交的事务。

这就是为什么事务日志(带有undo撤消)必须 使用WAL预写日志,这样才能在崩溃发生后回滚未提交的事务。