SqlServer 使用脚本创建分发服务及事务复制的可更新订阅

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
日志服务 SLS,月写入数据量 50GB 1个月
简介: 原文:SqlServer 使用脚本创建分发服务及事务复制的可更新订阅 【创建使用本地分发服务器】 /************************【使用本地分发服务器配置发布】***********************/ -- SqlServer 2008 R2 -- https://technet.
原文: SqlServer 使用脚本创建分发服务及事务复制的可更新订阅

【创建使用本地分发服务器】

/************************【使用本地分发服务器配置发布】***********************/  
--  SqlServer 2008 R2  
--  https://technet.microsoft.com/zh-cn/library/ms151860(v=sql.105).aspx  
use master  
go  
  
--  服务器上是否已安装分发服务器  
--  https://msdn.microsoft.com/zh-cn/library/ms190339(v=sql.105).aspx  
exec master.dbo.sp_get_distributor  
go  
  
--  配置分发服务器  
--  https://msdn.microsoft.com/zh-cn/library/ms176028(v=sql.105).aspx  
exec master.dbo.sp_adddistributor   
 @distributor = 'KK-PC'    --分发服务器名称  
,@heartbeat_interval = 10       --代理在不记录进度消息的情况下可以运行的最长分钟数  
,@password = N'123456'  --分发服务器密码  
go  
  
--  配置分发数据库  
--  https://msdn.microsoft.com/zh-cn/library/ms189755(v=sql.105).aspx  
exec master.dbo.sp_adddistributiondb   
 @database = N'distribution'    --要创建的分发数据库的名称  
,@data_folder = N'E:\TempFile\Distribution' --分发数据库数据文件的目录  
,@data_file = N'distribution'   --数据库文件的名称  
,@data_file_size = 5            --初始数据文件大小,以兆字节 (MB) 为单位  
,@log_folder = N'E:\TempFile\Distribution' ----分发数据库日志文件的目录  
,@log_file = N'distribution_log'   
,@log_file_size =  5            --初始日志文件大小,以兆字节 (MB) 为单位   
,@min_distretention = 0         --从分发数据库中删除事务前的最小保持期,以小时为单位  
,@max_distretention = 72        --删除事务前的最大保持期,以小时为单位   
,@history_retention = 48        --历史记录的保留时间,以小时为单位   
,@security_mode = 1             --同步时连接到分发服务器的安全模式。默认值为1:Windows验证,0: SQL验证   
,@login = N'KK-PC\SqlReplicator'   
,@password = N'123456'   
,@createmode = 1                --1:创建或使用现有数据库(instdist.sql)   
go  
  
--  配置发布服务器以使用指定的分发数据库  
--  https://msdn.microsoft.com/zh-cn/library/ms173807(v=sql.105).aspx  
exec master.dbo.sp_adddistpublisher   
 @publisher = N'KK-PC'         --发布服务器的名称  
,@distribution_db = N'distribution' --分发数据库的名称   
,@security_mode = 1                 --安全模式,默认1:Windows验证,0: SQL验证   
,@login = N'KK-PC\SqlReplicator'   
,@password = N'123456'   
,@working_directory = N'E:\TempFile\ReplData'--默认快照文件夹的UNC共享目录  
,@thirdparty_flag  = 0              --发布服务器是否是SQLServer,默认0:是,1:否  
,@publisher_type  = N'MSSQLSERVER'  --发布服务器类型:MSSQLSERVER(默认)/ORACLE/ORACLE GATEWAY  
go  
  
/*****配置完成!!*****/  


/*****【查看分发属性】******/

--	检查分发数据库目录
exec master.dbo.xp_subdirs N'E:\TempFile\Distribution'

--	发布服务器的属性(在分发服务器任何数据库执行)
--	https://technet.microsoft.com/zh-cn/library/ms190323(v=sql.105).aspx
exec master.dbo.sp_helpdistpublisher N'KK-PC'

