升级原因:由于用于复制需求越来越多,分发服务器压力越来越大,且分发服务为单点,非冗余,存在安全隐患.
需求:将分发由sql2005单实例升级为sql2008R2 cluster,由于复制很多,全部重新初始化将会是漫长过程,会影响业务,探索是否可以通过迁移distribution 库一并将未分发命令迁移,避免初始化.
注意:由于微软BOL声称是不能Mirror distribution 库的,但事实是可以的,这个案例我咨询过微软的专家,答案也是不能镜像分发库,其他的我给他的方案估计他没看.所以如果读者要部署生产库,需反复测试,或联系我共同探讨也可以.
警告:如实施跟我的环境相同(05到08)则镜像不能回滚,切记做好意外准备.
实施步骤:
1:镜像distribution 库
2:导出凭据,代理,从distribution 库中导出复制作业的脚本
3:停用分发上的分发,日志读取作业
4:手动转移镜像库
5:记录下原分发库的机器名(迁移后分发的network name),并修改为不相关的机器名(注意domain中唯一)
6:将新的分发(sql08R2 cluster)的network 名称改为原分发服务器名.
7:重新定义新分发的@@servername与老分发相同.
8:在hosts文件中添加新分发的IP和名称(群集中SQL虚拟IP和network name)
9:在新分发上脚本配置分发服务
10:新分发上用保存脚本创建凭据,代理,JOB(注意赋予相关代理相应权限)
11:确认新的发布状态为active
12:修改在新分发的distribution 库中修改job_id使之与msdb中相关表的Jod_id相对应
13:检查迁移
附:实例作业脚本为我发给微软专家的英文脚本,稍微改了下,没有翻译,相关可联系我.
/*************************************scripts about distribute service migration***********************************************************/
/* for the blow scripts,I will Move the distribute service From Server "DBsrvA" to "DBsrvB" (cluster network)for no tracsaction lose*/
/*DBsrvA's IP:192.168.0.10 DBsrvB's SQL virtual IP: 192.168.0.12*/
/*for this test,update one table which is used to publish,and disable the distributor JOB
so the distributon DB have the transaction but have not synchronous to subscription server
the publisher isn't equal to the subscription*/
--1:mirror the distribution database(The DBsrvA now is the distribute service server )
----scripts on 192.168.0.10
ALTER DATABASE [distribution] SET RECOVERY FULL
go
backup database distribution to disk=N'c:\distribution.bak' with init
go
CREATE ENDPOINT DbMirroringEP
AS TCP (LISTENER_PORT = 15022)
FOR DATABASE_MIRRORING (ROLE = PARTNER, ENCRYPTION = SUPPORTED);
GO
ALTER ENDPOINT DbMirroringEP STATE = STARTED
--then copy the distribution.bak to DBsrvB path:c:\distribution.bak too
----scripts on 192.168.0.12(for DBsrvB there is no distribute service configure yet)
RESTORE DATABASE [distribution] FROM DISK = N'C:\distribution.bak' WITH FILE = 1, NORECOVERY, NOUNLOAD, STATS = 10
GO
CREATE ENDPOINT DbMirroringEP
AS TCP (LISTENER_PORT = 15022)
FOR DATABASE_MIRRORING (ROLE = PARTNER, ENCRYPTION = SUPPORTED);
GO
ALTER ENDPOINT DbMirroringEP STATE = STARTED
----scripts on 192.168.0.10
backup log distribution to disk=N'c:\distribution.trn' with init
--then copy the distribution.trn to DBsrvB path:c:\distribution.trn too
----scripts on 192.168.0.12
restore log [distribution] FROM DISK = N'C:\distribution.trn' with NORECOVERY, NOUNLOAD, STATS = 10
ALTER DATABASE [distribution]
SET PARTNER = N'TCP:// 192.168.0.10:15022'
----scripts on 192.168.0.10
ALTER DATABASE [distribution]
SET PARTNER = N'TCP:// 192.168.0.12:15022'
--2:export the CREDENTIAL ,proxy,job scripts used by replication from DBsrvA
--for example
CREATE CREDENTIAL WITH IDENTITY=N'',SECRET=N''
exec msdb.dbo.sp_add_proxy @proxy_name=N'',@credential_name=N'',@enable=1
----grant proxy the subsystem power
sp_grant_proxy_to_subsystem @proxy_name='',@subsystem_name=N'Distribution'
----......
--3:disable the Distribution synchronous job and the log reader job on DBsrvA
EXEC msdb.dbo.sp_update_job @job_id, @enabled = 0
--(I use a proc,disable all jobs on DBsrvA)
--4:failover the mirroring database pair to new distribution server manually(DBsrvA to DBsrvB)
ALTER DATABASE [distribution] SET PARTNER FAILOVER
--5:change the DBsrvA's name to DBsrvC(restart os)(unique in domain),then stop the mssql service on DBsrvC
--6:change the DBsrvB's sql network name "DBsrvB" to "DBsrvA" (restart os)
--7:scripts on 192.168.0.12,redefine the instance'name(Now name is DBsrvA but @@servername is DBsrvB)
select @@servername
EXEC sp_dropserver @server= DBSRVB
--添加正确的服务器名
EXEC sp_addserver @server= DBSRVA, @local='local'
--restart mssql service
select @@servername /*now DBSRVA IP:192.168.0.12*,@@servername DBSRVA/
--8:add the info "192.168.0.12 DBsrvA" on Publisher "C:\WINDOWS\system32\drivers\etc\hosts"
--9:scripts on "192.168.0.12=DBsrvA",configure the new distribute service "192.168.0.12 DBsrvA" by sql script
use master
exec sp_adddistributor @distributor = N'DBSRVA', @password = N''
GO
exec sp_adddistributiondb @database = N'distribution', @data_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data', @log_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data', @min_distretention = 0, @max_distretention = 72, @history_retention = 48, @security_mode = 1
GO
RECONFIGURE
use [distribution]
if (not exists (select * from sysobjects where name = 'UIProperties' and type = 'U '))
create table UIProperties(id int)
if (exists (select * from ::fn_listextendedproperty('SnapshotFolder', 'user', 'dbo', 'table', 'UIProperties', null, null)))
EXEC sp_updateextendedproperty N'SnapshotFolder', N'C:\ReplData', 'user', dbo, 'table', 'UIProperties'
else
EXEC sp_addextendedproperty N'SnapshotFolder', 'C:\ReplData', 'user', dbo, 'table', 'UIProperties'
GO
exec sp_adddistpublisher @publisher = N'DBSRVA', @distribution_db = N'distribution', @security_mode = 1, @working_directory = N'c:\ReplData', @trusted = N'false', @thirdparty_flag = 0, @publisher_type = N'MSSQLSERVER'
GO
--10:scripts on "192.168.0.12=DBsrvA" recreate the CREDENTIAL ,proxy,job on "192.168.0.12=DBsrvA".(pay attention to grant the sub system authority to the relevant proxy)
CREATE CREDENTIAL WITH IDENTITY=N'',SECRET=N''
exec msdb.dbo.sp_add_proxy @proxy_name=N'',@credential_name=N'',@enable=1
----grant proxy the subsystem power
sp_grant_proxy_to_subsystem @proxy_name='',@subsystem_name=N'Distribution'
----......
--11:Ensure that each publisher on the new distribute is active
--list the publisher
exec sp_helpdistpublisher
--for example one publisher named DBtest
sp_changedistpublisher @publisher = 'DBtest'
, @property = 'active'
, @value = 'true'
--12:update the job_id on the distribution database equal to the sysjobs and sysjobsteps in the msdb
/*because the jobs regard to replication are created by exported scripts and not the same as the distribution
database which from 192.168.0.10*/
update MSsnapshot_agents set job_id=CAST(b.job_id AS binary(16))
from MSsnapshot_agents a,msdb.dbo.sysjobs b
where a.name=b.name and a.job_id<>b.job_id
update dbo.MSlogreader_agents set job_id=CAST(b.job_id AS binary(16))
from dbo.MSlogreader_agents a,msdb.dbo.sysjobs b
where a.name=b.name and a.job_id<>b.job_id
update dbo.MSdistribution_agents set job_id=CAST(b.job_id AS binary(16))
from dbo.MSdistribution_agents a,msdb.dbo.sysjobs b
where a.name=b.name and a.job_id<>b.job_id
update MSdistribution_agents set job_step_uid=b.step_uid
from MSdistribution_agents a,msdb..sysjobsteps b
where a.job_id=b.job_id and a.job_step_uid<>b.step_uid
--13:check and test this migration
/*ensure publisher isn't equal to the subscription,then run the distributor JOB manually,see whether is equal*/
/*create a new publisher then Subscribe it*/
/*************************************scripts about distribute service migration***********************************************************/