近来碰到过几次数据库逻辑坏块的情况,经过这几次的处理和学习,个人觉得可以从原理层面做一下总结分析。
1、 DBMS是运行于OS之上的一个系统,除了像Oracle的ASM自行做I/O管理之外,其他的方式一般都要通过OS的I/O子系统来完成数据库的读写。DBMS把I/O任务交给OS的I/O子系统后其实无法保证它一定准确无误的写入数据库了,尤其是在意外断电、OS死机的情况下。
*在理论上,是否ASM方式比通过OS的I/O子系统更加可靠?
2、 数据文件的I/O是以块为基本单位的,无论事务涉及到块中的几条记录,整个块都会被读写,进而可能对块内的其他记录产生影响。
*这是整块内多条记录受影响而非发生故障时被提交的修改记录的原因。
3、 同时,DBMS的数据字典又有一套维持数据一致性的机制,在每次查询时会判断数据是否一致。
4、 DBMS为了保持高效,并不对数据文件做实时读写,而用data buffer+log buffer+log file的方式,以触发阈值的方式来批量读写数据块。
*在一定条件下,这种方式是可以保证恢复数据库的,完整备份+其后的完整日志信息,完全可以恢复到发生故障之前的那一刻。
5、 除了数据一致性,DBMS的数据字典也维护了数据库的备份历史信息。
*这个备份历史信息是决定DBMS恢复的一个重要条件
综上所述,数据库这种data buffer + log buffer + log file设计方式不保证修改的数据被及时写入数据库,以块为基本单位的I/O,失败的情况下会造成块内的所有记录受到影响,OS的I/O子系统会对数据库产生重大影响。但是,数据库设计者也是在权衡后和实践中选择的这个方案,只要设置得当,是可以修复这些逻辑坏块甚至把损坏的数据库恢复出来。
=========================================================================================
1、 SQL Server
如果有逻辑坏块,DBMS的警告日志里会有告警信息。也可以用DBCC CHECKTABLE、DBCC CHECKDB命令进行检查,定位到损坏的页及其所述的对象类型。
2、 Oracle
如果有坏块,DBMS也会告警。可以用dbv工具检查。
=========================================================================================
对于数据很重要的业务来说,就意味着无法容忍数据的丢失,这种情况建议从备份集+日志集恢复受损的块。
1、 SQL Server
DBCC CHECKTABLE、DBCC CHECKDB命令在有些时候可以修复受损的数据块,有时要付出丢失数据的代价(如果逻辑坏块的数据是索引的话,那是可以的)。
再就是FULL模式下的发生坏块之前的完全备份+该备份以来的增量备份+事务日志备份+尾日志备份来恢复。
这里的FULL/SIMPLE模式是非常关键的,直接决定了数据库可以恢复至哪个时点。
*备份之前最好做数据文件完整性校验,防止备份已损坏的数据库从而覆盖无损的备份。
2、 Oracle
可以用RMAN工具来修复数据中的坏块。这就意味着数据库必须运行于ARCHIVELOG模式,并且有完整备份集可用。