现在的位置: 首页 > 综合 > 正文

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

2013年11月04日 ⁄ 综合 ⁄ 共 4219字 ⁄ 字号 评论关闭

 

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

源数据类型
目标数据类型
源数据类型
目标数据类型
tinyint
smallintintbigint
nvarchar(max)
ntext
smallint
Intbigint
varbinary(max)
image
int
bigint
text
varchar(max)
timestamp
varbinary
ntext
nvarchar(max)
varchar(max)
text
image
varbinary(max)
Ø Source Table必须至少包含一个:
主键
标识
ROWGUID 列
UNIQUE列
使用 -strict 选项时,Destination Table也必须至少包含一个上述列
Ø 如果生成T-SQL脚本,则脚本中不包含下列数据类型的列:
varchar(max)
nvarchar(max)
varbinary(max)
text
ntext
image
timestamp
xml
下表说明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'),

抱歉!评论已关闭.