admin管理员组文章数量:1533916
文章目录
- 数据库内容和介质的关系
- 为什么需要日志
- DBMS 要维持持久性和原子性
- 缓存区的处理策略
- Force 策略
- No steal 策略
- No Force 策略
- Steal 策略
- 什么是日志
- 缓存处理策略与日志 / 恢复策略的关系
- 日志的详细描述
- 日志的种类
- Undo 型日志
- 如何利用 Undo 型日志进行恢复
- 为什么需要检查点
- 检查点(Checkpoint)的种类
- 静止检查点
- 静止检查点进行 Undo 的日志恢复操作
- 非静止检查点
- 非静止检查点进行 Undo 的恢复操作
- Redo 型日志
- 如何利用 Redo 型日志进行恢复
- 检查点(Checkpoint)
- 检查点进行 Redo 日志恢复
- Redo/Undo 结合型日志
- 比较 Undo 和 Redo 型日志
- Undo / Redo 结合
- 如何利用 Redo / Undo 结合型日志进行恢复
- 设置检查点并使用检查点恢复
数据库内容和介质的关系
- R E A D ( X , t ) , W R I T E ( X , t ) READ(X,t), WRITE(X,t) READ(X,t),WRITE(X,t) 这两个是在内存和 DBMS 之间的操作
-
I
N
P
U
T
(
X
)
,
O
U
T
P
U
T
(
X
)
INPUT(X), OUTPUT(X)
INPUT(X),OUTPUT(X) 这两个是在内存和 外存(存储介质)之间的操作
为什么需要日志
DBMS 要维持持久性和原子性
- DBMS 需要保证事务的持久性和原子性。
- 持久性就是,事务改变了缓冲区的数据;对于已提交 commit 的数据,只在缓存区还不够,还需要持久化地放在磁盘上。对于回滚或者未提交的数据,要保证其不能放到磁盘上(磁盘不受影响)
- 原子性是要么就整个事务都成功,要么就整个事务都不成功,将整个事务作为一个原子,不可再分
缓存区的处理策略
- 最常用的是 No Force + Steal 策略的组合
Force 策略
- 内存中的数据最晚在 commit 的时候写入存储介质(磁盘)
No steal 策略
- 必须 commit 之后才能写入磁盘
No Force 策略
- 内存中(buffer)中的数据可以一直保留,commit 一段时间之后再写入磁盘(如果在延后的这段时间之内,系统发生崩溃,那么需要 Redo)
Steal 策略
- 允许事务在 commit 之前把内存中的数据写入磁盘。但是如果这时候系统在 commit 之前崩溃,但此时数据已经写入磁盘,需要恢复到崩溃前的状态,需要 Undo
什么是日志
- 只能追加
- 不同事务的日志记录交错存储
- 按发生的时间顺序
缓存处理策略与日志 / 恢复策略的关系
- No Steal 策略 + Force 策略作为缓存处理策略,是最慢的;但是通常能够保持 持久性,不需要重做,也不需要撤销
日志的详细描述
日志的种类
Undo 型日志
- Undo 型日志只保留旧值
- 必须先把事务改变的所有的值都写入磁盘,而后才能提交该事务
具体步骤
- 首先将旧值写入日志 < T , X , v > <T, X, v> <T,X,v> ( v v v 为 X X X 的旧值)
- 将 X X X 写入磁盘( O U T P U T ( X ) OUTPUT(X) OUTPUT(X))
- 将 < C O M M I T T > <COMMIT~T> <COMMIT T> 或者 < A B O R T T <ABORT~T <ABORT T> 写入 Undo 日志
- 首先要记录 Start 这个 T 的操作
- 当事务对 A 进行操作的时候,这一刻记录下 A 改变之前的值 8,同时把操作后的值 16 写入缓冲区(WRITE 操作)
- 对待 B 也是同样的
- 最后完成之后将 COMMIT 操作记录进入 Undo 日志
如何利用 Undo 型日志进行恢复
例如,如果下图的例子,故障发生于 OUTPUT(A) 和 OUTPUT(B) 之间,即 COMMIT 还没有发生,那么将会出现以下步骤:
- 沿着故障发生的位置从下往上找, < T , B , 8 > <T,B,8> <T,B,8> 恢复 B 的值 8
- 然后找到 < T , A , 8 > <T,A,8> <T,A,8> 恢复 A 的值 8
- 遇到 START 跳过
如果故障发生于 COMMIT 之后,则无需进行任何修改,因为已经写入磁盘,保证了原子性
为什么需要检查点
- 借助日志进行恢复的时候,从下往上进行恢复,遇到 COMMIT 就跳过(因为已经持久化了)
检查点(Checkpoint)的种类
静止检查点
- 必须保证当前所有活跃的事务要么提交,要么终止
- 将之前的事务 COMMIT 或者 ABORT 的日志记录写入磁盘
- 将日志的检查点记录 < C K P T > <CKPT> <CKPT> 写入日志,并再次刷新日志
- 会强制不发生新的事务,降低了效率。
静止检查点进行 Undo 的日志恢复操作
非静止检查点
- 设置检查点不必关闭系统,可以允许新事务继续进入
- 通过写入 < S T A R T C K P T ( T 1 , . . . , T k ) > <START~CKPT(T_1,...,T_k)> <START CKPT(T1,...,Tk)> 来记录所有为结束的当前的活跃事务
- 继续正常的操作,直到 ( T 1 , . . . , T k ) (T_1,...,T_k) (T1,...,Tk) 都写入完成,写入 < E N D C K P T > <END~CKPT> <END CKPT>
- 动态的检查点是一个范围,而不是一个点
非静止检查点进行 Undo 的恢复操作
- 恢复到遇到的第一个 <START~CKPT> 即可
Redo 型日志
- Redo 日志,中 < T , X , v > <T,X,v> <T,X,v> 里 v v v 的值是更新后的值。
- Redo 日志,先写
<
C
O
M
M
I
T
T
>
<COMMIT~T>
<COMMIT T> 最后写
O
U
T
P
U
T
(
X
)
OUTPUT(X)
OUTPUT(X)
如何利用 Redo 型日志进行恢复
- 将已 COMMIT 的事务进行重做
- 对未提交的不需要管,刚好与 Undo 相反
- 进行 Redo 恢复的时候,是按照从上向下的顺序对事务进行恢复的
当故障发生在 COMMIT 前:无需额外的操作,本来也不会持久化存储没有 COMMIT 的信息
事务提交之后发生故障:数据可能损失,直接加载日志中的值即可进行恢复即可
检查点(Checkpoint)
采用非静态检查点
检查点进行 Redo 日志恢复
- 从下向上找到第一个 < E N D C K P T > <END~CKPT> <END CKPT>
- 从其中回溯到每一个事务开始的位置,从上向下进行 Redo
Redo/Undo 结合型日志
比较 Undo 和 Redo 型日志
Undo / Redo 结合
- 把事务更新前和更新后的值同时保留下来 u , v u, v u,v
- 无所谓第二步和第三步,都可以
- 只要保证 < T , X , u , v > <T,X,u,v> <T,X,u,v> 先于 O U T P U T OUTPUT OUTPUT 写完即可
如何利用 Redo / Undo 结合型日志进行恢复
- 自前向后按照日志记录的正序重做所有已提交事务
- 自后向前按照日志记录的反序,撤销所有未完成事务的所有修改
- 如果
T
T
T 已经
C
O
M
M
I
T
COMMIT
COMMIT 那么将
u
u
u(旧值)写回磁盘(相当于 Undo);否则,将
x
=
v
x=v
x=v(新值)写回磁盘
故障发生在 COMMIT 之前
故障发生在 COMMIT 之后
设置检查点并使用检查点恢复
版权声明:本文标题:高级数据库系统(Advanced Database System)之:故障恢复(Fault Recovery):日志文件用于系统故障恢复(Undo, Redo, RedoUndo 型日志) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dongtai/1725749248a1040587.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论