重新初始化订阅

适用于: SQL Server Azure SQL 数据库

本主题说明如何通过使用 SQL Server Management Studio、Transact-SQL 或复制管理对象 (RMO) 在 SQL Server 中重新初始化订阅。 可以将各个订阅标记为重新初始化,以便在下次同步期间应用新快照。

注意

对于快照复制和事务复制,Azure SQL 托管实例可以是发布服务器、分发服务器和订阅服务器。 对于快照复制和事务复制,Azure SQL 数据库中的数据库只能是推送订阅服务器。 有关详细信息,请参阅使用 Azure SQL 数据库Azure SQL 托管实例进行事务复制。

使用 SQL Server Management Studio

重新初始化订阅的过程由两个部分组成:

  1. 将对发布的单个或所有订阅“标记” 为重新初始化。 在“重新初始化订阅”对话框中将订阅标记为重新初始化,该对话框可从 Microsoft SQL Server Management Studio 中的“本地发布”文件夹和“本地订阅”文件夹中获取。 也可以从 “所有订阅” 选项卡和复制监视器中的发布节点中对订阅进行标记。 有关启动复制监视器的信息,请参阅启动复制监视器。 将订阅标记为要重新初始化时,可以选择下列选项之一:

    使用当前快照
    选择此项可以在分发代理或合并代理下一次运行时将当前快照应用于订阅服务器。 如果无法获得有效快照,将无法选定此选项。

    使用新快照
    选择此项可以用新的快照来重新初始化订阅。 只有在快照代理已经生成新快照之后,才能将其应用于订阅服务器。 如果快照代理设置为按计划运行,则直到下一个计划的快照代理运行后才能重新初始化订阅。 选择 “立即生成新快照” 可以立即启动快照代理。

    在重新初始化之前上载未同步的更改
    仅限合并复制。 选择此项可以在用快照覆盖订阅服务器上的数据之前,从订阅数据库上载任何挂起的更改。

    如果添加、删除或更改参数化筛选器,则订阅服务器上挂起的更改在重新初始化期间将无法上载到发布服务器。 若要上载挂起的更改,请在更改筛选器前同步所有订阅。

  2. 在下次同步订阅时将重新初始化订阅:分发代理(用于事务复制)或合并代理(用于合并复制)将最近的快照应用于每个包含有标记为要重新初始化的订阅的订阅服务器。 有关同步订阅的详细信息,请参阅 Synchronize a Push SubscriptionSynchronize a Pull Subscription文件夹中打开。

在 Management Studio 中将单个推送订阅或单个请求订阅(位于发布服务器上)标记为要重新初始化

  1. 在 Management Studio 中连接到发布服务器,然后展开服务器节点。

  2. 展开 “复制” 文件夹,再展开 “本地发布” 文件夹。

  3. 展开包含要重新初始化的订阅的发布。

  4. 右键单击订阅,再单击 “重新初始化”

  5. “重新初始化订阅” 对话框中,选择选项,然后单击 “标记为要重新初始化”

在 Management Studio 中将单个请求订阅(位于订阅服务器)标记为要重新初始化

  1. 在 Management Studio 中连接到订阅服务器,然后展开服务器节点。

  2. 展开 “复制” 文件夹,再展开 “本地订阅” 文件夹。

  3. 右键单击订阅,再单击 “重新初始化”

  4. 在显示的确认对话框中,单击 “是”

在 Management Studio 中将所有订阅标记为要重新初始化

  1. 在 Management Studio 中连接到发布服务器,然后展开服务器节点。

  2. 展开 “复制” 文件夹,再展开 “本地发布” 文件夹。

  3. 右键单击具有要重新初始化的订阅的发布,再单击 “重新初始化所有订阅”

  4. “重新初始化订阅” 对话框中,选择选项,然后单击 “标记为要重新初始化”

在复制监视器中将单个推送订阅或单个请求订阅标记为要重新初始化

  1. 在复制监视器的左窗格中依次展开发布服务器组、发布服务器,再单击一个发布。

  2. 单击 “所有订阅” 选项卡。

  3. 右键单击要重新初始化的订阅,然后单击 “重新初始化订阅”

  4. “重新初始化订阅” 对话框中,选择选项,然后单击 “标记为要重新初始化”

在复制监视器中将所有订阅标记为要重新初始化

  1. 在复制监视器的左窗格中依次展开发布服务器组、发布服务器。

  2. 右键单击具有要重新初始化的订阅的发布,再单击 “重新初始化所有订阅”

  3. “重新初始化订阅” 对话框中,选择选项,然后单击 “标记为要重新初始化”

