Logging
Failure Classification
Crash Recovery
恢复算法是确保数据库一致性、事务原子性和在故障情况下持久性的技术。
- 正常txn处理期间的操作,以确保DBMS能够从故障中恢复
- 将数据库恢复到确保原子性、一致性和持久性的状态失败后的操作。
根据底层存储设备将DBMS划分成不用的组件:溢失和非溢失
- 溢失 : 掉电或程序退出后,数据不会保持。
- 非溢失:掉电或程序退出后,数据会保持
还必须对DBMS需要处理的不同类型的故障进行分类。
- Tnx 故障
- 逻辑错误:由于某些内部错误条件(例如,违反完整性约束),事务无法完成。
- 内部状态错误:DBMS由于错误条件(例如,死锁)而终止活动事务。
- 系统故障
- 软件错误:操作系统或DBMS实现的问题(例如,未捕获的除以零异常)。
- 硬件错误:执行DBMS的计算机崩溃(操作系统或DBMS实现的问题(例如,未捕获的除以零异常)。)
故障停止假设:假设非易失性存储内容不会因系统崩溃而损坏
- 存储介质故障
- 不可修复硬件故障:磁头崩溃或类似的磁盘故障会破坏全部或部分非易失性存储。
假定破坏是可检测的(例如,磁盘控制器使用校验和检测故障)。
- 不可修复硬件故障:磁头崩溃或类似的磁盘故障会破坏全部或部分非易失性存储。
没有DBMS可以从中恢复!必须从存档版本恢复数据库。
数据库的主存储位置在非易失性存储上,但这比易失性存储慢。使用易失性内存以加快访问速度
- 首先将目标记录复制到内存中。
- 在内存中执行写入。
- 将脏记录写回磁盘。
DBMS需要确保以下几点:
- 一旦DBMS告诉某人它已提交,任何txn的更改都是持久的。
- 如果txn中止,则没有部分更改是持久的。
Buffer Pool Policies
Steal Policy和Force Policy是两个描述数据库管理系统(DBMS)如何处理缓冲池的术语,缓冲池是内存空间,用于缓存数据页以提高访问速度。这些策略影响了DBMS的性能、一致性和恢复。
Undo VS Redo
Undo : 消除不完整的或中止的txn影响的过程
Redo:重新执行的txn的效果以获得持久性的过程
DBMS如何支持此功能取决于它如何管理缓冲池
Steal Policy
DBMS是否允许未提交的txn覆盖非易失性存储中对象的最新提交值。
- Steal : Is allowed
- No-Steal : Is not allowed
steal Policy决定了DBMS是否允许事务在提交之前将其修改的页面写入磁盘。如果策略是steal,那么DBMS可以从缓冲池中驱逐(steal)脏页,以便为其他页面腾出空间,即使修改它们的事务还没有提交。这可以提高缓冲区的利用率,减少页面错误的次数,但也需要DBMS维护撤销日志,以便在事务中止或系统故障时回滚更改。如果策略是no-steal,那么DBMS不会将任何未提交的更改写入磁盘,并将它们保留在缓冲池中,直到事务提交。这避免了撤销日志和回滚的需要,但也限制了缓冲区的空间,并增加了页面错误的可能性。
Force Policy
DBMS是否要求txn所做的所有更新在txn可以提交之前都反映在非易失性存储上
- Force : Is required
- No-Force : Is not Required
Force Policy决定了DBMS是否强制事务在提交时将其修改的页面写入磁盘。如果策略是force,那么DBMS确保已提交事务的所有脏页立即刷新到磁盘。这可以保证事务的持久性和原子性,但也增加了磁盘I/O开销和降低了吞吐量。如果策略是no-force,那么DBMS不要求事务在提交时将其更改写入磁盘,并允许它们保留在缓冲池中,直到被其他页面驱逐。这可以减少磁盘I/O成本和提高性能,但也需要DBMS维护重做日志,以便在系统崩溃时重放更改。
现代DBMSs最常用的策略组合是steal/no-force(WAL),这意味着未提交的更改可以写入磁盘,但已提交的更改不必立即写入。这种组合可以实现高性能和并发性,但也需要同时使用撤销和重做日志来进行恢复。下表总结了不同策略组合的优缺点:
策略 | 优点 | 缺点 |
---|---|---|
Steal/Force | 恢复简单 | 磁盘I/O成本高 |
Steal/No-Force | 性能和并发性高 | 需要同时使用撤销和重做日志 |
No-Steal/Force | 不需要撤销日志 | 缓冲区利用率低,页面错误多 |
No-Steal/No-Force | 不需要任何日志 | 无法从故障中恢复 |
Shadow Paging
DBMS不复制整个数据库,而是在写入时复制页面,以创建两个版本:
Master:仅包含来自已提交txns的更改。
Shadow : 临时数据库,其中包含从未提交的txns进行的更改。
要在txn提交时安装更新,请覆盖根,使其指向阴影,从而交换主文件和阴影。
它相当于Buffer Pool Policies中的No-steal + Force
很容易支持回滚和恢复。
Undo:删除阴影页。让主指针和DB根指针单独使用。
Redo:根本不需要。
缺点
复制整个页表的成本很高:
- 使用结构类似B+树(LMDB)的页表。
- 不需要复制整个树,只需要复制树中导致更新叶节点的路径。提交开销高
提交开销高:
- 刷新每个更新的页面、页表和根。
- 数据被碎片化(不适合顺序扫描)。
- 需要垃圾收集。
- 一次只支持一个写入器txn或批处理中的txns
当txn修改页面时,DBMS在覆盖主版本之前将原始页面复制到单独的日志文件中。
重新启动后,如果日志文件存在,则DBMS将将其恢复以撤消未提交的txns中的更改。
Shadow Paging要求DBMS对磁盘上的随机非连续页执行写入
我们需要一种DBMS将随机写入转换为顺序写入的方法
Write-Ahead Log
维护一个与包含txns对数据库所做更改的数据文件分开的日志文件。
- 假设日志在稳定存储上
- 日志包含足够的信息来执行必要的撤消和重做操作以恢复数据库
DBMS必须将与对数据库对象所做的更改相对应的日志文件记录写入磁盘,然后才能将该对象刷新到磁盘。
Buffer Pool Policy: STEAL + NO-FORCE
Write-Ahead Log(WAL)是一种保证数据完整性的标准方法,它的基本原理是在对数据库进行修改之前,先将修改的内容记录在一个日志文件中,然后再应用到数据库中。这样,即使发生系统崩溃或事务中止,也可以通过重放或回滚日志来恢复数据库的一致性。
Write-Ahead Log有以下几个主要功能:
- 允许缓冲池缓存磁盘上的数据页的更新,同时在数据库系统的更大范围内保证持久性。
- 在缓存的数据页被同步到磁盘之前,将所有操作持久化到磁盘上。
- 每个修改数据库状态的操作都必须在相关页面的内容被修改之前写入日志。
- 在发生崩溃时,允许从操作日志中重建丢失的内存中的更改。
Write-Ahead Log通常包含了重做和撤销信息,以便在不同的情况下进行恢复。重做信息用于在系统崩溃后重新执行已提交事务的更改,撤销信息用于在事务中止或回滚时取消未提交事务的更改。为了提高效率和减少开销,Write-Ahead Log通常采用一些优化技术,如分段日志、检查点、压缩、分组提交等。
Write-Ahead Log是一种广泛应用于数据库系统中的技术,它可以看作是事件溯源(Event Sourcing)架构的一种实现,其中系统的状态是由初始状态经过一系列事件演变而来的。许多现代文件系统也使用了WAL的变体来至少保证文件系统元数据的完整性,这被称为日志式文件系统(Journaling File System)。
WAL Protocol
为每个txn向日志中写入记录,以标记其起点。
当txn完成时,DBMS将:
- 在日志中写入记录
- 确保在向应用程序返回确认之前刷新所有日志记录。
每个日志条目都包含有关对单个对象的更改的信息
- Txn id
- Object Id
- Before Value(为了Undo)
- After Value(为了Redo)
WAL Implementation
每次txn提交时将日志缓冲区刷新到磁盘将成为瓶颈。
DBMS可以使用组提交优化将多个日志刷新批处理在一起,以摊销开销。
- 当缓冲区已满时,将其刷新到磁盘
- 或者如果有超时
Logging Schemes
- Physical Logging
- 记录对特定页面所做的字节级更改。
- Logial Logging
- 记录txns执行的高级操作
- Physiological Logging
- 混合方法,对由页ID+插槽号标识的单个元组进行字节级更改。
- 不指定页面的组织
Physical VS Logical Logging
逻辑日志记录需要在每个日志记录中写入的数据比物理日志记录少。
如果并发txns在较低的隔离级别运行,则很难使用逻辑日志记录实现恢复。
- 很难确定数据库的哪些部分可能在崩溃前被查询修改。
- 恢复也需要更长的时间,因为您必须重新执行每个txn。
日志结构的DBMS没有脏页。
脏页是指缓冲池中已经被修改但还没有写回磁盘的数据页,它们可能与磁盘上的数据不一致。日志结构的DBMS是一种使用Write-Ahead Log(WAL)技术的数据库系统,它的基本原理是在对数据库进行修改之前,先将修改的内容记录在一个日志文件中,然后再应用到数据库中。这样,即使发生系统崩溃或事务中止,也可以通过重放或回滚日志来恢复数据库的一致性。
日志结构的DBMS没有脏页的原因是它们使用了in-place方式更新数据文件,即直接覆盖原有的数据,而不需要创建新的副本。这可以减少索引和块列表的修改,提高空间利用率和性能。由于每次修改数据都会先写入日志文件,所以缓冲池中的数据页始终与磁盘上的数据页保持一致,不会出现脏页。
DBMS将日志记录缓存在内存页(MemTable)中。如果此缓冲区已满,则必须将其刷新到磁盘。但它可能包含未提交的更改txns。这些DBMS仍然维护一个单独的WAL,以在崩溃时重新创建MemTable。
Checkpoints
WAL将永远成长。
崩溃后,DBMS必须Back整个日志,这将需要很长时间
DBMS定期采取checkpoints,将所有缓冲区刷新到磁盘。这提供了一个提示,说明它需要在崩溃后Back WAL多远。
阻止/一致检查点协议:
- 暂停所有查询。
- 将内存中的所有WAL记录刷新到磁盘。
- 将缓冲池中所有修改的页面刷新到磁盘。
- 将< Checkpoints >条目写入WAL并刷新到磁盘。
- 恢复查询。
DBMS必须在采取检查点时停止txns,以确保快照一致。
扫描日志以查找未提交的txns可能需要很长时间。