【SQL Server高可用性】数据库镜像:在SQL Server 2008R2上的配置数据库镜像

时间:2021-09-28 18:56:41


在进行配置之前,要说明一下:配置数据库镜像,不是什么高深的技术,只要按照规范的步骤,就能配置成功,而且只需要在普通的pc上就可以配置成功,对机器、网络、存储等也没什么要求。


所以,你完全可以在公司的局域网内,通过和另外2个同事的电脑,或者在家,借用其他2个室友的笔记本,就能配置成功,如果你在生产环境中配置数据库镜像,那么基本的配置过程也是一样的。


1、基本的信息

本文主要是在3台笔记本上配置数据库镜像,通过证书来实现验证,而不是用域账户来实现。另外,本文配置的是高安全性的数据库镜像,能实现自动秒级切换,需要3台机器:主体服务器、镜像服务器、见证服务器。


主体服务器ip:192.168.1.101

镜像服务器ip:192.168.1.105

见证服务器ip:192.168.1.104


3台机器都安装的是SQL Server 2008R2,版本是:

select @@VERSION
/*
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64) Apr 22 2011 19:23:43
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
*/

另外,你可以通过在3台电脑上,通过SSMS分别连接另外2台电脑,看是否能连通,如果连不上,应该是防火墙屏蔽了端口,我把防火墙关闭了,当然,你也可以把默认1433,和数据库镜像端口5022加入到防火墙的例外中。


为了配置方便,所有的数据库文件、数据库备份文件、证书文件,都放在c:\share 目录下面,所以需要在c盘下,创建一个share。

另外,为了实现文件的共享,可以通过网络共享的方式实现,不过设置比较麻烦,所以我通过QQ传输了数据库备份文件、证书文件等,当然如果你有U盘,也可以通过文件拷贝到U盘,来传输文件的。


注意:下面所有的代码,都需要按照(编号)的顺序,在相应的服务器上执行。

比如:(1)是在主体服务器上执行的,(2)是在镜像服务器上执行的,(3)又是在主体服务器执行的,所有的操作必须要按照(编号)中的编号的顺序来执行。


2、主体服务器的配置

需要把数据库备份文件传输到镜像服务器上:

-- ===========================================
-- 无论是主体服务器、镜像服务器, 还是见证服务器
-- 除特别说明外,均需要保证下面的操作在master库中执行
USE master
GO

-- ===========================================
--(1) 建立镜像主体数据库
-- 此操作主体服务器上执行
-- a. 建立测试数据库
CREATE DATABASE DB_Mirror
ON(
NAME = DB_Mirror_DATA,
FILENAME = N'c:\share\DB_Mirror.mdf'
)
LOG ON(
NAME = DB_Mirror_LOG,
FILENAME = N'c:\share\DB_Mirror.ldf'
)

--设置数据库的恢复模式是完全模式
ALTER DATABASE DB_Mirror SET
RECOVERY FULL
GO

-- b. 完全备份,需要把这个完全备份文件,传输到镜像服务器上
BACKUP DATABASE DB_Mirror
TO DISK = N'c:\share\DB_Mirror.bak'
WITH FORMAT
GO

执行代码后,需要把创建的证书,传输到镜像服务器上:

-- ===========================================
--(3) 主体服务器上的数据库镜像端点及身份验证用的证书
-- 此操作主体服务器上执行
-- a. 用于数据库镜像端点身份验证的证书
IF NOT EXISTS( -- 使用数据库主密钥加密证书
SELECT * FROM sys.symmetric_keys
WHERE name = N'##MS_DatabaseMasterKey##')
CREATE MASTER KEY
ENCRYPTION BY PASSWORD = N'wcis123'

--drop certificate ct_mirror_srva
CREATE CERTIFICATE CT_Mirror_SrvA
WITH
SUBJECT = N'certificate for database mirror',
START_DATE = '19990101',
EXPIRY_DATE = '99991231'
GO


-- b. 备份证书, 以便在与此端点通信的另一端建立此证书
BACKUP CERTIFICATE CT_Mirror_SrvA
TO FILE = 'c:\share\CT_Mirror_SrvA.cer'
GO


--drop endpoint edp_mirror
-- c. 数据库镜像端点
CREATE ENDPOINT EDP_Mirror
STATE = STARTED
AS TCP(
LISTENER_PORT = 5022, -- 镜像端点使用的通信端口
LISTENER_IP = ALL) -- 侦听的IP地址
FOR DATABASE_MIRRORING(
AUTHENTICATION = CERTIFICATE CT_Mirror_SrvA, -- 证书身份验证
ENCRYPTION = DISABLED, -- 不对传输的数据加密,如果需要加密,可以配置为 SUPPORTED 或 REQUIRED, 并可选择加密算法
ROLE = ALL) -- 端点支持所有的数据库镜像角色, 也可以设置为 WITNESS(仅见证服务器),或 PARTNER(仅镜像伙伴)
GO

