数据库控制文件损坏文件损坏了 恢复硬盘可以吗

Oracle数据库恢复:数据块损坏与恢复详解
查看: 3935|
摘要: 所谓损坏的数据块,是指块没有采用可识别的 Oracle 格式,或者其内容在内部不一致。通常情况下,损坏是由硬件故障或操作系统问题引起的。Oracle 数据库将损坏的块标识为“逻辑损坏”或“介质损坏”。
1.什么是块损坏:
所谓损坏的数据块,是指块没有采用可识别的 Oracle 格式,或者其内容在内部不一致。通常情况下,损坏是由硬件故障或操作系统问题引起的。Oracle 数据库将损坏的块标识为“逻辑损坏”或“介质损坏”。如果是逻辑损坏,则是 Oracle 内部错误。Oracle 数据库检测到不一致之后,就将逻辑损坏的块标记为损坏。如果是介质损坏,则是块格式不正确;从磁盘读取的块不包含有意义的信息。
通过恢复块,或者删除包含损坏块的数据库对象(或同时采用这两种方式),可以修复介质损坏的块。如果介质损坏是由硬件故障引起的,则只有修复了硬件故障后,才能彻底解决问题。
只要对块执行读或写操作,就会执行下列一致性检查:
--高速中的 DBA(数据块地址)值与块缓冲区中的 DBA 值比较的结果
--块校验和(如果启用)
损坏的块被标识为以下类别:
--介质损坏
--逻辑(或软件)损坏
2.块损坏故障现象:ORA-01578
ORA-01578 错误:“ORACLE data block corrupted (file # %s, block # %s)”:
--发现损坏的数据块时生成此信息
--始终返回相对文件号和块号
--返回到发出查询的会话(该查询在发现损坏时执行)
--显示在 alert.log 文件中
一般情况下,ORA-01578 错误是由硬件问题引起的。如果 ORA-01578 错误始终返回相同的参数,则最可能的原因是块介质损坏。
如果返回的参数每次都有变化,则可能存在硬件问题。应检查和页面空间,并检查 I/O 子系统,以便查找有问题的控制器。
注:ORA-01578 会返回相对文件号,但随之出现的 ORA-01110 错误会显示绝对文件号。
3.如何处理损坏
--检查预警日志和操作系统日志文件。
--使用可用的诊断工具,找出损坏的类型。
--多次运行检查功能,确定错误是否持续存在。
--根据需要,从损坏的对象中恢复数据。
--解决硬件问题:
磁盘控制器、
--根据需要,从损坏的对象中恢复或还原数据。
始终尝试确定错误是否持续出现。多次运行 ANALYZE 命令;如果可能,可执行关闭再启动操作,然后再次尝试早先发生故障的操作。查找是否有其它损坏。如果发现一个损坏的块,则可能还存在其它损坏的块。
硬件故障必须立即解决。遇到硬件问题时,应与供应商取得联系,在检查并修复了计算机后再继续工作。此时应运行一次全面的硬件诊断会话。
硬件故障的类型可能会有很多种:
--I/O 硬件或故障
--操作系统
--I/O 或高速缓存问题
--内存或分页问题
--磁盘修复实用程序
4.实时验证块完整性:DB_BLOCK_CHECKING :
可通过将 DB_BLOCK_CHECKING 初始化参数设置为 TRUE 启用数据库块检查。只要修改了数据块或索引块,此项检查就会检查数据块和索引块的内部一致性。DB_BLOCK_CHECKING 是一个动态参数,可使用 ALTER SYSTEM SET 语句修改此参数。对于系统表空间,将始终启用块检查。块检查通常会产生 1% 到 10% 的开销,具体取决于工作量。正在执行的更新或插入操作越多,执行块检查的开销就会越高。DB_BLOCK_CHECKING 有以下四个可能的值:
--OFF:除 SYSTEM 之外的所有表空间都不执行块检查。
--LOW:在内存中块的内容发生更改之后(例如,在执行 UPDATE 或 INSERT 语句以及在执行磁盘上读取后),执行基本的块头检查。
--MEDIUM:执行所有 LOW 检查, 对所有不是按索引组织的表块执行语义块检查。
--FULL:执行所有 LOW 和 MEDIUM 检查, 对索引块执行语义检查。
初始化参数 DB_BLOCK_CHECKING:
--在对每个块执行自我一致性检查时,控制检查的处理程度
--可防止内存和数据损坏
--可使用 ALTER SESSION 命令或 ALTER SYSTEM DEFERRED 命令进行设置
5.块介质恢复
大多数情况下,第一次遇到损坏时,数据库会将块标记为介质损坏,然后将其写到磁盘上。在该块得到恢复之前,不能对其执行任何后续读取操作。只能对标记为损坏或者未通过损坏检查的块执行块恢复。可使用 RMAN RECOVER...BLOCK 命令执行块介质恢复。默认情况下,RMAN 会在闪回日志中搜索好的块副本,然后在完全备份或 0 级增量备份中搜索块。如果 RMAN 找到了好的副本,则会还原这些副本,并对块执行介质恢复。块介质恢复只能将重做日志用于介质恢复,不能使用增量备份。
V$DATABASE_BLOCK_CORRUPTION 视图显示由数据库组件(如 RMAN 命令、ANALYZE、dbv、SQL 查询等)标记为损坏的块。对于以下类型的损坏此视图会增加相应的行:
--物理/介质损坏:数据库无法识别块:校验和无效、块内容全部为零或者块头不完整。默认情况下,物理损坏检查处于启用状态。
--逻辑损坏:块的校验和有效,块头和块尾也匹配,但是内容不一致。块介质恢复不能修复逻辑块损坏。默认情况下,逻辑损坏检查处于禁用状态。通过指定 BACKUP、RESTORE、RECOVER 和 VALIDATE 命令的 CHECK LOGICAL 选项,可以启用逻辑损坏检查。
块介质恢复:
--降低平均恢复时间 (MTTR)
--提高介质恢复期间的可用性
--恢复期间数据文件保持联机状态
--只有正在恢复的块是不可访问的
--使用 RMAN RECOVER...BLOCK 命令调用
--使用闪回日志以及完全备份或 0 级备份还原块
--使用重做日志执行介质恢复
--V$DATABASE_BLOCK_CORRUPTION 视图显示标记为损坏的块
6.块介质恢复的先决条件
--目标数据库必须处于 ARCHIVELOG 模式
--包含损坏块的数据文件的备份必须是完全备份或 0 级备份。
--要使用代理副本,必须先将它们还原到非默认位置
--RMAN 只能使用归档的重做日志进行恢复
--要使用闪回日志,必须启用闪回数据库
以下先决条件适用于 RECOVER ... BLOCK 命令:
--目标数据库必须以 ARCHIVELOG 模式运行,并且必须是打开的,或是使用当前控制文件装载的。
--包含损坏块的数据文件备份必须是完全备份或 0 级备份,不能是代理副本。如果只存在代理副本备份,则可将它们还原到磁盘上的非默认位置;在这种情况下,RMAN 会认为它们是数据文件副本,在块介质恢复过程中会在其中搜索块。
--RMAN 只能使用归档的重做日志进行恢复。RMAN 不能使用 1 级增量备份。块介质恢复不能恢复丢失或无法访问的归档重做日志,但有时可以恢复丢失的重做记录。
--必须在目标数据库上启用闪回数据库,这样 RMAN 才能在闪回日志中搜索损坏块的好副本。如果启用了闪回事件记录,并且此事件记录包含损坏块的较旧但未损坏的版本,则 RMAN 可以使用这些块,因而可能会提高恢复的速度。
7.RECOVER...BLOCK 命令
--确定包含要进行恢复的块的备份
--读取备份并将请求的块累积到内存缓冲区
--必要时,通过从备份中读取归档日志来管理块介质恢复会话
RECOVER DATAFILE 6 BLOCK 3; Recover a single block
RECOVER Recover multiple blocks
DATAFILE 2 BLOCK 43 in multiple data files
DATAFILE 2 BLOCK 79
DATAFILE 6 BLOCK 183;
RECOVER CORRUPTION LIST; Recover all blocks logged in V$DATABASE_BLOCK_CORRUPTION
恢复单个块:
在进行块恢复之前,必须确定损坏的块。一般情况下,会在以下位置中报告块损坏:
--LIST FAILURE、VALIDATE 或 BACKUP ...VALIDATE 命令的结果
--V$DATABASE_BLOCK_CORRUPTION 视图
--标准输出中的错误消息
--预警日志文件和用户跟踪文件(在 V$DIAG_INFO 视图中标识)
--SQL ANALYZE TABLE 和 ANALYZE INDEX 命令的结果
--DBVERIFY 实用程序的结果
例如,可能会在用户跟踪文件中发现以下消息:
ORA-01578: ORACLE data block corrupted (file # 7, block # 3)
ORA-01110: data file 7: '/oracle/oradata/orcl/tools01.dbf'
ORA-01578: ORACLE data block corrupted (file # 2, block # 235)
ORA-01110: data file 2: '/oracle/oradata/orcl/undotbs01.dbf'
--确定了块以后,在 RMAN 提示符下运行 RECOVER ...BLOCK 命令,指定损坏块的文件号和块编号。
DATAFILE 7 BLOCK 3
DATAFILE 2 BLOCK 235;
8.使用10231事件进行处理:(块损坏但没有备份,没办法回复的情况下)
在sqlplus中执行如下命令:
ALTER SYSTEM SET EVENTS='10231 trace name context forever,level 10';
然后导出该表:
exp test/test file=t.dmp tables=t;
在数据库中删除该表
drop table t;
imp test/test file=t.dmp tables=t;
最后关闭10231事件:
ALTER SYSTEM SET EVENTS='10231 trace name context off';
上一篇:下一篇:用户名:张宇
文章数:218
评论数:740
访问量:1233005
注册日期:
阅读量:1297
阅读量:3317
阅读量:429721
阅读量:1117667
51CTO推荐博文
作者:,北亚中心,转载请联系作者,如果实在不想联系作者,至少请保留版权,谢谢。
RAID中对单盘做镜像的方式(以SAS硬盘为例):
-、关闭磁盘阵列,将所有硬盘依次拔下来(最好标记好顺序号),挂接在不含RAID功能的SAS适配器上。
下图为拔下硬盘的正面及背面图(SAS硬盘有2.5与3.5寸两种接口,图中为3.5寸)
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
下图为其接口放大:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
上图接口为SAS接口。只能用SAS适配器连接。RAID损坏后,要想完整备份源数据,必须保证对所有硬盘的读写都是可回溯的。为此,只能使用不含RAID功能的SAS适配器进行连接后镜像,这样才能以单硬盘的方式进行访问。
下图为PCI-E接口的SAS适配卡。
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
上图中的卡,已连接好数据线。可以最多连接4块SAS硬盘(末端的接口可直接连接硬盘),此卡为PCI-E 8×接口。
连接好硬盘的示意图如下:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
下图中的卡为PCI-X接口SAS适配卡。
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
使用下图连线可直接连接SAS硬盘
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
连接好线后的图如下:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
全部连接好的图如下所示:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
二、保证挂接服务器使用操作系统为WIN2003(其他系统也可以,本例以& WINDOWS为例)。
进入系统后,磁盘管理里会看到多个单独的硬盘,此时切记不可初始化磁盘、分区或分配盘符给可能的磁盘分区(如果不确定是否可避免,建议不要进入磁盘管理)。
推荐的作法是利用直接可访问磁盘底层扇区内容的16进制编辑器。以WINHEX为例,安装好WINHEX后,进入WINHEX,如下图所示:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
点击Tools―&Open disk菜单,如下图:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
点击后出现如下图所示:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
上图中Physical Media下列出的便是当前系统挂接到的所有物理存储设备,不经过RAID,以单盘的方式挂接,此列表就会出现物理硬盘的MODEL号及容量。上图中红色框内的便是3块IBM 73G单盘的ID显示。如果选中某块硬盘,点击OK按钮便可以以物理地址16进制的方式打开磁盘(此时不管有没有分区,什么文件系统,都无关重要。打开的便是硬盘73G的存储空间内容),当然,在做镜像时,并不需要打开。我们只是打开这个对话框确定一下硬盘是否挂上。选择Cancel退出。
开始做镜像:
点击Tools-&Disk tools-&Clone Disk,如下图所示:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
弹出的对话框如下图:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
点击图中兰色所圈按钮,选择源磁盘。选中红色所圈按钮,选择目标文件。(我们的目的是将源硬盘镜像为一个文件,此后,这个文件就是对源硬盘的完整镜像了,大小等于源硬盘的大小,此例中,完成后,目标文件即有73G之大)如下图
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
此例中选中HD2(即3块IBM SAS硬盘的第一块),点击OK后返回刚才的对话框,此时Source medium列表中便会出来选中的HD2 IBM…..
相同的方式,选择目标文件。如下图:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
选好目标文件路径及文件名后。确定返回。
此时,Clone disk对话框如下图。
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
请再次确认,Source(源)及Destination(目标)是否正确。
对话框中的其他值应该为:点中Copy entire medium(意为做全盘的镜像),Log procedure…可选(选中后,会在拷贝结束后展示摘要,推荐使用,可以知道硬盘是否有坏道等),其他参数不要管(其他参数通常适用于严重坏道等情形)
选好后(一定要确认源和目标),按下OK按钮便开始镜像操作了(WINHEX第一次做此操作,当按下OK按钮时会弹出一个帮助框,意在提醒用户,此操作是有风险的。无碍,可关掉。之后不会再出现)
拷贝的过程如下图:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)' src="http://www.datahf.net/zycu1/pic/.jpg" border="0" />
此过程完成后,镜像就完成了。目标文件即等同于源硬盘,之后可以使用WINHEX用逆向还原回原硬盘。
本文出自 “” 博客,转载请与作者联系!
了这篇文章
类别:┆阅读(0)┆评论(0)
本文收录至博客专题:《》《》
17:00:25 09:24:39 09:46:08 11:11:47 11:41:27 17:42:44 15:11:32 15:11:32 22:36:11 15:04:43 15:12:36 10:45:27 11:21:29 10:01:37 13:45:21 17:27:29 17:05:05 21:49:46 18:25:49 13:20:13 &&1&
&&页数 ( 1/2 ) &    在一个理想的世界中,不会存在任何数据库的损坏,就像我们不会将一些严重意外情况列入我们生活中的日常一样,而一旦这类事情发生,一定会对我们的生活造成非常显著的影响,在SQL Server中也同样如此,或许几年内您没有遇见过数据库中出现这类情况,而一旦遇见这类情况,往往伴随着数据的丢失,宕机,严重甚至您本身的职业生涯也会受到影响。因此对于这类情况,我们需要了解数据库损坏方面的知识,以便我们能够事前准备,事后能够处理。本篇文章会对数据库损坏的原因、现象、事前和事后的一些处理方法以及简单的修复方法进行探讨。
数据库为什么会损坏?
    在了解数据库损坏之前,首先我们要了解SQL Server是如何将数据保存到数据文件(MDF、NDF等)。无论更新还是插入数据,数据都需要首先在内存中的Buffer Pool驻留,然后通过CheckPoint和Lazy Writer等过程将内存中的数据持久化到磁盘。在这个过程中,数据脏页由内存写入持久化的IO子系统,在此期间,按照IO子系统的不同,数据可能经过这几层:
Windows(写数据一定调用的是WINDOWS API)
Windows底层的中间层(杀毒软件,磁盘加密系统)
网卡、路由器、交换机、光钎、网线等(如果IO子系统不是直连的话)
SAN控制器(如果使用了SAN)
RAID控制器(IO子系统做了RAID)
磁盘或SSD等持久化存储器
    因此,数据页被写入持久化存储期间,可能经过上述列表中的几项。在经历上述过程中,硬件环境会受到很多方面的影响,比如说电压是否稳定、断电、温度过高或过低、潮湿程度等,而软件方面,由于软件都是人写的,因此就可能存在BUG,这些都可能导致数据页在传输过程中出现错误。
   此外,影响磁盘的因素也包括电压是否稳定、灰尘等因素,这些也有可能引起磁盘坏道或整体损坏。
   上面提到的所有因素都可以被归结为IO子系统。因此,造成数据损坏的情况绝大部分是由IO子系统引起的,还有非常非常小的概率内存芯片也会导致数据页损坏,但这部分情况微乎其微,因此不在本文的讨论之列。
    上面提到的这些导致数据损坏的原因都属于天灾,还有一些人祸。比如说通过编辑器等手动编辑数据文件、数据库中还有需要Redo和Undo的事务时(也就是没有Clean Shutdown)删除了日志文件(通常会导致数据库质疑)。
发现数据库损坏
    在我们知道可能造成数据库的损坏原因之后,接下来我们来看SQL Server是如何监测数据库页损坏的。
    在SQL Server的数据库级别,可以设置页保护类型,一共有三个选项:None,CheckSum,Torn_Page_Detection,如图1所示:
图1.页保护的三种选项
    关于这三种选项,首先,请无视None,请不要在任何场景下选择该选项,该选项意味着SQL Server不对页进行保护。
    其次是TORN_PAGE_DETECTION,在SQL Server中,数据的最小单位是页,每一页是8K,但是对应磁盘上往往是16个512字节的扇区,如果一个页在写入持久化存储的过程中,只写了一半的页,这就是所谓的TORN_PAGE_DETECTION,SQL Server通过每个扇区提512字节中前2位作为元数据,总共16个扇区32位4字节的元数据(页头中标识为:m_tornBits),通过该元数据来检测是否存在部分写的TORN_PAGE,但该类型的页验证无法检测出页中的写入错误,因此在SQL Server 2005及以上版本,尽量选择CheckSum。
    在SQL Server 2005及以上版本,引入了CheckSum,CheckSum可以理解为校验和,当数据页被写入持久化存储时,会根据页的值计算出一个4字节的CheckSum存于页头(页头中标识同为:m_tornBits),和数据在同一页中一起保存在数据库中。当数据从IO子系统被读取到内存中时,SQL Server会根据页内的值再次计算CheckSum,用该重新计算的CheckSum和页头中存储的CheckSum进行比对,如果比对失败,则SQL Server就会认为该页被损坏。
    由CheckSum的过程可以看出,只有在页被写入SQL Server的过程中才会计算CheckSum,因此如果仅仅改变数据库选项的话,则页头中的该元数据并不会随之改变。
与IO相关的三种错误
    通过上述CheckSum的原理可以看出,SQL Server可以检测出页损坏,此时,具体的表现形式可能为下述三种错误的一种:
823错误,也就是所谓的硬IO错误,可以理解为SQL Server希望读取页,而Windows告诉SQL Server,无法读取到该页。
824错误,也就是所谓的软IO错误,可以理解为SQL Server已经读取到该页,但通过计算CheckSum等值发现不匹配,因此SQL Server认为该页已经被损坏。
825错误,也就是所谓Retry错误。
    其中, 上述823和824错误都是错误等级为24的严重错误,因此会被记录在Windows应用程序日志和SQL Server的错误日志中,而引起该错误的页会被记录在msdb.dbo.suspect_pages中。SQL Server错误日志中也会记录到出错页的编号,如图2所示。
   
图2.824错误在SQL Server错误记录中的描述
    因此,如果我们存在完善的备份的话,我们可以通过备份进行页还原(在此再次强调一下对于DBA来说,有”备”无患),一个简单的页还原代码如代码清单1所示。
USE [master]
RESTORE DATABASE [Corrupt_DB] PAGE='1:155'
DISK = N'C:\xxx.bak'
NORECOVERY,
代码清单1.一个简单的页还原代码,从备份中还原文件ID1中的第155页
    记得我们前面说的,在读取页计算校验和时出错,这既可能是被写入持久化存储的页本身出错,也可能是在页被读取的过程中出错,此时SQL Server会尝试从IO子系统中再次读取该页,最多可能是4次尝试,如果在4次尝试过程中校验和通过,则会是825错误,否则是824错误。这里要注意,与823和824错误不同的是,825错误是一个等级仅为10的信息。
    因此,由于有固定的错误编号,因此可以在SQL Server Agent中对823和824设置警报。
备份CheckSum
    上述页CheckSum只有在页被使用时才会被校验页的正确性。在备份数据库时,可以指定CheckSum选项来使得备份读取的页也计算校验和,从而保证了被备份的数据库是没有损坏的。在图3的备份选项我们可以注意到这两条:
图3.CheckSum和Continue_After_Error选项
    如果启用了CheckSum,当备份过程中发现了页校验和错误时,就会终止备份,而启用了Continue_After_Error选项的话,在检测到校验和错误时,仍然继续从而使得备份成功。
   备份如果启用了CheckSum选项,除去检测每一页的校验和之外,还会在备份完成后,对整个备份计算校验和并存储于备份头中。
   此外,对于备份,我们还可以通过Restore Verifyonly with CheckSum来验证备份,来保证备份的数据没有被损坏。
DBCC CheckDB
    前面提到SQL Server发现错误的方法有两种,分别为在读取页时和在备份时(本质上也是读取页)。但如果我们希望对于数据一致性的检查更加的激进,那我们应该定期使用CheckDB来检查数据的一致性,而不至于在生产时间数据被读取时才能发现错误。
    CheckDB命令会对整个数据库做所有的一致性检查。当检查对象是Master数据库时,CheckDB还会检查ResourceDB。
    CheckDB最简单的用法如代码清单2所示,在当前数据库上下文中直接执行CheckDB,将会检查当前数据库中所有的一切。
DBCC CHECKDB
代码清单2.CheckDB最简单的用法
    CheckDB命令在企业版中会使用多线程来进行,会对整个数据库进行一致性检查,在该过程中,使用了内建数据库快照的方式进行,因此不会造成阻塞,但CheckDB会消耗大量的CPU、内存和IO。因此CheckDB要选择在维护窗口时间或是系统闲时进行。
    默认情况下,CheckDB命令会将输出所有的信息,但通常我们并不关心这些信息,而是只关心错误信息,因此实际中通常给DBCC指定不显式信息的参数,如代码清单3所示。
DBCC CHECKDB WITH NO_INFOMSGS;
代码清单3.CheckDB通常搭配No_InfoMsgs参数
    实际上,CheckDB是一套命令的汇总,CheckDB会依次检查下述内容:
初次检查系统表
分配单元检查(DBCC CHECKALLOC)
完整检查系统表
对所有表进行一致性逻辑检查(DBCC CHECKTABLE)
元数据检查(DBCC CHECKCATALOG)
索引视图、XML索引等检查
    首先,当发现系统表损坏时,只能通过备份进行恢复(这也是为什么备份除TempDB之外的系统表非常重要)。其次,在一个大数据库中,做一次CheckDB时间会非常长,维护窗口时间或系统闲时的时间可能无法Cover这段时间,那么我们可以将CheckDB的任务分散到CHECKALLOC、DBCC CHECKTABLE、DBCC CHECKCATALOG这三个命令中。
    更多关于CheckDB的详细信息,请参阅:。
数据库损坏的修复
    数据库损坏最行之有效的办法就是存在冗余数据,使用冗余数据进行恢复。所谓的冗余数据包括热备、冷备、和暖备。
    使用镜像或可用性组作为热备,当检测到错误时,可以自动进行页修复(镜像要求2008以上,可用性组是2012的功能)。镜像当主体服务器遭遇824错误时,会向镜像服务器发送请求,将损坏的页由镜像复制到主体解决该问题。对于可用性组,如果数据页是在主副本上发现的,则主副本将会向所有辅助副本发送广播,并由第一个响应的辅助副本的页来修复页错误,如果错误出现在只读辅助副本,则会向主副本请求对应的页来修复错误。在这里有一点值得注意的是,无论是哪一种高可用性技术,都不会将页错误散播到冗余数据中,因为SQL Server中所有的高可用性技术都是基于日志,而不是数据页。
    其次是使用暖备或冷备来还原页,我已经在代码清单1中给出了详细的代码,这里就不细说了。
    如果没有合适的备份存在,如果损坏的数据页是存在于非聚集索引上,那么你很幸运,只需要将索引禁用后重建即可。
    如果存在基准的完整备份,并且日志链没有断裂(包括差异备份可以Cover日志缺失的部分),则可以通过备份尾端日之后还原数据库来进行修复。
    最后,如果基础工作做的并不好,您可能就需要通过损失数据的方式来换回数据库的一致性,我们可以通过DBCC CheckDB命令的REPAIR_ALLOW_DATA_LOSS来修复数据库。使用该方法可能导致数据损失,也可能不会导致数据损失,但大部分情况都会通过删除数据来修复一致性。使用REPAIR_ALLOW_DATA_LOSS需要将数据库设置为单用户模式,这意味着宕机时间。
    无论是哪种情况修复数据库,都要考虑是否满足SLA,如果出现了问题之后,发现无论用哪种方式都无法满足SLA的话,那只能检讨之前的准备工作并祈祷你不会因此丢了工作。
    本篇文章阐述了数据库损坏的概念、SQL Server检测损坏的原理、CheckDB的原理及必要性和简单的修复手段。对于数据库损坏事前要做好充足的准备,在事后才不会后悔莫及。就像买保险一样,你可不会希望出了事以后再去买保险吧?
阅读(...) 评论()}

我要回帖

更多关于 数据库文件损坏 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信