--	分发数据库的属性(在分发服务器的分发数据库上执行)
--	https://msdn.microsoft.com/zh-cn/library/vstudio/aa238917.aspx
exec master.dbo.sp_helpdistributiondb N'distribution'

--	列出有关分发服务器相关信息(在分发服务器任何数据库执行)
--	https://msdn.microsoft.com/zh-cn/library/ms177504(v=sql.105).aspx
exec master.dbo.sp_helpdistributor



/*****【删除分发】******/
--这里不必执行!


--	删除分发发布服务器(在分发服务器任何数据库执行)
--	https://technet.microsoft.com/zh-cn/library/ms188411(v=sql.105).aspx
exec master.dbo.sp_dropdistpublisher @publisher =  N'KK-PC',@no_checks = 0,@ignore_distributor = 0 --检查对象;连接分发;

--	删除分发数据库(在分发服务器任何数据库执行)
--	https://msdn.microsoft.com/zh-cn/library/ms188355(v=sql.105).aspx
exec master.dbo.sp_dropdistributiondb N'distribution';

--	卸载分发服务器(除分发数据库之外的任何数据库中执行)
--	https://technet.microsoft.com/zh-cn/library/ms173516(v=sql.105).aspx
exec master.dbo.sp_dropdistributor @no_checks = 0,@ignore_distributor = 0 --检查对象;连接分发;





【创建可更新订阅的事务发布】


/*************************************【创建发布】**************************************/
/*【实例:可更新订阅】

* A 为发布数据库,id为每个表的主键
* B,C 为订阅数据库
* A中符合条件 [id % 2 = 0] 的同步到B中
* A中符合条件 [id % 2 = 1] 的同步到C中
* 以下以 B 创建发布订阅
	
  当前发布数据库:[mytest]
  当前订阅数据库:[mytestA]
  
  
*/



--	作为发布的数据库
use [mytest]

--	设置指定数据库的复制数据库选项(发布服务器或订阅服务器执行)
--	http://msdn.microsoft.com/zh-cn/library/ms188769.aspx
exec sys.sp_replicationdboption @dbname = N'mytest', @optname = N'publish', @value = N'true'
go


--	为给定分发服务器添加队列读取器代理(在分发库或发布库执行)(每个实例默认只1个,已存在可不须再执行)
--	http://msdn.microsoft.com/ZH-CN/LIBRARY/ms189517
exec sys.sp_addqreader_agent @job_login = N'KK-PC\SqlReplicator', @job_password = N'123456', @job_name = null, @frompublisher = 1
go


--	为给定数据库添加日志读取器代理(在发布数据库执行)(每个数据库默认只1个,已存在可不须再执行)
--	http://technet.microsoft.com/zh-cn/library/ms189516.aspx
exec sys.sp_helplogreader_agent @publisher = null --查看当前数据库存在的日志代理
exec sys.sp_addlogreader_agent @job_login = N'KK-PC\SqlReplicator', @job_password = N'123456', @publisher_security_mode = 1, @job_name = null
go


/***************************【创建发布:以下用于1库多发布】******************************/

