sql server replication 为实现数据库读写分离,高可用等都提供了不错的解决方案。实现 replication 总共分为三种方法:
网络上针对第一种方法有了很多的记载和实验,动手一搜可以搜到很多的案例,自己看着搭建也可以很快走完整套流程,中间可能会有一些小细节或者小问题需要注意。但是涉及到第二种和第三种方法,就很少了,我在 MaryKay 的时候,老外针对这两种情况,也是选择放弃,甚至第一种就不考虑使用,大概就是因为不好用的原因。所以今天我就要以第一种方法切入,然后谈一下后面两种方法。
先从架构拓扑谈起,再细化到组件(Agents) 以及实现方法,最后讲一讲管理。从概念讲起,先在头脑里搭建这个 replication 的框架,每一个组件的配置及使用,然后灵活配置各个组件的应用,这一步一个脚印的往前进,循序渐进,才能走的更远。这个过程会花费很长的时间,所以耐心,是我完成搭建 replication 的一个必要条件。
上面这张图,简明扼要的阐述了 replication 的架构与组件,绿线表示读,红线表示写。看图说话,我们一一将里面的关键点说明白:
把图里的内容都讲了一遍了,就要问自己几个问题了:
人生嘛,就是解决一个一个的问题,要回答上面这些问题,还是靠一步一步做实验来弄清楚,先从 SSMS 搭建一个 replication 开始:
这里有张图,可以很好的看到,publication, distributor agents, subscription 的所属问题,注意黑圆点的标注:
好了,上面写的是思路,具体的实现,我们一步一步来,在这个实现的步骤里面,肯定会遇到很多不可思议的事情,一件一件记录下来,肯定能获得不少 serendipity (意外的收获):
Distributor 配置好之后,我们要为 publisher配置 distributor 了,这个时候,奇怪的问题来了,用密码登陆 distributor 的时候,始终登陆不了,总是出现这个错误 “ sql server could not cononect to the distributor with the specified password”。参考了网络上的一篇帖子,有这么个用法:
首先,先检查下 remote access 在数据库里面是不是开启,而在可以检查这个选项的时候,还需要将 show advanced options 这个开关给开起来,看看是怎么开的 :
sp_configure ‘show advanced options’, 1
reconfigure
这还只是第一步,先将 show advanced options 启动,reconfigure 就是让这个选项获得新值之后,重新写到数据库配置文里面。接下来就是配置 remote access, 让其 Run Value 等于 1:
sp_configure ‘remote access’, 1
reconfigure
到这一步就可以了,重启 sql server instance, 再 sp_configure 查看下 remote access 的值, 确认 Run_Value 是1 了。这一步在 publisher, distributor 上面都要执行好。
别以为 sql server 默认会帮你把一切都配置好,尤其是要用到 replication,failover cluster 等这类特性的时候,我们需要检查一些常规的配置,比如刚才 1 中提到的 remote access, 接下来 remote access 是允许了,但是 remote access 用到的相关渠道(协议)是不是也已经开启了呢? 这里讲的就是 sql server configuration manager 里面会用到的 TCP/IP, Named pipes 远程协议是不是被启动了? 没启动,这里要启动起来。否则,经典的连接错误就会找上来:
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 28 - Server doesn’t support requested protocol)
到这里,把前面的自个儿问自个儿的问题都回答了,那么我们就要进入下一个话题,如何用 T-SQL 编程的方法或者 .NET Client 的方法来构建 replication 呢?
DECLARE @distributor AS sysname;
DECLARE @distributionDB AS sysname;
DECLARE @publisher AS sysname;
DECLARE @directory AS nvarchar(500);
DECLARE @publicationDB AS sysname;
-- Specify the Distributor name.
SET @distributor = 'storage\distributor';
-- Specify the distribution database.
SET @distributionDB = N'distributionstock';
-- Specify the Publisher name.
SET @publisher ='publisher\crm';
-- Specify the replication working directory.
SET @directory = N'C:\snapshot';
-- Specify the publication database.
SET @publicationDB = N'stocktrans';
-- Install the server Storage\Distributor as a Distributor using the defaults,
-- including autogenerating the distributor password.
USE master
EXEC sp_adddistributor @distributor = @distributor;
-- Create a new distribution database using the defaults, including
-- using Windows Authentication.
USE master
EXEC sp_adddistributiondb @database = @distributionDB, @security_mode = 1;
GO
-- Create a Publisher and enable stocktrans for replication.
-- Add publisher\crm as a publisher with storage\distributor as a local distributor
-- and use Windows Authentication.
DECLARE @distributionDB AS sysname;
DECLARE @publisher AS sysname;
-- Specify the distribution database.
SET @distributionDB = N'distribution'stock;
-- Specify the Publisher name.
SET @publisher = 'publisher\crm' USE [distributionstock] EXEC sp_adddistpublisher @publisher=@publisher, @distribution_db=@distributionDB, @security_mode = 1;
GO
2.2 publication script , article script
2.2.1 首先要做的两点,就是:一启动 publisher 的角色;二配置要使用的 distributor . 这里使用到的存储过程 sp_replicationdboption .
use stocktrans
go
sp_adddistributor
@distributor = 'storage\distributor',
@password = 'XXXXXXXXXXX'
sp_replicationdboption 'stocktrans','publish',true
2.2.2 在第一步里指定的 replication database, 执行 sp_addpublication 来添加 publication.
-- Create a new transactional publication with the required properties.
EXEC sp_addpublication
@publication = 'stocktranspub',
@status = N'active',
@allow_push = N'true',
@allow_pull = N'true',
@independent_agent = N'true';
-- Create a new snapshot job for the publication, using a default schedule.
EXEC sp_addpublication_snapshot
@publication = 'stocktranspub',
@job_login = 'smartoffice\joe',
@job_password = 'xxxx',
-- Explicitly specify the use of Windows Integrated Authentication (default)
-- when connecting to the Publisher.
@publisher_security_mode = 1;
GO
2.2.3 添加 article
DECLARE @publication AS sysname;
DECLARE @table AS sysname;
DECLARE @filterclause AS nvarchar(500);
DECLARE @filtername AS nvarchar(386);
DECLARE @schemaowner AS sysname;
SET @publication = N'stocktranspub';
SET @table = N'stock';
SET @schemaowner = N'dbo''; EXEC sp_addarticle @publication = @publication, @article = @table, @source_object = @table, @source_owner = @schemaowner, @vertical_partition = N'true', @type = N'logbased'
2.3 subscription script 以 push subscription 为例子. 所有的操作都在publisher, publication 里面执行。
2.3.1 判断 publication 是不是可以被 push 或者 pull
Sp_helppublication
2.3.2 添加 push subscription
Sp_addsubscription
2.3.3 添加 push distributor agent
Sp_addpushsubscription_agent
2.3.4 默认是一天执行一次 snapshot push over ,那么怎么去修改这个同步间隔呢?
Sp_add_schedule
use stocktrans
go
sp_addsubscription
@publication = 'stocktranspub',
@subscriber = 'sqlcluster\mysqlcluster',
@destination_db = 'stock'
3 . 监控健康指标
3.1 Replication Monitor
4 . 移除 replication , 察看 distribution 数据库元数据的更改
4.1 先移除 subscriber 和 subscription Sp_dropsubscription,sp_subscription_cleanup
4.2 再移除 publisher 和 publication
4.3 再移除 distributor
4.4 细节解说
为了禁止 Replication,我们必须依次执行以下步骤:
4.4.1 停掉所有的 Replication 相关的 Sql Agent Job, 关于 Replication 相关的 Sql Agent job ,命名也是有规律可以寻的,可以参考这篇文章 Replication Agent Security Model
4.4.2 在每一个 subscriper 的 subscription 数据库上,执行 sp_removedbreplication,删掉 replication 相关的数据库对象。
4.4.3 在 publisher 的 publication 数据库上,执行 sp_removedbreplication 来删掉 replication 相关的数据库对象。如果配置了 distributor ,那么执行 sp_dropdistributor 来删掉相关应用。
4.4.4 在 Distributor 的实例上,执行 sp_dropdisttpublisher. 有多少 publisher 配置了,就要执行相应的次数的命令,直到全部删掉。之后,执行 sp_dropdistributiondb 来卸载相关的 distribution 数据库。配置了多少 distribution 数据库,针对每个库都要做一次 sp_dropdistributiondb。最后执行 sp_dropdistributor 来删掉这个 distributor 角色。