“使用 Transact-SQL”

可以使用复制存储过程以编程方式重新初始化订阅。 使用的存储过程取决于订阅的类型(推送或请求)以及订阅所属的发布的类型。

重新初始化对事务发布的请求订阅

  1. 在订阅服务器上,对订阅数据库执行 sp_reinitpullsubscription (Transact-SQL)。 指定 @publisher@publisher_db@publication。 这会将订阅标记为在下一次运行分发代理时将要重新初始化。

  2. (可选)在订阅服务器上启动分发代理,以使订阅同步。 有关详细信息,请参阅 Synchronize a Pull Subscription

重新初始化对事务发布的推送订阅

  1. 在发布服务器上,执行 sp_reinitsubscription (Transact-SQL)。 指定 @publication@subscriber@destination_db。 这会将订阅标记为在下一次运行分发代理时将要重新初始化。

  2. (可选)在分发服务器上启动分发代理,以使订阅同步。 有关详细信息,请参阅 同步推送订阅

重新初始化对合并发布的请求订阅

  1. 在订阅服务器上,对订阅数据库执行 sp_reinitmergepullsubscription (Transact-SQL)。 指定 @publisher@publisher_db@publication。 若要在进行重新初始化之前从订阅服务器上载更改,请将 @upload_first 的值指定为 true。 这会将订阅标记为在下一次运行合并代理时将要重新初始化。

    重要

    如果添加、删除或更改参数化筛选器,则订阅服务器上挂起的更改在重新初始化期间将无法上载到发布服务器。 若要上载挂起的更改,请在更改筛选器前同步所有订阅。

  2. (可选)在订阅服务器上启动合并代理,以使订阅同步。 有关详细信息,请参阅 Synchronize a Pull Subscription

重新初始化对合并发布的推送订阅

  1. 在发布服务器上,执行 sp_reinitmergesubscription (Transact-SQL)。 指定 @publication@subscriber@subscriber_db。 若要在进行重新初始化之前从订阅服务器上载更改,请将 @upload_first 的值指定为 true。 这会将订阅标记为在下一次运行分发代理时将要重新初始化。

    重要

    如果添加、删除或更改参数化筛选器,则订阅服务器上挂起的更改在重新初始化期间将无法上载到发布服务器。 若要上载挂起的更改,请在更改筛选器前同步所有订阅。

  2. (可选)在分发服务器上启动合并代理,以使订阅同步。 有关详细信息,请参阅 同步推送订阅

创建新的合并发布时设置重新初始化策略

  1. 在发布服务器上,对发布数据库执行 sp_addmergepublication,同时为 @automatic_reinitialization_policy指定下列值之一:

    • 1 - 在对订阅执行更改所要求的自动重新初始化操作之前,从订阅服务器上载更改。

    • 0 - 在对订阅执行发布更改所要求的自动重新初始化操作时,放弃订阅服务器上的更改。

    重要

    如果添加、删除或更改参数化筛选器,则订阅服务器上挂起的更改在重新初始化期间将无法上载到发布服务器。 若要上载挂起的更改,请在更改筛选器前同步所有订阅。

    有关详细信息,请参阅 Create a Publication

更改现有合并发布的重新初始化策略

  1. 在发布服务器上,对发布数据库执行 sp_changemergepublication,同时将 @property 的值指定为 automatic_reinitialization_policy 并为 @value指定下列值之一:

    • 1 - 在对订阅执行更改所要求的自动重新初始化操作之前,从订阅服务器上载更改。

    • 0 - 在对订阅执行发布更改所要求的自动重新初始化操作时,放弃订阅服务器上的更改。

    重要

    如果添加、删除或更改参数化筛选器,则订阅服务器上挂起的更改在重新初始化期间将无法上载到发布服务器。 若要上载挂起的更改,请在更改筛选器前同步所有订阅。

    有关详细信息,请参阅 View and Modify Publication Properties

使用复制管理对象 (RMO)

可以将各个订阅标记为重新初始化,以便在下次同步期间应用新的快照。 可以使用复制管理对象 (RMO) 以编程的方式重新初始化订阅。 所用的类取决于订阅所属的发布类型以及订阅类型(即推送订阅或请求订阅)。