--	添加(可更新订阅)事务发布(在发布数据库执行)
--	http://msdn.microsoft.com/zh-cn/library/ms188738(v=sql.100).aspx
exec sys.sp_addpublication 
@publication = N'tran_repl',		--【指定发布名称】
@description = N'来自发布服务器“”的数据库“mytest”的具有可更新订阅的事务发布。', 
@sync_method = N'concurrent',			--同步模式:本机模式大容量复制程序输出
@retention = 0,							--订阅活动的保持期(小时):默认值为336小时;0:订阅永不过期
@allow_push = N'true',					--推送订阅 
@allow_pull = N'true',					--允许创建请求订阅
@allow_anonymous = N'false',			--不可创建匿名订阅 
@enabled_for_internet = N'false',		--非Internet发布
@snapshot_in_defaultfolder = N'false',	--不指定快照默认文件夹,须设置@alt_snapshot_folder
@alt_snapshot_folder = N'E:\TempFile\ReplData',	--指定快照的备用文件夹的位置
@compress_snapshot = N'false',			--不压缩快照
@ftp_port = 21,							--默认分发服务器的FTP服务的端口号:21
@ftp_login = N'anonymous',				--默认用于连接到 FTP 服务的用户名:anonymous
@allow_subscription_copy = N'false',	--禁用复制订阅此发布的订阅数据库
@add_to_active_directory = N'false',	--(已不推荐使用)
@repl_freq = N'continuous',				--复制频率的类型:基于日志的事务的输出
@status = N'active',					--发布数据可立即用于订阅服务器
@independent_agent = N'true',			--【独立分发代理】
@immediate_sync = N'false',				--每次运行快照代理时不为发布创建同步文件
@allow_sync_tran = N'true',				--允许使用【立即更新订阅】
@autogen_sync_procs = N'true',			--在发布服务器上生成更新订阅的【同步存储过程】
@allow_queued_tran = N'true',			--在订阅服务器中启用更改的队列
@allow_dts = N'false',					--不允许数据转换
@conflict_policy = N'sub wins',			--排队更新订阅服务器选项时所遵从的冲突解决策略:【订阅入选】
@centralized_conflicts = N'true',		--在发布服务器上存储冲突记录
@conflict_retention = 14,				--冲突保持期(天)
@queue_type = N'sql',					--使用的队列类型:默认SQL Server存储事务
@replicate_ddl = 1,						--【支持架构复制】
@allow_initialize_from_backup = N'false', --不允许用备份初始化订阅
@enabled_for_p2p = N'false',			--非对等复制
@enabled_for_het_sub = N'false'			--只支持SQL Server订阅服务器
go


--	为指定的发布创建快照代理(在发布数据库执行)
--	http://msdn.microsoft.com/zh-cn/library/ms174958(v=sql.100)
exec sys.sp_addpublication_snapshot 
@publication = N'tran_repl',
@frequency_type = 1,
@frequency_interval = 0,
@frequency_relative_interval = 0,
@frequency_recurrence_factor = 0,
@frequency_subday = 0, 
@frequency_subday_interval = 0, 
@active_start_time_of_day = 0, 
@active_end_time_of_day = 235959, 
@active_start_date = 0, 
@active_end_date = 0, 
@job_login = N'KK-PC\SqlReplicator', 
@job_password = N'123456', 
@publisher_security_mode = 1
go


--	更改发布属性
--	https://msdn.microsoft.com/zh-cn/library/ms188413(v=sql.105).aspx
--	exec sys.sp_changepublication ……



--	创建项目并将其添加到发布中(在发布数据库执行)
--	http://msdn.microsoft.com/zh-cn/library/ms173857

/*1. 添加可筛选的表(默认架构dbo)*/
declare @tableName			nvarchar(100)
declare @publName			nvarchar(100)
declare @mark				bit			-- 区分是否有sid的列,有则进行筛选
declare @filterNum			nvarchar(10)-- 一个数据库多个发布加编号区别
declare @filterClause		nvarchar(100)
declare @SQLaddarticle		nvarchar(max)
declare @SQLarticlefilter	nvarchar(max)
declare @SQLarticleview		nvarchar(max)
set @publName = N'tran_repl' --	【指定发布名称】
set @filterClause = N'dbo.f_SIDTOInt(SID) % 2 = 0' --	【指定行筛选】
select @filterNum = CONVERT(NVARCHAR(10),count(*)) from distribution.dbo.MSpublications
declare cur_addTable cursor local fast_forward
for 
	/*有主键 并且 有SID列(用于筛选)*/
	select name,1 mark from sys.tables t1(nolock) where is_ms_shipped = 0
	and exists(select 1 from sys.columns t2(nolock) where t1.object_id=t2.object_id and t2.name='SID')
	and name in(select table_name from information_schema.key_column_usage(nolock) 
		where objectproperty(object_id(constraint_name),'isprimarykey')=1 )
	union all
	/*有主键 并且 无SID列(不可筛选)*/
	select name,0 mark from sys.tables t1(nolock) where is_ms_shipped = 0
	and not exists(select 1 from sys.columns t2(nolock) where t1.object_id=t2.object_id and t2.name='SID')
	and name in(select table_name from information_schema.key_column_usage (nolock)
		where objectproperty(object_id(constraint_name),'isprimarykey')=1 )
