SQLserver 能够把镜像和复制同一时候部署,结合了两方的高可用性。能够使数据库得到更好的高可用性和容灾的保证。
关于镜像: f=255&MSPPError=-2147217396">数据库镜像
关于复制:SQL Server 复制
本章的复制为事务可更新订阅:事务复制的可更新订阅
关于复制和数据库镜像:复制和数据库镜像
理论的东西參考官方文档吧,这里主要是部署配置过程。
下图为本章參考部署的架构图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
本章模拟的server:
kk-ad |
192.168.2.1 |
DC(域控) |
kk-db1 |
192.168.2.10 |
主机(Replication + Mirror) |
kk-db2 |
192.168.2.11 |
镜像(Mirror) |
kk-db3 |
192.168.2.12 |
见证机(WITNESS)+ 分发 |
kk-db4 |
192.168.2.13 |
订阅(測试1个) |
将复制与数据库镜像一起使用时。注意下面要求和注意事项:
1. 主体数据库和镜像数据库必须共享分发server。 建议此处使用远程分发server,假设公布server有意外故障转移,则远程分发server能够提供较大的容错能力。
2. 对于合并复制,以及对于使用仅仅读订阅server或排队更新订阅server的事务复制。复制支持对公布数据库进行镜像。 不支持即时更新对等拓扑中的订阅server、Oracle 公布server、公布server并又一次公布。
3. 存在于数据库外部的元数据和对象不拷贝到镜像数据库。包含登录名、作业、链接server等等。 假设要求镜像数据库中有元数据和对象。则必须手动复制它们。
配置复制和数据库镜像主要步骤:
1. 配置数据库镜像。(參考 SQLServer 数据库镜像(二)域环境中完整镜像脚本配置)
2. 配置分发server;(參考 怎样配置公布和分发 。 怎样在分发server上启用远程公布server)
3. 配置公布和订阅。(參考 怎样创建事务性公布的可更新订阅 ,SqlServer 使用脚本创建分发服务及事务复制的可更新订阅)
说明及注意改动的地方:
本測试使用域账号作为数据库登录账号:[KK\UserReplMirror]
相应数据库用户:[UserReplMirror]
測试数据库:[DemoDB]
确保各server能相互訪问
数据库 [DemoDB] 恢复模式为完整模式(镜像必须)
数据库 [DemoDB] 全部者改为 [sa]
账号 [KK\UserReplMirror] 授予 sysadmin 权限。或者在数据库 [DemoDB] 中授予用户 [UserReplMirror] 数据库角色为 [db_owner]
复制的代理作业的全部者都改为[sa]
数据库外的对象不会镜像:如登录账户。代理作业 等
1. 配置数据库镜像:
--主体创建数据库
USE [master]
GO
CREATE DATABASE [DemoDB]
GO
ALTER DATABASE [DemoDB] SET RECOVERY FULL WITH NO_WAIT
GO --主体:创建证书 和 备份
USE master;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'kk_2012@';
GO
CREATE CERTIFICATE Cert_kk_db1_mssqlserver
WITH SUBJECT = 'Cert_kk_db1_mssqlserver',
START_DATE = '2015-06-01',EXPIRY_DATE = '2018-06-01';
GO
BACKUP CERTIFICATE Cert_kk_db1_mssqlserver
TO FILE = 'C:\Databases\Cert_kk_db1_mssqlserver.cer';
GO --镜像:创建证书 和 备份
USE master;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'kk_2012@';
GO
CREATE CERTIFICATE Cert_kk_db2_mssqlserver
WITH SUBJECT = 'Cert_kk_db2_mssqlserver',
START_DATE = '2015-06-01',EXPIRY_DATE = '2018-06-01';
GO
BACKUP CERTIFICATE Cert_kk_db2_mssqlserver
TO FILE = 'C:\Databases\Cert_kk_db2_mssqlserver.cer';
GO --见证:创建证书 和 备份
USE master;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'kk_2012@';
GO
CREATE CERTIFICATE Cert_kk_db3_mssqlserver
WITH SUBJECT = 'Cert_kk_db3_mssqlserver',
START_DATE = '2015-06-01',EXPIRY_DATE = '2018-06-01';
GO
BACKUP CERTIFICATE Cert_kk_db3_mssqlserver
TO FILE = 'C:\Databases\Cert_kk_db3_mssqlserver.cer';
GO -- 交换证书(相互拷贝证书):
/*
主体证书(复制到)————>镜像、见证
镜像证书(复制到)————>主体、见证
见证证书(复制到)————>主体、镜像
*/ -- 主体(创建用户、还原证书、创建端点):
USE master
GO
CREATE LOGIN [KK\UserReplMirror] FROM WINDOWS;
GO
CREATE USER [UserReplMirror] FOR LOGIN [KK\UserReplMirror];
GO
CREATE CERTIFICATE [Cert_kk_db2_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db2_mssqlserver.cer';
GO
CREATE CERTIFICATE [Cert_kk_db3_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db3_mssqlserver.cer';
GO CREATE ENDPOINT [Endpoint_For_Mirror]
AUTHORIZATION [KK\UserReplMirror]
STATE=STARTED
AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)
FOR DATA_MIRRORING
(ROLE = PARTNER, AUTHENTICATION = CERTIFICATE Cert_kk_db1_mssqlserver, ENCRYPTION = REQUIRED ALGORITHM AES)
GO
--GRANT CONNECT ON ENDPOINT::Endpoint_For_Mirror TO [KK\UserReplMirror];
--GO -- 镜像(创建用户、还原证书、创建端点):
USE master
GO
CREATE LOGIN [KK\UserReplMirror] FROM WINDOWS;
GO
CREATE USER [UserReplMirror] FOR LOGIN [KK\UserReplMirror];
GO
CREATE CERTIFICATE [Cert_kk_db1_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db1_mssqlserver.cer';
GO
CREATE CERTIFICATE [Cert_kk_db3_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db3_mssqlserver.cer';
GO CREATE ENDPOINT [Endpoint_For_Mirror]
AUTHORIZATION [KK\UserReplMirror]
STATE=STARTED
AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)
FOR DATA_MIRRORING
(ROLE = PARTNER, AUTHENTICATION = CERTIFICATE Cert_kk_db2_mssqlserver, ENCRYPTION = REQUIRED ALGORITHM AES)
GO
--GRANT CONNECT ON ENDPOINT::Endpoint_For_Mirror TO [KK\UserReplMirror];
--GO -- 见证(创建用户、还原证书、创建端点):
USE master
GO
CREATE LOGIN [KK\UserReplMirror] FROM WINDOWS;
GO
CREATE USER [UserReplMirror] FOR LOGIN [KK\UserReplMirror];
GO
CREATE CERTIFICATE [Cert_kk_db1_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db1_mssqlserver.cer';
GO
CREATE CERTIFICATE [Cert_kk_db2_mssqlserver]
AUTHORIZATION [UserReplMirror]
FROM FILE = 'C:\Databases\Cert_kk_db2_mssqlserver.cer';
GO USE master;
CREATE ENDPOINT [Endpoint_For_Mirror]
AUTHORIZATION [KK\UserReplMirror]
STATE=STARTED
AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL)
FOR DATA_MIRRORING
(ROLE = WITNESS, AUTHENTICATION = CERTIFICATE Cert_kk_db3_mssqlserver, ENCRYPTION = REQUIRED ALGORITHM AES)
GO
--GRANT CONNECT ON ENDPOINT::Endpoint_For_Mirror TO [KK\UserReplMirror];
--GO --主体:备份数据库
USE master;
BACKUP DATABASE [DemoDB]
TO DISK = 'C:\Databases\DemoDB.BAK' WITH INIT,FORMAT
GO BACKUP LOG [DemoDB]
TO DISK = 'C:\Databases\DemoDB_LOG.BAK' WITH INIT,FORMAT
GO --镜像:还原数据库(NORECOVERY)
USE master;
RESTORE DATABASE [DemoDB]
FROM DISK = N'C:\Databases\DemoDB.BAK'
WITH FILE = 1,
MOVE N'DemoDB' TO N'C:\Databases\DemoDB.mdf',
MOVE N'DemoDB_log' TO N'C:\Databases\DemoDB_log.ldf',
NOUNLOAD, NORECOVERY, STATS = 10
GO RESTORE DATABASE [DemoDB]
FROM DISK = N'C:\Databases\DemoDB_LOG.BAK'
WITH NORECOVERY
GO --開始镜像 --在【镜像】运行,PARTNER为主服务器
USE [master]
GO
ALTER DATABASE [DemoDB] SET PARTNER = 'TCP://192.168.2.10:5022';
GO --在【主体】运行,PARTNER为镜像服务器
USE [master]
GO
ALTER DATABASE [DemoDB] SET PARTNER = 'TCP://192.168.2.11:5022';
GO
ALTER DATABASE [DemoDB] SET WITNESS = 'TCP://192.168.2.12:5022';
GO --在主体运行:设置为高安全模式
ALTER DATABASE [DemoDB] SET SAFETY FULL
EXEC [DemoDB].dbo.sp_changedbowner @loginame = N'sa', @map = false
GO
EXEC master..sp_addsrvrolemember @loginame = N'KK\UserReplMirror', @rolename = N'sysadmin'
GO
2. 配置分发server
登录到该server。
kk-db3 |
192.168.2.12 |
见证机(WITNESS)+ 分发 |
右键复制,配置分发。
分发server选择 “kk-db3” 本地server。加入 “KK-DB1 ” (主机)和 “KK-DB2 ” (镜像) 为公布server。否则连接不到该分发server。
注意:创建分发server时,要求数据管理password。右键“复制”—“分发server属性”—“公布server” 可看到和设置。
配置用于故障转移的复制代理
可配置參数 PublisherFailoverPartner 的代理:
1 - 复制快照代理(对于全部公布)
2 - 复制日志读取器代理(对于全部事务公布)
4 - 复制合并代理(对于合并订阅)
9 - 复制队列读取器代理(对于支持排队更新订阅的事务公布)
当前为可更新订阅,仅仅要更改1,2,9 即可(分发库运行)
--@parameter_value 为镜像服务
exec sp_add_agent_parameter @profile_id = 1,
@parameter_name = N'-PublisherFailoverPartner',
@parameter_value = N'kk-db2' exec sp_add_agent_parameter @profile_id = 2,
@parameter_name = N'-PublisherFailoverPartner',
@parameter_value = N'kk-db2' exec sp_add_agent_parameter @profile_id = 9,
@parameter_name = N'-PublisherFailoverPartner',
@parameter_value = N'kk-db2'
接着 重新启动SQL Server 代理
3. 配置公布和订阅
登录到server
kk-db1 |
192.168.2.10 |
主机(Replication + Mirror) |
创建本地公布,选择分发server。
(仅仅有分发中加入了公布server的信息。此处才干訪问)
这里须要输入在分发server设置的管理password。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
注:此时在分发server( 192.168.2.12 )生成的复制相关作业代理,全部者改为 [sa]
登录到server
kk-db4 |
192.168.2.13 |
订阅 |
创建订阅:(公布选择 “kk-db1”)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
创建完毕订阅后。初始化订阅,登录到server:
kk-db1 |
192.168.2.10 |
主机(Replication + Mirror) |
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
登录到server:
kk-db3 |
192.168.2.12 |
见证机(WITNESS)+ 分发 |
右键 “复制”—“启动复制监视器”,右键 “加入公布server”,将 公布server “kk-db1” 加入。就可以看到复制监控情况
配置已完毕!
~
4. 測试
如今把主体(Replication + Mirror)服务停止:
停止后,到原来的镜像(kk-db2)查看。镜像变成了主体。本地公布也出现了(原来镜像是不存在的)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
可是。当我从如今的主体(kk-db2)插入数据时,数据并没有同步到订阅!
~
难道是哪里配置不正确??!~~
网上查找后,发现是BUG,原因是:
This problem occurs because Log Reader Agent does not copy the transactions that are marked for replication from the transaction log into the distribution database. Log Reader Agent cannot read past a specific log sequence number (LSN). This specific LSN
represents the last LSN that has been hardened to the transaction log of the mirror database.
临时不修复,用其它方法设置也能够:
(先启动 kk-db1 的SQLserver 服务)
在主体 和 镜像中,设置服务启动參数。加入 -T1448,重新启动服务就可以。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2sxODU4MDA5NjE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
此时停止主体实例。镜像变成主体。操作数据可正常和订阅同步了!
~
至此,就算完毕了,个人測试,也可能有不正确的地方。