重新初始化对事务发布的请求订阅

  1. 使用 ServerConnection 类创建与订阅服务器的连接。

  2. 创建 TransPullSubscription 类的实例,并设置 PublicationNameDatabaseNamePublisherNamePublicationDBName以及步骤 1 中 ConnectionContext的连接。

  3. 调用 LoadProperties 方法获取该对象的属性。

    注意

    如果此方法返回 false,则步骤 2 中对订阅属性的定义不正确,或者请求订阅不存在。

  4. 调用 Reinitialize 方法。 此方法将订阅标记为要重新初始化。

  5. 同步请求订阅。 有关详细信息,请参阅 Synchronize a Pull Subscription

重新初始化对事务发布的推送订阅

  1. 使用 ServerConnection 类创建与发布服务器的连接。

  2. 创建 TransSubscription 类的实例,并设置 PublicationNameDatabaseNameSubscriberNameSubscriptionDBName以及步骤 1 中 ConnectionContext的连接。

  3. 调用 LoadProperties 方法获取该对象的属性。

    注意

    如果此方法返回 false,则步骤 2 中对订阅属性的定义不正确,或者推送订阅不存在。

  4. 调用 Reinitialize 方法。 此方法将订阅标记为要重新初始化。

  5. 同步推送订阅。 有关详细信息,请参阅 同步推送订阅

重新初始化对合并发布的请求订阅

  1. 使用 ServerConnection 类创建与订阅服务器的连接。

  2. 创建 MergePullSubscription 类的实例,并设置 PublicationNameDatabaseNamePublisherNamePublicationDBName以及步骤 1 中 ConnectionContext的连接。

  3. 调用 LoadProperties 方法获取该对象的属性。

    注意

    如果此方法返回 false,则步骤 2 中对订阅属性的定义不正确,或者请求订阅不存在。

  4. 调用 Reinitialize 方法。 传递 true 值以在重新初始化之前上载订阅服务器上的更改,或者传递 false 值以重新初始化并丢失订阅服务器上任何挂起的更改。 此方法将订阅标记为要重新初始化。

    注意

    如果订阅过期,则无法上载更改。 有关详细信息,请参阅 Set the Expiration Period for Subscriptions

  5. 同步请求订阅。 有关详细信息,请参阅 Synchronize a Pull Subscription

重新初始化对合并发布的推送订阅

  1. 使用 ServerConnection 类创建与发布服务器的连接。

  2. 创建 MergeSubscription 类的实例,并设置 PublicationNameDatabaseNameSubscriberNameSubscriptionDBName以及步骤 1 中 ConnectionContext的连接。

  3. 调用 LoadProperties 方法获取该对象的属性。

    注意

    如果此方法返回 false,则步骤 2 中对订阅属性的定义不正确,或者推送订阅不存在。

  4. 调用 Reinitialize 方法。 传递 true 值以在重新初始化之前上载订阅服务器上的更改,或者传递 false 值以重新初始化并丢失订阅服务器上任何挂起的更改。 此方法将订阅标记为要重新初始化。

    注意

    如果订阅过期,则无法上载更改。 有关详细信息,请参阅 Set the Expiration Period for Subscriptions

  5. 同步推送订阅。 有关详细信息,请参阅 同步推送订阅

示例 (RMO)

此示例将重新初始化事务发布的请求订阅。

// Define server, publication, and database names.
String subscriberName = subscriberInstance;
String publisherName = publisherInstance;
String publicationName = "AdvWorksProductTran";
String publicationDbName = "AdventureWorks2022";
String subscriptionDbName = "AdventureWorks2022Replica";

// Create a connection to the Subscriber.
ServerConnection conn = new ServerConnection(subscriberName);

TransPullSubscription subscription;

try
{
    // Connect to the Subscriber.
    conn.Connect();

    // Define subscription properties.
    subscription = new TransPullSubscription();
    subscription.ConnectionContext = conn;
    subscription.DatabaseName = subscriptionDbName;
    subscription.PublisherName = publisherName;
    subscription.PublicationDBName = publicationDbName;
    subscription.PublicationName = publicationName;

    // If the pull subscription and the job exists, mark the subscription
    // for reinitialization and start the agent job.
    if (subscription.LoadProperties() && subscription.AgentJobId != null)
    {
        subscription.Reinitialize();
        subscription.SynchronizeWithJob();
    }
    else
    {
        // Do something here if the subscription does not exist.
        throw new ApplicationException(String.Format(
            "A subscription to '{0}' does not exists on {1}",
            publicationName, subscriberName));
    }
}
catch (Exception ex)
{
    // Do appropriate error handling here.
    throw new ApplicationException("The subscription could not be reinitialized.", ex);
}
finally
{
    conn.Disconnect();
}
' Define server, publication, and database names.
Dim subscriberName As String = subscriberInstance
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksProductTran"
Dim publicationDbName As String = "AdventureWorks2022"
Dim subscriptionDbName As String = "AdventureWorks2022Replica"

