有时候我和同事都会陷讨论关于SQL Server的镜像和传统故障转移群集的问题.他们都提供了SQL Server的高可用性支持特性.最终很难下定决心采用哪种方式,因为他们都有自己的特性和特点.

镜像有一个特性我觉得应该和大家分享的是"自动页修复"功能,说明请参考官方http://msdn.microsoft.com/en-us/library/bb677167.aspx

如果在主服务器里检测到页损坏,sqlserver会自动从镜像服务器读取相应的数据页并且修复主服务器.使用故障转移群集,数据库文件仅仅被放到到一个地方.在大规模的存储系统一旦发生数据损坏,唯一的方法就是从备份中恢复.

示例

我在本地的两个实例上创建了镜像,创建过程就不一一详述了

sqlserver 2019 数据库镜像后无法打开 sqlserver镜像恢复_磁盘



 

镜像数据库是MyData,sql\master\sql2008实例是主服务器.

我创建了一个数据表



use MyData
go

create table TestData (id int identity, col1 char(2000))
go

insert into TestData (col1) values (replicate('a', 2000))
go 4096

 

接下来在sqlmaster\sql2008上模拟磁盘错误,先停止sql server的服务然后用十六进制的编辑器修改mdf文件,

sqlserver 2019 数据库镜像后无法打开 sqlserver镜像恢复_sqlserver_02

所有a的数据区域,修改部分区域用0代替

All the a’s are the data column, and the part in the middle is probably a page header. The details are not important for this test, but I’ll replace a bunch of the data with zeros:

sqlserver 2019 数据库镜像后无法打开 sqlserver镜像恢复_sql server_03


保存文件重新启动sqlserver

用最简单的select * from 方法执行表扫描,结果如下

Msg 824, Level 24, State 2, Line 1
SQL Server detected a logical consistency-based I/O error: incorrect
checksum (expected: 0xb4f55a1a; actual: 0xa4a264f1). It occurred during
a read of page (1:840) in database ID 5 at offset 0x00000000690000 in
file 'C:\DemoData\MyData.mdf'.
Additional messages in the SQL Server error log or system event log may provide
more detail. This is a severe error condition that threatens database integrity
and must be corrected immediately. Complete a full database consistency check
(DBCC CHECKDB). This error can be caused by many factors; for more information,
see SQL Server Books Online.

这个信息我们通常不太会看到,报page 840的地方有错误 , 接下来我再运行select语句,我得到一个类似的错误--不过这次是page 841.第三次我执行select语句,他成功了.

SQL Server提供了动态管理试图sys.dm_db_mirroring_auto_page_repair,可以通过它来看是否有修复产生,

SELECT DB_NAME(database_id) as DatabaseName, *
FROM sys.dm_db_mirroring_auto_page_repair;

 

sqlserver 2019 数据库镜像后无法打开 sqlserver镜像恢复_sqlserver_04

这里我们可以看到页840和页841都已经自动修复了

总结:

"自动页修复"不能防止错误发生,不过当查询试图访问受损页时,他将自动修复受损页.这样下次查询就可以正常使用.所以磁盘错误的问题某种程度上可以得到弥补.

如果你正在使用镜像.你可以看一看这个动态管理视图.如果这里显示错误,可能你的磁盘已经有错误发生,你应该尝试修复它.

如果你正在考虑给sql server采用什么高可用性方案,镜像的这个特性可能值得考虑.