使用TableDiff实用工具解决事务复制中的问题

事务复制是数据同步中常用的一种手段,复制过程难免会遇到不少问题,就笔者遇到的问题而言,一般有两大类:一类是通过重新启动Distributor Agent即可解决的问题,另一类是因为Subscriber修改了数据,导致发布的数据有冲突,这类问题一般需要手工去修复。
TableDiff是SQL Server 2005的一个命令行实用工具,该工具可以比较两个表,并且生成数据同步的脚本。借助这个工具,可以很容易地修复两个表数据不一致的问题。
但如果应用该工具来解决事务复制中数据冲突的问题,则除了同步数据外,还必须解决手工同步数据后,跳过未发布的错误事务序列的问题。
本文的第1部分介绍了TableDiff工具的用法和笔者的一些使用测试,第2部分介绍了如何借助这个工具来修复事务复制中的数据冲突问题。希望通过这两个部分的介绍,能让大家对于解决事务复制中的问题有所帮助。
比较两个非收敛的表中的数据,可以从命令提示符或在批处理文件中使用该实用工具执行以下任务:
Ø在充当复制发布服务器的SQL Server实例中的源表与充当复制订阅服务器的一个或多个SQL Server实例中的目标表之间进行逐行比较。
Ø通过只比较行数和架构可以执行快速比较。
Ø执行列级比较。
Ø生成T-SQL脚本,用以修复目标服务器中的差异,以使源表和目标表实现收敛。
Ø将结果记录到输出文件或目标数据库的表中
使用该工具,需要满足下述条件:
Ø只能用于SQL Server。
Ø表中不包含sql_variant 数据类型的列
ØSource Table和Destination Table需要满足下列一致性:
n数目一致
n名称一致
n如果使用 -strict 选项,要求列的类型一致,否则,仅要求列的类型兼容。下面的数据类型是兼容的

源数据类型
目标数据类型
源数据类型
目标数据类型
tinyint
smallint int bigint
nvarchar(max)
ntext
smallint
Int bigint
varbinary(max)
image
int
bigint
text
varchar(max)
timestamp
varbinary
ntext
nvarchar(max)
varchar(max)
text
image
varbinary(max)
ØSource Table必须至少包含一个:
n主键
n标识
nROWGUID 列
nUNIQUE列
n使用 -strict 选项时,Destination Table也必须至少包含一个上述列
Ø如果生成T-SQL脚本,则脚本中不包含下列数据类型的列:
nvarchar(max)
nnvarchar(max)
nvarbinary(max)
ntext
nntext
nimage
ntimestamp
nxml
下表说明TableDiff的使用语法及相关的参数说明