' Create a connection to the Subscriber.
Dim conn As ServerConnection = New ServerConnection(subscriberName)

Dim subscription As TransPullSubscription

Try
    ' Connect to the Subscriber.
    conn.Connect()

    ' Define subscription properties.
    subscription = New TransPullSubscription()
    subscription.ConnectionContext = conn
    subscription.DatabaseName = subscriptionDbName
    subscription.PublisherName = publisherName
    subscription.PublicationDBName = publicationDbName
    subscription.PublicationName = publicationName

    ' If the pull subscription and the job exists, mark the subscription
    ' for reinitialization and start the agent job.
    If subscription.LoadProperties() And (Not subscription.AgentJobId Is Nothing) Then
        subscription.Reinitialize()
        subscription.SynchronizeWithJob()
    Else
        ' Do something here if the subscription does not exist.
        Throw New ApplicationException(String.Format( _
         "A subscription to '{0}' does not exists on {1}", _
         publicationName, subscriberName))
    End If
Catch ex As Exception
    ' Do appropriate error handling here.
    Throw New ApplicationException("The subscription could not be reinitialized.", ex)
Finally
    conn.Disconnect()
End Try

此示例将在第一次上载订阅服务器上挂起的更改后,重新初始化合并发布的请求订阅。

// Define server, publication, and database names.
String subscriberName = subscriberInstance;
String publisherName = publisherInstance;
String publicationName = "AdvWorksSalesOrdersMerge";
String publicationDbName = "AdventureWorks2022";
String subscriptionDbName = "AdventureWorks2022Replica";

// Create a connection to the Subscriber.
ServerConnection conn = new ServerConnection(subscriberName);

MergePullSubscription subscription;

try
{
    // Connect to the Subscriber.
    conn.Connect();

    // Define subscription properties.
    subscription = new MergePullSubscription();
    subscription.ConnectionContext = conn;
    subscription.DatabaseName = subscriptionDbName;
    subscription.PublisherName = publisherName;
    subscription.PublicationDBName = publicationDbName;
    subscription.PublicationName = publicationName;

    // If the pull subscription and the job exists, mark the subscription
    // for reinitialization after upload and start the agent job.
    if (subscription.LoadProperties() && subscription.AgentJobId != null)
    {
        subscription.Reinitialize(true);
        subscription.SynchronizeWithJob();
    }
    else
    {
        // Do something here if the subscription does not exist.
        throw new ApplicationException(String.Format(
            "A subscription to '{0}' does not exists on {1}",
            publicationName, subscriberName));
    }
}
catch (Exception ex)
{
    // Do appropriate error handling here.
    throw new ApplicationException("The subscription could not be synchronized.", ex);
}
finally
{
    conn.Disconnect();
}
' Define server, publication, and database names.
Dim subscriberName As String = subscriberInstance
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2022"
Dim subscriptionDbName As String = "AdventureWorks2022Replica"

' Create a connection to the Subscriber.
Dim conn As ServerConnection = New ServerConnection(subscriberName)

Dim subscription As MergePullSubscription

Try
    ' Connect to the Subscriber.
    conn.Connect()

    ' Define subscription properties.
    subscription = New MergePullSubscription()
    subscription.ConnectionContext = conn
    subscription.DatabaseName = subscriptionDbName
    subscription.PublisherName = publisherName
    subscription.PublicationDBName = publicationDbName
    subscription.PublicationName = publicationName

    ' If the pull subscription and the job exists, mark the subscription
    ' for reinitialization after upload and start the agent job.
    If subscription.LoadProperties() And (Not subscription.AgentJobId Is Nothing) Then
        subscription.Reinitialize(True)
        subscription.SynchronizeWithJob()
    Else
        ' Do something here if the subscription does not exist.
        Throw New ApplicationException(String.Format( _
         "A subscription to '{0}' does not exists on {1}", _
         publicationName, subscriberName))
    End If
Catch ex As Exception
    ' Do appropriate error handling here.
    Throw New ApplicationException("The subscription could not be synchronized.", ex)
Finally
    conn.Disconnect()
End Try