重新初始化订阅

本主题介绍如何使用 SQL Server Management Studio、Transact-SQL 或复制管理对象(RMO)在 SQL Server 2014 中重新初始化订阅。 可以将具体订阅标记为重新初始化,以便在下次同步时应用新的快照。

本主题内容

使用 SQL Server Management Studio

重新初始化订阅的过程分为两部分:

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

    使用当前快照
    选择在分发代理或合并代理下次运行时将当前快照应用到订阅服务器。 如果没有可用的有效快照,则无法选择此选项。

    使用新快照
    选择以使用新快照重新初始化订阅。 仅当快照代理生成快照后,才能将快照应用于订阅方。 如果快照代理设置为按计划运行,则在下次计划的快照代理运行之后,订阅才会重新初始化。 选择“ 立即生成新快照 ”以立即启动快照代理。

    在重新初始化之前上传未同步的更改
    仅限于合并复制。 在数据被快照覆盖到订阅方之前,选择上传来自订阅数据库的任何待处理的更改。

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

  2. 订阅将于下次重新同步时重新初始化:分发代理(用于事务复制)或合并代理(用于合并复制)会将最新的快照应用于每个标记为需重新初始化的订阅者。 有关同步订阅的详细信息,请参阅 同步推送订阅同步请求订阅

在发布服务器的 Management Studio 中标记单个推送或拉取订阅以进行重新初始化

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

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

  3. 展开包含所需重新初始化订阅的出版物。

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

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

在 Management Studio 中标记用于重新初始化的单个请求订阅(在订阅服务器上)

  1. 在 SQL Server 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. (可选)在订阅服务器上启动分发代理以同步订阅。 有关详细信息,请参阅 同步请求订阅

将一个事务性发布的推送订阅重新初始化

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

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

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

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

    重要

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

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

重新初始化推送订阅以进行合并发布

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

    重要

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

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

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

  1. 在发布者的发布数据库上,执行 sp_addmergepublication,为 @automatic_reinitialization_policy指定以下值之一:

    • 1 - 更改由订阅者上传,然后由于出版物的更改,订阅会自动重新初始化。

    • 0 - 当订阅因发布变更而被自动重新初始化时,订阅者所做的更改将被丢弃。

    重要

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

    有关详细信息,请参阅 “创建发布”。

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

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

    • 1 - 更改会从订阅用户上传,然后根据发布更改的要求,订阅会自动重新初始化。

    • 0 - 当订阅因发布更改而需要自动重新初始化时,订阅者处的更改将被丢弃。

    重要

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

    有关详细信息,请参阅 “查看和修改发布属性”。

使用复制管理对象 (RMO)

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

重新初始化事务发布的拉取订阅

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

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

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

    注释

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

  4. 调用 Reinitialize 方法。 此方法标记用于重新初始化的订阅。

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

将推送订阅重新初始化到事务发布

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

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

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

    注释

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

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

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

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

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

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

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

    注释

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

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

    注释

    如果订阅已过期,则无法上传更改。 有关详细信息,请参阅 设置订阅的过期期限

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

将推送订阅重新初始化到合并发布

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

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

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

    注释

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

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

    注释

    如果订阅已过期,则无法上传更改。 有关详细信息,请参阅 设置订阅的过期期限

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

示例 (RMO)

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

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

// 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 = "AdventureWorks2012"
Dim subscriptionDbName As String = "AdventureWorks2012Replica"

' 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 = "AdventureWorks2012";
String subscriptionDbName = "AdventureWorks2012Replica";

// 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 = "AdventureWorks2012"
Dim subscriptionDbName As String = "AdventureWorks2012Replica"

' 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

另请参阅

重新初始化订阅
复制管理对象概念
复制安全最佳做法