从镜像服务器创建的证书文件拷贝到主体服务器上后,运行如下代码:

-- ===========================================
--(6) 在主体服务器上完成镜像服务器数据库镜像端点的传输安全模式配置
-- 此操作主体服务器上执行
-- a. 建立主体服务器上的证书(假设镜像服务器上备份的证书已经复制到 c:\share\CT_Mirror_SrvB.cer)
CREATE CERTIFICATE CT_Mirror_SrvB
FROM FILE = 'c:\share\CT_Mirror_SrvB.cer'

-- b. 建立登录,用这个login来登录到镜像服务器上
CREATE LOGIN LOGIN_Mirror_SrvB
FROM CERTIFICATE CT_Mirror_SrvB

-- c. 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvB
GO

-- ===========================================
--(8) 在主体服务器上启用数据库镜像(默认为高安全性模式,所以不用进行模式设置)
-- 此操作主体服务器上执行
ALTER DATABASE DB_Mirror SET
PARTNER = 'TCP://192.168.1.105:5022'
GO

把在见证服务器上创建的证书,复制到主体服务器上,然后执行如下代码:

-- ===========================================
--(11) 在主体服务器上完成见证服务器数据库镜像端点的传输安全模式配置
-- 此操作主体服务器上执行
-- a. 建立见证服务器上的证书(假设见证服务器上备份的证书已经复制到 c:\share\CT_Mirror_SrvWitness.cer)
CREATE CERTIFICATE CT_Mirror_SrvWitness
FROM FILE = 'c:\share\CT_Mirror_SrvWitness.cer'

-- b. 建立登录
CREATE LOGIN LOGIN_Mirror_SrvWitness
FROM CERTIFICATE CT_Mirror_SrvWitness

-- c. 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvWitness
GO

-- ===========================================
--(12) 在主体服务器上为数据库镜像启用见证服务器
-- 此操作主体服务器上执行
ALTER DATABASE DB_Mirror SET
WITNESS = 'TCP://192.168.1.104:5022'
GO

3、镜像服务器的配置

把主体服务器上的数据库备份文件,拷贝到镜像服务器上后,再执行下面的代码:

-- ===========================================
-- 无论是主体服务器、镜像服务器, 还是见证服务器
-- 除特别说明外,均需要保证下面的操作在master库中执行
USE master
GO


-- ===========================================
--(2) 初始化镜像主体数据库
-- 此操作镜像服务器上执行
-- 假设主体数据库的完全备份已经复制到 c:\share\DB_Mirror.bak
-- SQL Server必须使用相同的账户名来启动
RESTORE DATABASE DB_Mirror
FROM DISK = 'c:\share\DB_Mirror.bak'
WITH REPLACE
, NORECOVERY
-- 如果镜像数据库文件要放在指定位置, 则启用下面的 Move 选项
--, MOVE 'DB_Mirror_DATA' TO N'C:\DB_Mirror.mdf'
--, MOVE 'DB_Mirror_LOG' TO N'C:\DB_Mirror.ldf'
GO


-- ===========================================
--(4) 镜像服务器上的数据库镜像端点及身份验证用的证书
-- 此操作镜像服务器上执行
-- a. 用于数据库镜像端点身份验证的证书
IF NOT EXISTS( -- 使用数据库主密钥加密证书
SELECT * FROM sys.symmetric_keys
WHERE name = N'##MS_DatabaseMasterKey##')
CREATE MASTER KEY
ENCRYPTION BY PASSWORD = N'wwwwc123'


CREATE CERTIFICATE CT_Mirror_SrvB
WITH
SUBJECT = N'certificate for database mirror',
START_DATE = '19990101',
EXPIRY_DATE = '99991231'
GO


-- b. 备份证书, 以便在与此端点通信的另一端建立此证书
BACKUP CERTIFICATE CT_Mirror_SrvB
TO FILE = 'c:\share\CT_Mirror_SrvB.cer'
GO

