故障、恢复和备份
故障、恢复和备份简述
什么是故障
DBMS系统在运行过程中由于各种因此可能会发生一些故障。如软件代码逻辑层次、操作系统故障、计算机故障等。
什么是恢复
当DBMS发生故障后,数据可能会丢失,后续DBMS能够恢复丢失的数据。
什么是备份
预先的备份DBMS所管理的数据,避免故障导致数据丢失。
故障
事务故障
DBMS 在事务执行过程中出现故障。
- SQL 使用不正确导致的故障;如外键关联等。
- DBMS 内部错误;如死锁、并发问题等。
系统故障
系统级别的故障。
- DBMS 进程崩溃;如内存占用过高等、BUG等。
- 操作系统层面出现问题。
- 计算机崩溃;如蓝屏、死机等。
存储介质故障
数据所在的介质故障。
- 磁盘损坏;
注意:磁盘损坏导致的故障无法轻易恢复。因此只能采用复制或备份技术尽可能的实现。
恢复
为了解决故障,因此出现了恢复技术,避免故障导致的数据问题。
回滚
回滚解决了事务执行过程中出错的问题。
撤销
等同于回滚,只是表达角度不同,回滚着重于故障后的逻辑,而撤销着重于数据的恢复。
恢复
恢复解决系统故障,即系统故障发生后,DBMS重启时的记录重建。
简单写入
为了解决事务提交后,系统故障导致的数据丢失问题,DBMS可以在事务提交时 强制持久化记录数据 到磁盘。从而实现恢复。
优点:系统故障的恢复很简单,重启DBMS后什么也不用做。
缺点:性能非常差,数据很大时,磁盘IO过于耗费时间。
WAL(预写数据)
为了解决系统故障和优化强制持久化的性能问题,记录数据的写入不在事务提交时持久化,而是写入到Buffer中,由DBMS异步线程或操作系统控制。此时事务提交后,如果出现系统故障,可能会使得Buffer未完全持久化到磁盘导致数据丢失。没有解决恢复问题。
而为了实现恢复,WAL 采用 log 技术,由一个log去记录事务中的每个更新操作。当出现系统故障后,再次重启DBMS时,DBMS会 根据 log 中的事件 记录 重建 记录数据。从而实现恢复。
优点:提升了DBMS性能。
缺点:额外的log记录、系统故障后必须依赖log完成数据的恢复。
注意:log的写入必须是在记录数据持久化之前完成(通常log会使用Buffer优化) ,否则log都不完整,肯定没办法恢复。
物理日志
存储到磁盘中的日志是物理日志文件,WAL中的日志就属于此类。
逻辑日志
仅仅是逻辑层次的日志,实际实现过程中不一定是通过日志文件的方式实现。
Undo Log
为了解决事务故障,产生了undo log,undo log中记录了修改前的旧数据。undo log只是一个逻辑日志,本质实现是一个结构,存储在表中间中(数据页)。
在一些DBMS中,Undo log也用于实现MVCC技术中的版本概念。
Undo Log 实现原理
必须持久化?会丢失吗?
更新记录时:
- 更新前创建一个undo log存储到表中间中;
- 更新数据并存储回滚指针;
回滚时:
- 找到当前引用的回滚记录;
- 执行回滚;
为什么不需要 undo log buffer
Undo log只是一个逻辑日志,因此使用表空间的Buffer即可,不需要额外的Buffer。
undo log 防止丢失
undo log由于使用的是表空间,那么就是面临系统故障后的数据丢失问题,而在系统故障后事务需要回滚时,就会出现错误。
通常创建undo log时,redo log也会参与,即通过redo log保证了undo log的安全性。DBMS恢复时,也会通过 redo log 重建undo log(实际上就是表空间的数据页)。
Undo Log 什么时间被删除
事务提交后,由Purge线程删除。
Redo Log
为了解决系统故障,出现了Redo log,Redo Log记录了修改后的记录。实际上就是WAL的具体实现。记录了每一个记录数据的变更。从而在系统故障后进行数据重建。Redo log是一个物理日志,一般用单独的物理文件存储。
系统故障发生时:
- 如果 事务提交成功 ,那么 Redo Log必然持久化成功 ,即 记录肯定可以恢复;事务提交会强制持久化redo log,此时无论记录数据是否从buffer poll中持久化完成,都不影响后续的恢复重建。
- 如果 事务未提交,那么Redo Log 有可能持久化成功 ,也 可能丢失 ,而Buffer Poll可能持久化成功,也可能丢失,不过redo重放的数据和真实磁盘中的记录数据不一致也不重要,因为反正事务未提交,那么就执行undo回滚即可。
Redo Log 实现原理
更新记录时:
- 先更新Buffer Poll中的记录。
- 再添加一条redo事件日志到redo log buffer。
- 异步线程会刷新Buffer Poll和redo log buffer。
重建时:
- 根据redo日志重放。
- 如果redo重放完成后,发现一些事务未提交,那么执行undo回滚。
恢复(重建)过程
redo日志强制持久化完成后才可以返回给用户commit成功。
- 场景1:事务提交,redo log = 磁盘中的记录数据;(redo中只要事务commit,那么必然重建完整记录)
-
- 原因:redo持久化成功,buffer poll持久化成功后,此时系统故障。
- 重建:重放redo内容,由于幂等和事务已提交,因此记录数据被恢复。
- 场景2:事务提交,redo log > 磁盘中的记录数据;(redo中只要事务commit,那么必然重建完整记录)
-
- 原因:redo持久化成功时,系统故障。此时buffer poll剩余数据数据还未持久化,但有部分数据已经持久化了。
- 重建:重放redo内容,由于当前事务已经commit,因此记录数据被恢复。
- 场景3:事务未提交,redo log = 磁盘中的记录数据;(redo中只要事务没有commit,那么无论redo和记录数据是否一致,后续都会undo)
-
- 原因:系统故障后,redo log 和 磁盘记录数据持久化进程一致。
- 重建:重放redo log,回滚,因为redo中记录的事务是未提交的。
- 场景4:事务未提交,redo log > 磁盘中的记录数据;(redo中只要事务没有commit,那么无论redo和记录数据是否一致,后续都会undo)
-
- 原因:系统故障后,redo log 持久化的事件多而Buffer Poll持久化的数据少。
- 重建:重放redo log,回滚,因为redo中记录的事务是未提交的。
- 场景5:事务未提交,redo log < 磁盘中的记录数据;(redo中只要事务没有commit,那么无论redo和记录数据是否一致,后续都会undo)
-
- 原因:系统故障后,redo log 持久化的事件少,而Buffer Poll持久化的数据多。很难出现,因为redo log通常尽可能的早于Buffer Poll的持久化。如MySQL中Log Buffer没1s刷新,而Buffer Poll每30s刷新。
- 重建:重放redo log,回滚,因为redo中记录的事务是未提交的。
事务提交前记录数据是否会落库
会,WAL的实现就是 预写日志+force redo。因此在未提交时,记录数据可能部分已经在磁盘中了。如果此时系统故障,那么重建时,由于redo日志记录的操作不完整,所以还会使用undo日志回滚当前操作。
注意:redo日志并不是在记录更新后才写事件,而是在更新前后都记录一次事件。
为什么使用 redo log buffer
WAL是一个很方便的技术,但由于预先写数据情况下必须保证log的准确性,因此log一定需要先于记录数据的存储。
而在此情况下,每次log事件的物理存储都需要一次磁盘IO,所以为了优化性能,使用了buffer进行缓冲。而异步再去持久化buffer。
Log Buffer 优化了Log的存储性能,但由于异步持久化,因此事务未提交时的系统故障会使得Log内容和磁盘记录数据不一致,因此必须考虑使用undo回滚(即使一致也需要回滚,因为在用户看来,事务并没有成功) 。而事务 提交时 ,DBMS会 强制刷新log buffer,因此保证了数据的恢复。
redo log buffer 丢失数据
严格的redo由于性能,因此使用了buffer,而buffer由于在事务未提交时是异步刷新,因此在事务未提交时系统故障后,log buffer可能丢失数据,造成的结果就是log buffer和buffer poll持久化的数据不一致。
不过这种情况是可以忽略的,只需要在恢复时使用undo回滚未提交的事务数据即可,但需要保证undo不能丢失。
为什么先写 redo log buffer
基于WAL思想,预写记录数据 + Force Log。因此Log的记录就必须准确,即在持久化记录数据之前完成redo log记录。
为什么批量持久化 redo log buffer
同 ‘为什么使用 redo log buffer’ 问题一样,为了优化 额外的log 存储性能,批处理是一个很好的技术。
redo log buffer 的 flush 策略
- 每间隔一定时间;
- Log Buffer 空间不足时;
- 事务提交时;不需要每次事件都持久化,即保证了WAL的条件,又提升了性能。
- DBMS进程正常退出时;
- checkpoint时;
CheckPoint
简单理解为检查点时,DBMS需要清场。避免redo log物理文件膨胀;通常redo log都是一组用于实现高可用,太多事件则覆盖最早数据,类似于环。
备份
本地磁盘备份
使用外设硬件实现本地备份。
远程备份
一些服务器专门用于实现远程磁盘的备份。
复制
将DBMS实现为分布式系统,同时多个DBMS提供服务,通过内部通信和数据的同步、异步复制实现备份。