Skip to content

日志和恢复

1、数据库的一致性概念

  • 一致状态(Consistent state:):满足所有完整性约束
  • 一致数据库:满足一致状态的数据库
  • 事务内部允许不保证DB的一致性

2、事务的基本概念、ACID和原子操作

  • 事务(transaction)概念:一个不可分割的操作序列,其中的操作要么 都做,要么都不做
  • ACID
    • 原子性(Atomicity): 事务是不可分的原子,其中的操作要么都做,要么都不做
    • 一致性(Consistency): 事务的执行保证数据库从一个一致状态转到另一个一致状态
    • 隔离性(Isolation): 多个事务一起执行时相互独立
    • 持久性(Durability): 事务一旦成功提交,就在数据库永久保存
  • 事务状态
    • 开始 <Start T> 表示事务T开始
    • 提交 <Commit T> 表示事务已经完成,并且写回磁盘持久化
    • 丢弃 <Abort T> T事物中断,所有修改取消
  • 原语操作
    • Input(x): disk block with x → memory
    • Output(x): buffer block with x → disk
    • Read(x, t)
      • do input(x) if necessary
      • t ← value of x in buffer
    • Write(x, t)
      • do input(x) if necessary
      • value of x in buffer ← t

image.png

3、WAL的概念*

Write Ahead Logging 先写日志:在数据被写到磁盘之前,对应此修改的日志记录必须已被写到磁盘上

4、Undo日志、Redo日志、Undo/Redo日志*

概述

image.png

日志类型包括:Undo日志、Redo日志、Undo/Redo日志

Undo日志<T, x, old-value>

机制

  • 在 Flash Log之前,日志仅存于内存中,还没有写到磁盘
  • 当对应的修改发生之前(Output)写到磁盘中(WAL)
  • 内存Commit也不算,Commit写到磁盘上才算成功

image.png

注意下图中,write后内存中产生commit日志,且后续先 Output 才 Flash Log 将 commit 日志写回磁盘(和redo日志不同)

image.png

恢复

  • 从头扫描日志,找出所有没有 <Commit, T>或<Abort, T>的所有事务,放 入一个事务列表L中
  • 从尾部开始扫描日志记录<T, x, v>,如果T∈ L(从后往前undo),把X写为old value
    • write(X, v)
    • output(X)
  • For each T ∈ L do(添加Abort日志)
    • write <Abort, T > to log

Redo日志<T, x, new-value>

机制

注意一点不同:在数据写回磁盘前先写<Commit, T>日志 记录!!也就是说先 Flash Log 再 Output

image.png

下图中 write之后内存中已产生 commit 日志

image.png

恢复

  • 从头扫描日志,找出所有有<Commit,T> 的事务,放入一个事务列表L中
  • 从首部开始扫描日志记录<T,x,v>,如果T∈ L,则(从前往后redo,把X写为new value)
    • write (X, v)
    • output (X)
  • For each T∈ L do(添加 Abort 日志)
    • write <Abort, T> to log

redo日志恢复的特点

commit != 写回磁盘!!!

  • 没有<Commit,T>记录的操作必定没有改写磁 盘数据,因此在恢复时可以不理会
  • 有<Commit,T>记录的结果可能还未写回磁盘 ,因此在恢复时要Redo

在undo日志中,commit 必然已经已写回磁盘

Undo/Redo日志<T, x, old-value, new-value>

  • Undo基于立即更新(Immediately Update) ——
    • write 后立即Output 把数据更新到磁盘中
    • 也可以延迟更新,但这样undo的优点发挥不出来
    • 乐观:内存代价小,恢复代价高
  • Redo基于延迟更新(Deferred Update)
    • 等所有要处理的变量都write后,在事务末尾才output更新到磁盘中
    • 悲观:恢复代价小,内存代价高

基于Undo/Redo日志的恢复

既可以延迟更新也可以立即更新

  • 正向扫描日志,将<commit>的事务放入 Redo列表中,将没有结束的事务放入 Undo列表
  • 反向扫描日志,对于<T,x,v,w>,若T在 Undo列表中,则(先Undo)
    • Write(x,v); Output(x)
  • 正向扫描日志,对于<T,x,v,w>,若T在 Redo列表中,则(后Redo)
    • Write(x,w); Output(x)
  • 对于Undo列表中的T,写入<abort,T>

5、Checkpoint

简单检查点,到达检查点时间时:

  • 中止接受新的事务
  • 等待所有正在进行的事务完成(提交/中止)
  • 将所有日志记录刷新到磁盘(日志)
  • 将所有缓冲区刷新到磁盘(数据库)
  • 在磁盘上写入“检查点”记录(日志)
  • 恢复事务处理

检查点技术保证检查点之前的所有commit操作的 结果已写回数据库,在恢复时不需REDO

日志轮转:把已经比较老的失效日志归档到廉价磁盘或者磁带

Released under the GNU General Public License v3.0.