日志和恢复
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 → memoryOutput(x)
: buffer block with x → diskRead(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
3、WAL的概念*
Write Ahead Logging 先写日志:在数据被写到磁盘之前,对应此修改的日志记录必须已被写到磁盘上
4、Undo日志、Redo日志、Undo/Redo日志*
概述
日志类型包括:Undo日志、Redo日志、Undo/Redo日志
Undo日志<T, x, old-value>
机制
- 在 Flash Log之前,日志仅存于内存中,还没有写到磁盘
- 当对应的修改发生之前(Output)写到磁盘中(WAL)
- 内存Commit也不算,Commit写到磁盘上才算成功
注意下图中,write后内存中未产生commit日志,且后续先 Output 才 Flash Log 将 commit 日志写回磁盘(和redo日志不同)
恢复
- 从头扫描日志,找出所有没有 <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
下图中 write之后内存中已产生 commit 日志
恢复
- 从头扫描日志,找出所有有<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
日志轮转:把已经比较老的失效日志归档到廉价磁盘或者磁带