open cur_addTable
fetch next from cur_addTable into @tableName,@mark
while @@fetch_status = 0
begin
	if ( @mark = 1 ) /*可筛选的表对象*/
	begin
		set @SQLaddarticle = N'
		exec sp_addarticle 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@source_owner = N''dbo'', 
		@source_object = N'''+@tableName+''', 
		@type = N''logbased'', 
		@description = null, 
		@creation_script = null, 
		@pre_creation_cmd = N''drop'', 
		@schema_option = 0x0000000008035CDF, 
		@identityrangemanagementoption = N''none'', 
		@destination_table = N'''+@tableName+''', 
		@destination_owner = N''dbo'', 
		@status = 24,
		@vertical_partition = N''false'''
		exec(@SQLaddarticle)
		/*添加项目筛选器*/
		set @SQLarticlefilter = N' 
		exec sp_articlefilter 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@filter_name = N''FLTR_'+@tableName+'_'+@filterNum+'__'+rtrim(ltrim(str(@@spid)))+''', 
		@filter_clause = N'''+@filterClause+''', 
		@force_invalidate_snapshot = 1, 
		@force_reinit_subscription = 1'
		exec(@SQLarticlefilter)
		/*添加项目同步对象*/
		set @SQLarticleview = N'
		exec sp_articleview 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@view_name = N''SYNC_'+@tableName+'_'+@filterNum+'__'+rtrim(ltrim(str(@@spid)))+''', 
		@filter_clause = N'''+@filterClause+''', 
		@force_invalidate_snapshot = 1, 
		@force_reinit_subscription = 1'
		exec(@SQLarticleview)
		print '已筛选:'+@tableName
	end
	else if ( @mark = 0 )
	begin
		set @SQLaddarticle = N'
		exec sp_addarticle 
		@publication = N'''+@publName+''', 
		@article = N'''+@tableName+''', 
		@source_owner = N''dbo'', 
		@source_object = N'''+@tableName+''', 
		@type = N''logbased'', 
		@description = null, 
		@creation_script = null, 
		@pre_creation_cmd = N''drop'', 
		@schema_option = 0x0000000008035CDF, 
		@identityrangemanagementoption = N''none'', 
		@destination_table = N'''+@tableName+''', 
		@destination_owner = N''dbo'', 
		@status = 24,
		@vertical_partition = N''false'''
		exec(@SQLaddarticle)
		print '无筛选:'+@tableName
	end
	fetch next from cur_addTable into @tableName,@mark
end
close cur_addTable
deallocate cur_addTable



/*2. 添加视图/存储过程/函数对象(默认架构dbo)*/
declare @publName		nvarchar(100)
declare @ObjectName		nvarchar(100)
declare @Type			nvarchar(30)
declare @ObjectType		nvarchar(30)
declare @SQLaddObject	nvarchar(max)
set @publName = N'tran_repl' --	【指定发布名称】
declare cur_addObject cursor local fast_forward
for select name,type from mytest.sys.objects where type in(N'P') and is_ms_shipped = 0
	union all
	select name,type from mytest.sys.objects a where type in(N'V') and is_ms_shipped = 0
	and exists(select 1 from mytest.sys.sql_modules b where a.object_id=b.object_id and is_schema_bound = 0)
	union all
	select name,N'B' as type from mytest.sys.objects a where type in(N'V') and is_ms_shipped = 0 
	and exists(select 1 from sys.sql_modules b where a.object_id=b.object_id and is_schema_bound = 1)/*架构绑定的索引视图*/
	union all
	select name,type from mytest.sys.objects where type in(N'TF',N'FN') and is_ms_shipped = 0
	order by type,name
open cur_addObject
fetch next from cur_addObject into @ObjectName,@ObjectType
while @@fetch_status = 0
begin
	SET @Type = 
	(
		CASE 
		WHEN @ObjectType = N'V' THEN N'view schema only'
		WHEN @ObjectType = N'B' THEN N'indexed view schema only'
		WHEN @ObjectType = N'P' THEN N'proc schema only'
		WHEN @ObjectType in(N'TF',N'FN') THEN N'func schema only'
		END
	)
	set @SQLaddObject = N'
	exec sp_addarticle 
	@publication = N'''+@publName+''', 
	@article = N'''+@ObjectName+''', 
	@source_owner = N''dbo'', 
	@source_object = N'''+@ObjectName+''', 
	@type =  N'''+@Type+''', 
	@description = null, 
	@creation_script = null, 
	@pre_creation_cmd = N''drop'', 
	@schema_option = 0x0000000008000001, 
	@status = 16,
	@destination_owner = N''dbo'', 
	@destination_table = N'''+@ObjectName+''''
	exec(@SQLaddObject)
	print @ObjectType+ ':' + @ObjectName
	fetch next from cur_addObject into @ObjectName,@ObjectType
end
close cur_addObject
deallocate cur_addObject


【创建订阅】

		
/***********************************【创建订阅】***************************************/
/*【要在发布服务器上运行的脚本】*/

use [mytest]

--	将订阅添加到发布并设置订阅服务器的状态
--	(警告: distribution 代理作业隐式创建,并将在 SQL Server 代理服务帐户下运行)
--	http://technet.microsoft.com/zh-cn/library/ms181702(v=sql.100).aspx
exec sys.sp_addsubscription 
@publication = N'tran_repl',	--指定发布名称
@subscriber = N'KK-PC',		--订阅服务器
@destination_db = N'mytestA',--订阅数据库
@subscription_type = N'Push',		--推送订阅
@sync_type = N'automatic',			--默认,已发布表的架构和初始数据将首先传输到订阅服务器
@article = N'all',					--发布所订阅的项目
@update_mode = N'queued failover',	--将订阅启用为排队更新订阅,并允许更改为立即更新模式
@subscriber_type = 0				--订阅服务器的类型:SQL Server订阅服务器
go

--	添加新的预定分发代理作业,以使推送订阅与事务发布同步
--	http://msdn.microsoft.com/zh-cn/library/ms175006(v=SQL.100)
exec sys.sp_addpushsubscription_agent 
@publication = N'tran_repl',	--指定发布名称
@subscriber = N'KK-PC',			--订阅服务器
@subscriber_db = N'mytestA',	--订阅数据库
@job_login = N'KK-PC\SqlReplicator', 
@job_password = N'123456', 
@subscriber_security_mode = 1,			--Windows 身份验证
@frequency_type = 64,					--分发代理计划的频率:自动启动(默认)
@frequency_interval = 1, 
@frequency_relative_interval = 1, 
@frequency_recurrence_factor = 0, 
@frequency_subday = 4, 
@frequency_subday_interval = 5, 
@active_start_time_of_day = 0, 
@active_end_time_of_day = 235959, 
@active_start_date = 0, 
@active_end_date = 0, 
@dts_package_location = N'Distributor'
go


/*【要在订阅服务器上运行的脚本】*/

use mytestA

--	设置在连接到发布服务器时立即更新订阅的同步触发器所使用的配置和安全信息
--	http://msdn.microsoft.com/zh-cn/library/ms174991(v=sql.100).aspx
exec sys.sp_link_publication 
@publisher = N'KK-PC', 
@publisher_db = N'mytest', 
@publication = N'tran_repl', 
@distributor = N'KK-PC', 
@security_mode = 1,		--SQL Server 身份验证或 Windows 身份验证
@login = N'KK-PC\SqlReplicator', 
@password = N'123456'
go



【启动快照并初始化】

/**********************************【启动快照并初始化】**************************************/
--	发布服务器发布数据
use [mytest]

--	对其请求订阅中的新项目的订阅添加到发布中(在发布服务器的发布数据库中执行)
--	https://technet.microsoft.com/zh-cn/library/ms181680(v=sql.100).aspx
--	exec sys.sp_refreshsubscriptions @publication = N'tran_repl'


--	将订阅标记为要重新初始化
--	https://msdn.microsoft.com/zh-cn/library/ms189469(v=sql.100).aspx
exec sys.sp_reinitsubscription 
@publication = N'tran_repl', 
@subscriber = N'KK-PC', 
@destination_db = N'mytestA', 
@article = N'all'
go

--	启动可为发布生成初始快照的快照代理作业(在发布服务器的发布数据库中执行)
--	http://msdn.microsoft.com/zh-cn/library/ms176026(v=sql.105).aspx
exec sys.sp_startpublication_snapshot @publication = N'tran_repl'
go

--	为所有表项目编写自定义 sp_MSins、sp_MSupd 和 sp_MSdel 过程的脚本
--	https://msdn.microsoft.com/zh-cn/library/ms187946(SQL.100).aspx
--exec sys.sp_scriptpublicationcustomprocs 'tran_repl'
--go


--	至此,完成发布订阅!!!~ 初始化完成!!~





之前测试了N遍!!!~~今晚有空终于成功处理了!~




相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
存储
SQLServer存储过程中事务的创建
SQLServer存储过程中事务的创建
66 0
|
4月前
|
SQL 数据库 数据安全/隐私保护
SQL Server数据库Owner导致事务复制log reader job无法启动的解决办法
【8月更文挑战第14天】解决SQL Server事务复制Log Reader作业因数据库所有者问题无法启动的方法:首先验证数据库所有者是否有效并具足够权限;若非,使用`ALTER AUTHORIZATION`更改为有效登录名。其次,确认Log Reader使用的登录名拥有读取事务日志所需的角色权限。还需检查复制配置是否准确无误,并验证Log Reader代理的连接信息及参数。重启SQL Server Agent服务或手动启动Log Reader作业亦可能解决问题。最后,审查SQL Server错误日志及Windows事件查看器以获取更多线索。
|
4月前
|
存储 SQL Go
全网最长的sql server巡检脚本分享(1000行)
全网最长的sql server巡检脚本分享(1000行)
59 1
|
3月前
|
SQL 存储 监控
SQLServer事务复制延迟优化之并行(多线程)复制
【9月更文挑战第12天】在SQL Server中,事务复制延迟会影响数据同步性。并行复制可通过多线程处理优化这一问题,提高复制效率。主要优化方法包括:配置分发代理参数、优化网络带宽、调整系统资源、优化数据库设计及定期监控维护。合理实施这些措施可提升数据同步的及时性和可靠性。
|
4月前
|
SQL
SqlServer 服务无法启动 操作系统错误: 5(拒绝访问。)
SqlServer 服务无法启动 操作系统错误: 5(拒绝访问。)
126 0
SqlServer 服务无法启动 操作系统错误: 5(拒绝访问。)
|
3月前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
127 0
|
4月前
|
SQL 监控 供应链
|
4月前
|
SQL 存储 Go
SQL Server一键巡检脚本分享
SQL Server一键巡检脚本分享
37 0
|
4月前
|
SQL 数据库连接 网络安全
SQLServer非默认端口下事务复制代理作业服务无法启动的处理
【8月更文挑战第14天】若SQL Server非默认端口下的事务复制代理作业无法启动,可按以下步骤解决:1) 确认服务器连接字符串正确无误,包括非默认端口号;2) 检查防火墙设置,确保允许非默认端口的连接;3) 核实SQL Server配置已启用非默认端口;4) 查阅代理作业日志寻找错误详情;5) 重启SQL Server与Agent服务;6) 使用工具测试非默认端口的连接性。如问题持续,请寻求专业支持。
|
4月前
|
SQL 关系型数据库 MySQL
SQL Server 事务执行、回滚
SQL Server 事务执行、回滚
48 0
下一篇
无影云桌面