-- c. 数据库镜像端点
CREATE ENDPOINT EDP_Mirror
STATE = STARTED
AS TCP(
LISTENER_PORT = 5022, -- 镜像端点使用的通信端口
LISTENER_IP = ALL) -- 侦听的IP地址
FOR DATABASE_MIRRORING(
AUTHENTICATION = CERTIFICATE CT_Mirror_SrvB, -- 证书身份验证
ENCRYPTION = DISABLED, -- 不对传输的数据加密,如果需要加密,可以配置为 SUPPORTED 或 REQUIRED, 并可选择加密算法
ROLE = ALL) -- 端点支持所有的数据库镜像角色, 也可以设置为 WITNESS(仅见证服务器),或 PARTNER(仅镜像伙伴)
GO

把主体服务器上的证书,拷贝到镜像服务器上后,再执行下面的代码:

-- ===========================================
--(5) 在镜像服务器上完成主体服务器数据库镜像端点的传输安全模式配置
-- 此操作镜像服务器上执行
-- a. 建立主体服务器上的证书(假设主体服务器上备份的证书已经复制到 C:\CT_Mirror_SrvA.cer)
CREATE CERTIFICATE CT_Mirror_SrvA
FROM FILE = 'c:\share\CT_Mirror_SrvA.cer'


-- b. 建立登录
CREATE LOGIN LOGIN_Mirror_SrvA
FROM CERTIFICATE CT_Mirror_SrvA


-- c. 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvA
GO

-- ===========================================
--(7) 在镜像服务器上启用数据库镜像
-- 此操作镜像服务器上执行
ALTER DATABASE DB_Mirror SET
PARTNER = 'TCP://192.168.1.101:5022'
GO

把见证服务器上的证书,拷贝到镜像服务器上后,再执行下面的代码:

-- ===========================================
--(10) 在镜像服务器上完成见证服务器数据库镜像端点的传输安全模式配置
-- 此操作镜像服务器上执行
-- a. 建立见证服务器上的证书(假设见证服务器上备份的证书已经复制到 C:\CT_Mirror_SrvWitness.cer)
CREATE CERTIFICATE CT_Mirror_SrvWitness
FROM FILE = 'c:\share\CT_Mirror_SrvWitness.cer'

-- b. 建立登录
CREATE LOGIN LOGIN_Mirror_SrvWitness
FROM CERTIFICATE CT_Mirror_SrvWitness

-- c. 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvWitness
GO

4、见证服务器的配置

把主体服务器和镜像服务器上的证书,拷贝到见证服务器上后,再执行下面的代码:

-- ===========================================
-- 无论是主体服务器、镜像服务器, 还是见证服务器
-- 除特别说明外,均需要保证下面的操作在master库中执行
USE master
GO


-- ===========================================
--(9) 配置见证服务器
-- 此操作在见证服务器上执行
-- a. 完成见证服务器上数据库镜像端点的传输安全模式配置
-- (a). 用于数据库镜像端点身份验证的证书
IF NOT EXISTS( -- 使用数据库主密钥加密证书
SELECT * FROM sys.symmetric_keys
WHERE name = N'##MS_DatabaseMasterKey##')
CREATE MASTER KEY
ENCRYPTION BY PASSWORD = N'abc.123'

CREATE CERTIFICATE CT_Mirror_SrvWitness
WITH
SUBJECT = N'certificate for database mirror',
START_DATE = '19990101',
EXPIRY_DATE = '99991231'
GO


-- (b). 备份证书, 以便在与此端点通信的另一端建立此证书
BACKUP CERTIFICATE CT_Mirror_SrvWitness
TO FILE = 'c:\CT_Mirror_SrvWitness.cer'
GO


-- (c). 数据库镜像端点
CREATE ENDPOINT EDP_Mirror
STATE = STARTED
AS TCP(
LISTENER_PORT = 5022, -- 镜像端点使用的通信端口
LISTENER_IP = ALL) -- 侦听的IP地址
FOR DATABASE_MIRRORING(
AUTHENTICATION = CERTIFICATE CT_Mirror_SrvWitness, -- 证书身份验证
ENCRYPTION = DISABLED, -- 不对传输的数据加密,如果需要加密,可以配置为 SUPPORTED 或 REQUIRED, 并可选择加密算法
ROLE = ALL) -- 端点支持所有的数据库镜像角色, 也可以设置为 WITNESS(仅见证服务器),或 PARTNER(仅镜像伙伴)
GO

-- b. 完成主体服务器上数据库镜像端点的传输安全模式配置
-- (a). 建立主体服务器上的证书(假设主体服务器上备份的证书已经复制到 C:\CT_Mirror_SrvA.cer)
CREATE CERTIFICATE CT_Mirror_SrvA
FROM FILE = 'C:\CT_Mirror_SrvA.cer'

-- (b). 建立登录
CREATE LOGIN LOGIN_Mirror_SrvA
FROM CERTIFICATE CT_Mirror_SrvA

