在订阅服务器上验证数据
本主题说明如何使用 SQL Server Management Studio、Transact-SQL 或复制管理对象 (RMO) 在 SQL Server 2012 中验证订阅服务器上的数据。
验证数据分为三个部分:
将对发布的单个或所有订阅“标记”为要验证。 可以在**“验证单个订阅”、“验证多个订阅”和“验证所有订阅”对话框中,将订阅标记为要验证,这些对话框可以通过 Microsoft SQL Server Management Studio 中的“本地发布”文件夹和“本地订阅”文件夹访问。 也可以从“所有订阅”选项卡、“订阅监视列表”**选项卡和复制监视器中的发布节点中对订阅进行标记。 有关启动复制监视器的信息,请参阅启动复制监视器。
下次分发代理(对于事务复制)或合并代理(对于合并复制)同步订阅时,将对订阅进行验证。 分发代理通常是连续运行的,在这种情况下验证会立即进行;合并代理通常是按需运行的,在这种情况下验证在运行代理后进行。
查看验证结果:
在复制监视器的详细信息窗口中查看:对于事务复制,在**“分发服务器到订阅服务器的历史记录”选项卡中;对于合并复制,在“同步历史记录”**选项卡中。
在 Management Studio 的**“查看同步状态”**对话框中查看。
本主题内容
开始之前:
限制和局限
验证订阅服务器上的数据,使用:
SQL Server Management Studio
Transact-SQL
复制管理对象 (RMO)
开始之前
限制和局限
复制监视器的过程仅适用于推送订阅,因为请求订阅不能在复制监视器中同步。 但是,可以在复制监视器中将订阅标记为要验证并查看请求订阅的验证结果。
验证结果指示验证是成功还是失败,但如果失败,并不指定哪些行验证失败。 若要比较发布服务器和订阅服务器中的数据,请使用 tablediff 实用工具。 有关使用此实用工具处理复制数据的详细信息,请参阅比较所复制表的差异(复制编程)。
[Top]
使用 SQL Server Management Studio
验证事务发布的订阅的数据 (Management Studio)
在 SQL Server Management Studio 中连接到发布服务器,然后展开服务器节点。
展开**“复制”文件夹,再展开“本地发布”**文件夹。
右键单击要验证其订阅的发布,然后单击**“验证多个订阅”**。
在**“验证多个订阅”**对话框中,选择要验证的订阅:
选择**“验证所有 SQL Server 订阅”**。
选择**“验证下列订阅”**,再选择一个或多个订阅。
若要指定要执行的验证类型(行计数,或行计数和校验和),请单击**“验证选项”,然后在“订阅验证选项”**对话框中指定选项。
单击“确定”。
在复制监视器或**“查看同步状态”**对话框中查看验证结果。 对于每个订阅:
展开发布,右键单击该订阅,然后单击**“查看同步状态”**。
如果代理未运行,请单击**“查看同步状态”对话框中的“启动”**。 该对话框将显示有关验证的信息性消息。
如果未显示有关验证的任何消息,则说明该代理已记录了后续消息。 在这种情况下,请在复制监视器中查看验证结果。 有关详细信息,请参阅本主题中有关复制监视器相关操作的过程。
验证合并发布的单个订阅的数据 (Management Studio)
在 SQL Server Management Studio 中连接到发布服务器,然后展开服务器节点。
展开**“复制”文件夹,再展开“本地发布”**文件夹。
展开要验证其订阅的发布,右键单击该订阅,然后单击**“验证单个订阅”**。
在**“验证单个订阅”对话框中,选择“验证此订阅”**。
若要指定要执行的验证类型(行计数,或行计数和校验和),请单击**“选项”,然后在“订阅验证选项”**对话框中指定选项。
单击“确定”。
在复制监视器或**“查看同步状态”**对话框中查看验证结果:
展开发布,右键单击该订阅,然后单击**“查看同步状态”**。
如果代理未运行,请单击**“查看同步状态”对话框中的“启动”**。 该对话框将显示有关验证的信息性消息。
如果未显示有关验证的任何消息,则说明该代理已记录了后续消息。 在这种情况下,请在复制监视器中查看验证结果。 有关详细信息,请参阅本主题中有关复制监视器相关操作的过程。
验证合并发布的所有订阅的数据 (Management Studio)
在 SQL Server Management Studio 中连接到发布服务器,然后展开服务器节点。
展开**“复制”文件夹,再展开“本地发布”**文件夹。
右键单击要验证其订阅的发布,然后单击**“验证所有订阅”**。
在**“验证所有订阅”**对话框中,指定要执行的验证类型(行计数,或行计数和校验和)。
单击“确定”。
在复制监视器或**“查看同步状态”**对话框中查看验证结果。 对于每个订阅:
展开发布,右键单击该订阅,然后单击**“查看同步状态”**。
如果代理未运行,请单击**“查看同步状态”对话框中的“启动”**。 该对话框将显示有关验证的信息性消息。
如果未显示有关验证的任何消息,则说明该代理已记录了后续消息。 在这种情况下,请在复制监视器中查看验证结果。 有关详细信息,请参阅本主题中有关复制监视器相关操作的过程。
验证事务发布的所有推送订阅的数据(复制监视器)
在复制监视器的左窗格中,展开发布服务器组,再展开一个发布服务器。
右键单击要验证其订阅的发布,然后单击**“验证多个订阅”**。
在**“验证多个订阅”**对话框中,选择要验证的订阅:
选择**“验证所有 SQL Server 订阅”**。
选择**“验证下列订阅”**,再选择一个或多个订阅。
若要指定要执行的验证类型(行计数,或行计数和校验和),请单击**“验证选项”,然后在“订阅验证选项”**对话框中指定选项。
单击“确定”。
单击**“所有订阅”**选项卡。
查看验证结果。 对于每个推送订阅:
如果代理未运行,请右键单击该订阅,然后单击**“开始同步”**。
右键单击该订阅,然后单击**“查看详细信息”**。
在**“所选会话中的操作”文本区域中的“分发服务器到订阅服务器的历史记录”**选项卡中,查看信息。
验证合并发布的单个推送订阅的数据(复制监视器)
在复制监视器的左窗格中,展开发布服务器组,再展开一个发布服务器,然后单击一个发布。
单击**“所有订阅”**选项卡。
右键单击要验证的订阅,然后单击**“验证单个订阅”**。
在**“验证单个订阅”对话框中,选择“验证此订阅”**。
若要指定要执行的验证类型(行计数,或行计数和校验和),请单击**“选项”,然后在“订阅验证选项”**对话框中指定选项。
单击“确定”。
单击**“所有订阅”**选项卡。
查看验证结果:
如果代理未运行,请右键单击该订阅,然后单击**“开始同步”**。
右键单击该订阅,然后单击**“查看详细信息”**。
在**“所选会话的最后消息”文本区域中的“同步历史记录”**选项卡上,查看信息。
验证合并发布的所有推送订阅的数据(复制监视器)
在复制监视器的左窗格中,展开发布服务器组,再展开一个发布服务器。
右键单击要验证其订阅的发布,然后单击**“验证所有订阅”**。
在**“验证所有订阅”**对话框中,指定要执行的验证类型(行计数,或行计数和校验和)。
单击“确定”。
单击**“所有订阅”**选项卡。
查看验证结果。 对于每个推送订阅:
如果代理未运行,请右键单击该订阅,然后单击**“开始同步”**。
右键单击该订阅,然后单击**“查看详细信息”**。
在**“所选会话的最后消息”文本区域中的“同步历史记录”**选项卡上,查看信息。
[Top]
使用 Transact-SQL
验证事务发布中所有项目的数据
在发布服务器上,对发布数据库执行 sp_publication_validation (Transact-SQL)。 指定 @publication 并为 @rowcount_only 指定以下值之一:
1 - 只检查行计数(默认值)
2 - 行计数和二进制校验和。
注意
执行 sp_publication_validation (Transact-SQL) 时,将对发布中的每个项目都执行 sp_article_validation (Transact-SQL)。 若要成功地执行 sp_publication_validation (Transact-SQL),必须对发布的基表中的所有列拥有 SELECT 权限。
检查代理输出以获取验证结果。 有关详细信息,请参阅验证已复制的数据。
验证事务发布中单个项目的数据
在发布服务器上,对发布数据库执行 sp_article_validation (Transact-SQL)。 指定 @publication、为 @article 指定项目名称并为 @rowcount_only 指定以下值之一:
1 - 只检查行计数(默认值)
2 - 行计数和二进制校验和。
注意
若要成功执行 sp_article_validation (Transact-SQL),必须对发布的基表中的所有列拥有 SELECT 权限。
检查代理输出以获取验证结果。 有关详细信息,请参阅验证已复制的数据。
验证订阅事务发布的单个订阅服务器的数据
在发布服务器的发布数据库中,使用 BEGIN TRANSACTION (Transact-SQL) 打开一个显式事务。
在发布服务器上,对发布数据库执行 sp_marksubscriptionvalidation (Transact-SQL)。 为 @publication 指定发布,为 @subscriber 指定订阅服务器的名称,并为 @destination_db 指定订阅数据库的名称。
(可选)对每个要验证的订阅都重复步骤 2。
在发布服务器上,对发布数据库执行 sp_article_validation (Transact-SQL)。 指定 @publication、为 @article 指定项目名称并为 @rowcount_only 指定以下值之一:
1 - 只检查行计数(默认值)
2 - 行计数和二进制校验和。
注意
若要成功执行 sp_article_validation (Transact-SQL),必须对发布的基表中的所有列拥有 SELECT 权限。
在发布服务器的发布数据库中,使用 COMMIT TRANSACTION (Transact-SQL) 提交事务。
(可选)为每个要验证的项目都重复步骤 1 到步骤 5。
检查代理输出以获取验证结果。 有关详细信息,请参阅在订阅服务器上验证数据。
验证合并发布的所有订阅中的数据
在发布服务器上,对发布数据库执行 sp_validatemergepublication (Transact-SQL)。 指定 @publication 并为 @level 指定以下值之一:
1 - 只验证行计数。
3 - 行计数二进制校验和验证。
这样会标记所有订阅以便验证。
检查代理输出以获取验证结果。 有关详细信息,请参阅在订阅服务器上验证数据。
验证订阅合并发布的所选订阅中的数据
在发布服务器上,对发布数据库执行 sp_validatemergesubscription (Transact-SQL)。 指定 @publication,为 @subscriber 指定订阅服务器的名称,为 @subscriber_db 指定订阅数据库的名称,并为 @level 指定以下值之一:
1 - 只验证行计数。
3 - 行计数二进制校验和验证。
这样会标记所选订阅以便验证。
检查代理输出以获取验证结果。
为每个要验证的订阅重复步骤 1 到步骤 3。
![]() |
---|
通过在运行 复制合并代理 时指定 -Validate 参数还可以在同步结束时验证对合并发布的订阅。 |
使用合并代理参数验证订阅中的数据
通过以下方式之一从命令提示符下启动订阅服务器(请求订阅)或分发服务器(推送订阅)上的合并代理。
为 -Validate 参数指定值 1(行计数)或 3(行计数和二进制校验和)。
为 -ProfileName 参数指定 rowcount validation 或 rowcount and checksum validation。
[Top]
使用复制管理对象 (RMO)
通过使用复制,您可以使用复制管理对象 (RMO) 以编程方式验证订阅服务器上的数据是否与发布服务器上的数据匹配。 使用的对象取决于复制拓扑的类型。 事务复制要求验证发布的所有订阅。
![]() |
---|
有关示例,请参阅本节后面的示例 (RMO)。 |
验证事务发布中所有项目的数据
使用 ServerConnection 类创建与发布服务器的连接。
创建 TransPublication 类的实例。 设置发布的 Name 和 DatabaseName 属性。 将 ConnectionContext 属性设置为步骤 1 中创建的连接。
调用 LoadProperties 方法获取该对象的其余属性。 如果此方法返回 false,则说明步骤 2 中的发布属性定义不正确,或者此发布不存在。
调用 ValidatePublication 方法。 传递以下参数:
一个布尔值,指示是否在验证完成后停止分发代理。
这将把项目标记为等待验证。
如果尚未运行,则启动分发代理以同步每个订阅。 有关详细信息,请参阅同步推送订阅或同步请求订阅。 验证操作的结果将写入代理历史记录。 有关详细信息,请参阅监视复制。
验证合并发布的所有订阅中的数据
使用 ServerConnection 类创建与发布服务器的连接。
创建 MergePublication 类的实例。 设置发布的 Name 和 DatabaseName 属性。 将 ConnectionContext 属性设置为步骤 1 中创建的连接。
调用 LoadProperties 方法获取该对象的其余属性。 如果此方法返回 false,则说明步骤 2 中的发布属性定义不正确,或者此发布不存在。
调用 ValidatePublication 方法。 传递所需的 ValidationOption。
对每个订阅运行合并代理以开始验证,或者等待下一个计划的代理运行。 有关详细信息,请参阅同步请求订阅和同步推送订阅。 验证操作的结果将写入代理的历史记录,您可以使用复制监视器查看。 有关详细信息,请参阅监视复制。
验证合并发布的单个订阅中的数据
使用 ServerConnection 类创建与发布服务器的连接。
创建 MergePublication 类的实例。 设置发布的 Name 和 DatabaseName 属性。 将 ConnectionContext 属性设置为步骤 1 中创建的连接。
调用 LoadProperties 方法获取该对象的其余属性。 如果此方法返回 false,则说明步骤 2 中的发布属性定义不正确,或者此发布不存在。
调用 ValidateSubscription 方法。 传递要验证的订阅服务器和订阅数据库的名称以及所需的 ValidationOption。
对订阅运行合并代理以开始验证,或者等待下一个计划的代理运行。 有关详细信息,请参阅同步请求订阅和同步推送订阅。 验证操作的结果将写入代理的历史记录,您可以使用复制监视器查看。 有关详细信息,请参阅监视复制。
示例 (RMO)
此示例将对事务发布的所有订阅标记为行计数验证。
// Define the server, database, and publication names
string publisherName = publisherInstance;
string publicationName = "AdvWorksProductTran";
string publicationDbName = "AdventureWorks2012";
TransPublication publication;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Set the required properties for the publication.
publication = new TransPublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// If we can't get the properties for this publication,
// throw an application exception.
if (publication.LoadProperties())
{
// Initiate validataion for all subscriptions to this publication.
publication.ValidatePublication(ValidationOption.RowCountOnly,
ValidationMethod.ConditionalFast, false);
// If not already running, start the Distribution Agent at each
// Subscriber to synchronize and validate the subscriptions.
}
else
{
throw new ApplicationException(String.Format(
"Settings could not be retrieved for the publication. " +
"Ensure that the publication {0} exists on {1}.",
publicationName, publisherName));
}
}
catch (Exception ex)
{
// Do error handling here.
throw new ApplicationException(
"Subscription validation could not be initiated.", ex);
}
finally
{
conn.Disconnect();
}
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksProductTran"
Dim publicationDbName As String = "AdventureWorks2012"
Dim publication As TransPublication
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
Try
' Connect to the Publisher.
conn.Connect()
' Set the required properties for the publication.
publication = New TransPublication()
publication.ConnectionContext = conn
publication.Name = publicationName
publication.DatabaseName = publicationDbName
' If we can't get the properties for this publication,
' throw an application exception.
If publication.LoadProperties() Then
' Initiate validataion for all subscriptions to this publication.
publication.ValidatePublication(ValidationOption.RowCountOnly, _
ValidationMethod.ConditionalFast, False)
' If not already running, start the Distribution Agent at each
' Subscriber to synchronize and validate the subscriptions.
Else
Throw New ApplicationException(String.Format( _
"Settings could not be retrieved for the publication. " + _
"Ensure that the publication {0} exists on {1}.", _
publicationName, publisherName))
End If
Catch ex As Exception
' Do error handling here.
Throw New ApplicationException( _
"Subscription validation could not be initiated.", ex)
Finally
conn.Disconnect()
End Try
此示例将对合并发布的特定订阅标记为行计数验证。
// Define the server, database, and publication names
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks2012";
string subscriberName = subscriberInstance;
string subscriptionDbName = "AdventureWorks2012Replica";
MergePublication publication;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Set the required properties for the publication.
publication = new MergePublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// If we can't get the properties for this merge publication, then throw an application exception.
if (publication.LoadProperties())
{
// Initiate validation of the specified subscription.
publication.ValidateSubscription(subscriberName,
subscriptionDbName, ValidationOption.RowCountOnly);
// Start the Merge Agent to synchronize and validate the subscription.
}
else
{
throw new ApplicationException(String.Format(
"Settings could not be retrieved for the publication. " +
"Ensure that the publication {0} exists on {1}.",
publicationName, publisherName));
}
}
catch (Exception ex)
{
// Do error handling here.
throw new ApplicationException(String.Format(
"The subscription at {0} to the {1} publication could not " +
"be validated.", subscriberName, publicationName), ex);
}
finally
{
conn.Disconnect();
}
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2012"
Dim subscriberName As String = subscriberInstance
Dim subscriptionDbName As String = "AdventureWorks2012Replica"
Dim publication As MergePublication
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
Try
' Connect to the Publisher.
conn.Connect()
' Set the required properties for the publication.
publication = New MergePublication()
publication.ConnectionContext = conn
publication.Name = publicationName
publication.DatabaseName = publicationDbName
' If we can't get the properties for this merge publication, then throw an application exception.
If publication.LoadProperties() Then
' Initiate validation of the specified subscription.
publication.ValidateSubscription(subscriberName, _
subscriptionDbName, ValidationOption.RowCountOnly)
' Start the Merge Agent to synchronize and validate the subscription.
Else
Throw New ApplicationException(String.Format( _
"Settings could not be retrieved for the publication. " + _
"Ensure that the publication {0} exists on {1}.", _
publicationName, publisherName))
End If
Catch ex As Exception
' Do error handling here.
Throw New ApplicationException(String.Format( _
"The subscription at {0} to the {1} publication could not " + _
"be validated.", subscriberName, publicationName), ex)
Finally
conn.Disconnect()
End Try
[Top]