TableDiff 语法
参数说明
[ -? ] |
{
-sourceserver source_server_name[\instance_name]
-sourcedatabase source_database
-sourcetable source_table_name
[ -sourceschema source_schema_name ]
[ -sourcepassword source_password ]
[ -sourceuser source_login ]
[ -sourcelocked ]
-destinationserver destination_server_name[\instance_name]
-destinationdatabase subscription_database
-destinationtable destination_table
[ -destinationschema destination_schema_name ]
[ -destinationpassword destination_password ]
[ -destinationuser destination_login ]
[ -destinationlocked ]
[ -q ]
[ -c ]
[ -strict ]
[ -b large_object_bytes ]
[ -bf number_of_statements ]
[ -f [ file_name ] ]
[ -o output_file_name ]
[ -et table_name ]
[ -dt ]
[ -rc number_of_retries ]
[ -ri retry_interval ]
[ -t connection_timeouts ]
}
返回支持参数的列表
设置Source信息。
如果未指定 sourceuser,表示使用Windows身份验证。
Sourcelocked指定比较过程中锁定源表的方式,可以是TABLOCK或者HOLDLOCK, 未指定,则不锁定源表(NOLOCK)
设置Destination信息。
如果未指定 destinationuser,表示使用Windows身份验证。
destinationlocked指定比较过程中锁定目的表的方式,可以是TABLOCK或者HOLDLOCK, 未指定,则不锁定目的表(NOLOCK)
比较方式:
-q 只比较行数和架构
-c 比较列级差异,如果生成T-SQL脚本文件,则无论是否指定这个选项,都会进行列级差异比较
-strict 对源架构和目标架构进行严格比较
要比较的大型对象数据类型列的字节数,默认只比较前8000字节
生成T-SQL脚本的选项
-f 指定T-SQL脚本文件名
- bf 指定每个T-SQL脚本文件最多允许的语句数,超过此值会生成新脚本文件
输出文件的完整名称和路径
输出结果表
-et 指定输出结果表名(位于Subscriber)
如果结果表已经存在,则还需要指定-dt参数
指定连接相关的信息
-rc 指定失败重试的次数
-ri 指定重试的时间间隔
-t 指定连接超时时间
TableDiff的参数较长,根据使用的需求,下面的脚本可以帮助快速构建TableDiff命令。
DECLARE
@User sysname, @Pwd sysname, @lock sysname,
@Source nvarchar(1000), @Destination nvarchar(1000)
-- set parameters on here
SELECT
@User = '',
@Pwd = '',
@lock = 'HOLDLOCK',
@Source = N'publisher.pubs..titles',
@Destination = N'subscriber.pubs..titles'
SELECT 'tablediff'
+ ' /sourceserver' + QUOTENAME(sSrv, '"')
+ ' /sourcedatabase' + QUOTENAME(sDb, '"')
+ ' /sourceschema' + QUOTENAME(sSch, '"')
+ ' /sourcetable' + QUOTENAME(sTb, '"')
+ CASE
WHEN @lock IS NULL OR @lock = '' THEN ''
ELSE ' /sourcelocked' + QUOTENAME(@lock, '"') END
+ CASE
WHEN @User IS NULL OR @User = '' THEN ''
ELSE ' /sourceuser' + QUOTENAME(@User, '"')
+ ' /sourcepassword' + QUOTENAME(@Pwd, '"')
END
+ ' /destinationserver' + QUOTENAME(dSrv, '"')
+ ' /destinationdatabase' + QUOTENAME(dDb, '"')
+ ' /destinationschema' + QUOTENAME(dSch, '"')
+ ' /destinationtable' + QUOTENAME(dTb, '"')
+ CASE
WHEN @lock IS NULL OR @lock = '' THEN ''
ELSE ' /destinationlocked' + QUOTENAME(@lock, '"') END
+ CASE
WHEN @User IS NULL OR @User = '' THEN ''
ELSE ' /destinationuser' + QUOTENAME(@User, '"')
+ ' /destinationpassword' + QUOTENAME(@Pwd, '"')
END
--+ ' /q'
--+ ' /c'
--+ ' /strict'
--+ ' /b"8000"'
--+ ' /bf"10000"'
--+ ' /f"c:\syn.sql"'
--+ ' /o"c:\output.txt"'
--+ ' /et"TableDiffResult"'
--+ ' /dt'
--+ ' /rc"3"'
--+ ' /ri"300"'
--+ ' /t"15"'
FROM (
SELECT
sSrv = ISNULL(PARSENAME(Source, 4), N'localhost'),
sDb = ISNULL(PARSENAME(Source, 3), N'master'),
sSch = ISNULL(PARSENAME(Source, 2), N'dbo'),
sTb = ISNULL(PARSENAME(Source, 1), N'notable'),
dSrv = ISNULL(PARSENAME(Destination, 4), N'localhost'),
dDb = ISNULL(PARSENAME(Destination, 3), N'master'),
dSch = ISNULL(PARSENAME(Destination, 2), N'dbo'),
dTb = ISNULL(PARSENAME(Destination, 1), N'notable')
FROM(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值