(一)测试目的
目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既不可写也不可读,即采用的高可用技术为“数据库镜像”。存在的问题为:开发人员需要登录到生产服务器上去确认数据,无法保证数据安全。因此,需要搭建一种主备模式,保证备库可读,从而让开发人员在不接触生产环境的情况下也能通过备库校验数据的正确性。
(二)技术选择
经过确认,SQL Server2012的高可用主要有以下方案:
高可用技术 |
优势 |
劣势 |
最终选择 |
SQL Server集群 |
多台服务器组成一个集群,可保证一个节点出故障,其它节点仍正常运行 |
集群使用共享存储,存储故障会导致整个集群出故障 |
不符合本次主备分离的特点。 |
日志传送 |
通过主库的日志恢复备库,可保证主备库数据一摸一样 |
备份作业每隔一段时间触发一次,所以不是实时的 |
日志恢复有延迟,无法查到最新的数据 |
数据库镜像 |
可保证主备库数据一摸一样 |
镜像数据库是一个一直处于“恢复”状态的数据库,因此不能直接访问 |
备库无法访问,不符合要求 |
复制-->快照复制 |
直接同步数据库某一时刻的整个状态 |
数据有延迟、需要保证整体数据量小,数据量大的时候速度非常慢 |
不符合要求 |
复制-->事务复制 |
通过日志读取代理和分发代理程序,将发布服务器上的数据更改和架构修改几乎实时传递给订阅服务器; |
暂时无 |
符合要求 |
复制-->合并复制 |
允许用户同时修改订阅服务器和发布服务器上的数据,并把这些修改合并成一个统一的结果 |
暂时无 |
实际环境中主库不需要同步备库的变更,不符合要求 |
经过确认,使用复制技术中的事物复制来测试是否满足需求。
(三)搭建步骤
测试基础环境信息如下:
主库 |
备库 |
|
操作系统 |
Windows Server 2012 R2 64bit |
Windows Server 2012 R2 64bit |
数据库版本 |
cn_sql_server_2012_enterprise_edition_x86_x64 |
cn_sql_server_2012_enterprise_edition_x86_x64 |
服务器名称(IP) |
WIN-PRIMARY(10.1.106.2) |
WIN-STANDBY(10.1.106.3) |
同步数据库信息 |
masterdb |
slavedb |
(3.1)配置分发(主库执行)
STEP1: 在SSMS“对象资源管理器”中选择“复制”,右键“配置分发”,弹出“配置分发向导”,点击“下一步”
STEP2: 分发服务器可以是当前服务器,也可以是其它服务器,这里选择当前服务器作为分发服务器
STEP3: 快照文件夹用于存放快照
该文件夹需要手动修改权限,最好直接给“Everyone”的权限
STEP4: 配置分发数据库,默认即可
STEP5: 配置发布服务器,默认即可
STEP6: 后续步骤默认即可
(3.2)创建发布(主库执行)
STEP1: 在SSMS“对象资源管理器”中选择“复制”,点击“本地发布”,右键“新建发布”
STEP2:选择要发布的数据库,这里选择要发布的数据库,即要进行主备同步的数据库。本次测试为masterdb数据库的所有表,选择masterdb
STEP3:选择发布类型,这里选择事务发布
STEP4:发布项目,选择要发布的表。需要注意,要发布的表必须要有主键,否则无法发布。
STEP5:是否要过滤数据,这里因为要保持主备数据相同,不过滤,直接下一步。
STEP6:勾选“立即创建快照并使快照保持可用状态,以初始化订阅”
STEP7:代理安全性,选择“安全设置”
STEP8:默认在向导结束时创建发布
STEP9:填写发布名称,点击“完成”
STEP10:确认发布成功
发布成功后,可以在对象资源管理器的“复制”-->”本地发布”下面找到新的发布:
(3.3)创建订阅(备库执行)
STEP1:在备库服务器上创建新的数据库slavedb。在SSMS的“对象资源管理器”-->“数据库”-->右键点击“新建数据库”,创建slavedb。
STEP2:选择“复制”-->“本地订阅”-->“新建订阅”
STEP3:发布。“发布服务器”菜单选择“<查找SQL Server发布服务器...>”,在弹出的菜单中,填写主数据库的信息,然后“连接”,如下:
在“数据库和发布”中选择主库的发布
STEP4:在分发代理位置中选择“在分发服务器xxx上运行所有代理(推送订阅)”
STEP5:订阅服务器中选择“订阅数据库”为slavedb
STEP6:分发代理安全性,点击红框部分
如下图设置分发代理安全性
STEP7:同步计划,选择“连续运行”
STEP8:初始化订阅,选择“立即”
STEP9:保持默认
STEP10:确认订阅成功
刷新“本地订阅”,即可看到刚刚创建的订阅
(3.4)检查数据同步状态
检查“对象资源管理器”-->“数据库”-->“slavedb”-->“表”下面是否已经有表
检查表中是否有数据
如果有表和数据,那么说明数据已经同步过来。或者在主库手动插入数据,看是否会同步到备库,也是一个好办法。
(四)数据库操作对复制的影响
(4.1)添加新表(主库操作)
结果:主库添加新表,备库并不会自动同步。
如果要同步,有3种方法:
方法一:在发布服务器重新生成快照,重启发布、分发作业
STEP1:在主库上打开SSMS,点击“复制”-->“本地发布”,点击要修改的发布名称“[masterdb]:publish_masterdb”-->右键“属性”
STEP2:在“项目”中,去掉勾选“仅显示列表中已选中的项目”,即可看到所有表,选择新表,点击确定,
STEP3:选择发布,重新初始化
STEP4:重启快照代理和分发代理
首先确认本地发布“publish_masterdb”的快照代理和分发代理的名称。在“SQL Server代理”--“作业活动监视器”,找到“publish_masterdb”相关代理。
然后关闭快照代理和分发代理(停止作业),最后在开启快照代理和分发代理(作业开始步骤...)
STEP5:确认备库表是否同步过去
方法二:添加新表到原来的发布中,然后重启发布、分发作业
TEP1:在主库上打开SSMS,点击“复制”-->“本地发布”,点击要修改的发布名称“[masterdb]:publish_masterdb”-->右键“属性”
STEP2:在“项目”中,去掉勾选“仅显示列表中已选中的项目”,即可看到所有表,选择新表,点击确定,
STEP3:重启快照代理和分发代理
首先确认本地发布“publish_masterdb”的快照代理和分发代理的名称。在“SQL Server代理”--“作业活动监视器”,找到“publish_masterdb”相关代理。
然后关闭快照代理和分发代理(停止作业),最后在开启快照代理和分发代理(作业开始步骤...)
STEP4:确认备库表是否同步过去
方法三:对新表新建发布、订阅
这里以test10表为例,将test10表同步到salvedb中。
STEP1:在主库上对test10表新建事务发布“p_masterdb_test10”
STEP2:在备库上对“p_masterdb_test10”进行订阅
STEP3:确认备库表是否同步过去
三种方法使用总结:
方法 |
使用优劣势 |
方法一:在发布服务器重新生成快照,重启发布、分发作业 |
优势:能够在同一个发布中增加新表,管理规范、方便; 劣势:重新初始化步骤会将主库的所有数据重新同步到备库,如果数据量很大,同步速度会较慢; |
方法二:添加新表到原来的发布中,然后重启发布、分发作业 |
优势:1.能够在同一个发布中增加新表,管理规范、方便; 2.不需要重新生成快照,仅对新加的表增量更新,负载小 个人认为该方法是最优的 |
方法三:对新表新建发布、订阅 |
优势:直接对新表新建发布订阅,不影响原有的同步,对业务影响小; 劣势:每次增加新表都需要新建发布订阅,管理上不规范; |
(3.2)删除表(主库操作)
结果:主库无法删除正在同步的表。
drop table test01;
报错:
消息 3724,级别 16,状态 2,第 2 行
无法对 表'test01' 执行 删除,因为它正用于复制。
(3.3)修改表结构(主库操作)
结果:①添加列:主库添加列,备库会自动添加列;②删除列:主库删除列,备库会自动删除列;
(3.4)插入、更新、删除数据(主库操作)
结果:主库插入、更新、删除数据,备库自动同步;
(3.5)truncate表(主库操作)
结果:无法执行truncate操作;
truncate table test01;
消息 4711,级别 16,状态 1,第 1 行
无法截断表 'test01',因为该表已为复制发布或者已启用了变更数据捕获。
(3.6)修改操作系统Administrator密码(主库操作)
结果:数据传输正常;
(四)如何监控
在SMSS中,点击“复制”-->“启动复制监视器”,即可看到所有的发布、订阅监视列表、代理,双击“订阅监视列表”,即可看到具体的执行记录。
(五)总结
如果使用事务复制:
1.对于要同步到备库的表,必须要有主键;
2.被复制的表在主库无法执行drop、truncate操作;
3.新添加表需要DBA重新手动将其加入到发布中;
4.备库仅仅作为数据查询使用,不具备主备切换的功能。