-- (c). 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvA
GO

-- c. 完成镜像服务器上数据库镜像端点的传输安全模式配置
-- (a). 建立镜像服务器上的证书(假设镜像服务器上备份的证书已经复制到 C:\CT_Mirror_SrvB.cer)
CREATE CERTIFICATE CT_Mirror_SrvB
FROM FILE = 'C:\CT_Mirror_SrvB.cer'

-- (b). 建立登录
CREATE LOGIN LOGIN_Mirror_SrvB
FROM CERTIFICATE CT_Mirror_SrvB

-- (c). 授予对数据库镜像端点的 connect 权限
GRANT CONNECT ON ENDPOINT::EDP_Mirror
TO LOGIN_Mirror_SrvB
GO

5、查看数据库状态

配置完成后,主体服务器:

【SQL Server高可用性】数据库镜像:在SQL Server 2008R2上的配置数据库镜像


运行如入代码,查看同步状态:

-- ===========================================
-- 下面的操作可用于确定同步
-- 查询数据库状态
-- 下面的脚本可以在主体服务器和镜像服务器上执行,执行结果为镜像的状态
SELECT
mirroring_role_desc, -- 数据库在镜像会话中当前的角色
mirroring_state_desc, -- 镜像当前状态
mirroring_safety_level_desc, -- 镜像运行模式
mirroring_witness_state_desc -- 与见证服务器的连接情况
FROM sys.database_mirroring
WHERE database_id = DB_ID(N'DB_Mirror')


而镜像服务器:

【SQL Server高可用性】数据库镜像:在SQL Server 2008R2上的配置数据库镜像



6、在镜像服务器上测试同步是否成功


那么有什么办法能知道数据是否被同步到进行服务器了呢?

这个可以通过数据库快照来实现。


这里引用微软的文档的一段文字:


可以利用为了实现可用性目标而维护的镜像数据库来减轻报表的负载。若要将镜像数据库用于报表,可以在镜像数据库中创建数据库快照,并将客户端连接请求定向到最新的快照。由于数据库快照只在创建快照时存在,因此,它是一个静态的、只读的并与其源数据库保持事务一致的快照。若要在镜像数据库中创建数据库快照,数据库必须处于同步镜像状态。


与镜像数据库本身不同,客户端可以访问数据库快照。只要镜像服务器与主体服务器进行通信,就可以将报表客户端连接定向到快照。注意,由于数据库快照是静态的,因此没有新数据可用。为了让用户能够使用相对较新的数据,必须定期创建新的数据库快照,并通过应用程序将传入客户端连接定向到最新的快照。


新的数据库快照几乎是空的,但是它会随着越来越多的数据页的首次更新而增长。由于数据库中的每个快照都以这种方式增长,因此,每个数据库快照与常规数据库使用同样多的资源。根据镜像服务器和主体服务器的配置,在镜像数据库中保留过多的数据库快照可能会降低主体数据库的性能。因此,我们建议在镜像数据库中仅保留少量相对较新的快照。一般情况下,在创建替换快照之后,应重新将传入查询定向到新的快照,并在完成所有当前的查询之后删除较早的快照。


完整的信息可以参考:

数据库镜像和数据库快照 (SQL Server) http://technet.microsoft.com/zh-cn/library/ms175511.aspx


首先,在主体服务器上创建一个表,并插入数据:

create table t(id int,v varchar(10))

insert into t
values(2,'wc')

然后,在镜像服务器上,创建一个数据库快照,查询数据:

CREATE DATABASE SNP_DB_Mirror
ON(
NAME = DB_Mirror_DATA,
FILENAME = N'C:\share\SNP_DB_Mirror.mdf')
AS SNAPSHOT OF DB_Mirror
GO

use SNP_DB_Mirror
go

select *
from t
/*
idv
2wc
*/

接下来,在主体服务器上再次插入数据后,再查询镜像服务器上的数据库快照,就不能查询新的数据了:

--主体服务器上执行
insert into t
values(3,'wwww')

--在镜像服务器上执行
use SNP_DB_Mirror
go

--1.查询发现没有新的数据
select *
from t
/*
idv
2wc
*/
go


--2.于是新建一个数据库快照
CREATE DATABASE SNP_DB_Mirror_New
ON(
NAME = DB_Mirror_DATA,
FILENAME = N'C:\share\SNP_DB_Mirror_New.mdf')
AS SNAPSHOT OF DB_Mirror
GO


use SNP_DB_Mirror_New
go


--3.再次查询,发现有新的数据被同步了
select *
from t
/*
idv
2wc
3wwww
*/