【问题标题】:On demand SQL snapshot replication synchronization with PowerShell与 PowerShell 的按需 SQL 快照复制同步
【发布时间】:2021-08-10 22:00:50
【问题描述】:

我正在尝试创建一个 PowerShell 脚本,以便更轻松地执行从我们的主数据服务器到我们的测试服务器的按需同步。我们目前正在使用快照复制,并且仅在项目之间同步数据,因此可能需要数天或数周才能更新数据。涉及到许多数据库,我希望能够运行一个 PowerShell 脚本来更新快照、重新初始化订阅,然后启动同步过程。我一直在使用复制监视器执行此操作,但有很多步骤,我希望能够确保每次都以完全相同的方式发生,因此脚本。

关于 SQL 复制和 PowerShell 的主题,我所能找到的只是如何编写新发布和订阅的脚本或监控当前正在运行的复制进程。实际启动同步过程似乎没有任何意义。最终我想封装这个功能,只需要提供一些参数,比如发布者、发布者和订阅者。

有没有人用过他们用 MS SQL Server 启动按需复制的东西?

谢谢

【问题讨论】:

    标签: sql-server powershell replication


    【解决方案1】:

    这是我为同步事务复制拉订阅而编写的旧脚本。这一切都基于使用RMO to Synchronize a Subscription

    RMO 涵盖所有复制类型,因此它应该适用于具有微小更改的快照:

    $asm = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")
    $asm = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Replication")
    $asm = [Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.RMO")
    
    function Do-Replication
    {
    <# 
       .SYNOPSIS Initiate Merge Replication Sync .DESCRIPTION This Function kicks of a Transactional Replication Synchronization 
       .EXAMPLE Give an example of how to use it .PARAMETER subscriber The SQL Instance Name name of the Publication, EG localhost 
       .PARAMETER spublisher The SQL Instance Name name of the Publisher, eg MyPublisher .PARAMETER publication The name of the publication 
       .PARAMETER subscriptionDatabase The name of the Subscriber Database .PARAMETER publicationDatabase The name of the publisher database 
       .PARAMETER forceReInit $true to force a ReInitialization of the subscription, $false otherwise .PARAMETER verboseLevel Logging verbosity level 
       .PARAMETER retries Number of times to retry the sync in case of a failure 
       
    #>
      param(
        [string][Parameter(Mandatory = $true,position = 0)] $subscriber,
        [string][Parameter(Mandatory = $true,position = 1)] $publisher,
        [string][Parameter(Mandatory = $true,position = 2)] $publication,
        [string][Parameter(Mandatory = $true,position = 3)] $subscriptionDatabase,
        [string][Parameter(Mandatory = $true,position = 4)] $publicationDatabase,
        [Boolean][Parameter(Mandatory = $true,position = 5)] $forceReInit,
        [int32][Parameter(Mandatory = $true,position = 6)] $verboseLevel,
        [int32][Parameter(Mandatory = $true,position = 7)] $retries) 
        
        "Subscriber: $subscriber";
        "Publisher: $publisher";
        "Publication: $publication";
        "Publication Database: $publicationDatabase";
        "Subscription Database: $subscriptionDatabase";
        "ForceReInit: $forceReinit";
        "VerboseLevel: $verboseLevel";
        "Retries: $retries";
    
        for ($counter = 1; $counter -le $retries; $counter++) 
        { 
          "Subscriber $subscriber";
          $serverConnection = New-Object Microsoft.SqlServer.Management.Common.ServerConnection $subscriber;
          try 
          { 
            $serverConnection.Connect();
            $transPullSubscription = New-Object Microsoft.SqlServer.Replication.TransPullSubscription;
            $transPullSubscription.ConnectionContext = $serverConnection;
            $transPullSubscription.DatabaseName = $subscriptionDatabase;
            $transPullSubscription.PublisherName = $publisher;
            $transPullSubscription.PublicationDBName = $publicationDatabase;
            $transPullSubscription.PublicationName = $publication;
            if ($true -ne $transPullSubscription.LoadProperties()) 
            { 
              throw New-Object System.ApplicationException "A subscription to [$publication] does not exist on [$subscriber]"  
            } 
            if ($null -eq $transPullSubscription.PublisherSecurity) 
            { 
              throw New-Object System.ApplicationException "There is insufficent metadata to synchronize the subscription. Recreate the subscription with the agent job or supply the required agent properties at run time.";
            } 
    
            $transPullSubscription.SynchronizationAgent.Output = "c:\temp\ReplicationLog.txt";
            $transPullSubscription.SynchronizationAgent.OutputVerboseLevel = $verboseLevel;
    
            if ($forceReInit -eq $true) 
            { 
              $transPullSubscription.Reinitialize();
            } 
    
            $transPullSubscription.SynchronizationAgent.Synchronize();
            "Sync Complete";
            return;
        }
        catch [Exception]
        {
          if ($counter -lt $retries) 
          { 
              $_.Exception.Message + ": " + $_.Exception.InnerException "Retry $counter"; 
              continue; 
          } 
          else 
          { 
              return $_.Exception.Message + ": " + $_.Exception.InnerException 
          } 
        }
      }
    
    }
    
    
    Do-Replication -subscriber "DBROWNE0" "DBROWNE0" "inventory" "subscriberTest" "replTest" $false 1 4;
    

    【讨论】:

    • 谢谢!这有很大帮助。我能够将其更改为使用推送复制而不是拉取。如果将来有人搜索如何执行此操作,您只需将 TransPullSubscription 更改为 TransSubscription 并匹配适当的发布者/订阅者属性。需要设置的另一件事是包括 SynchronizationAgentProcessSecurity.Login & Password 属性。现在我需要做的就是弄清楚如何识别和运行快照代理。
    • 我想出了如何运行快照代理。使用 [MySourceDatabase];去 sp_startpublication_snapshot 'MyPublicationName';我能够将该 SQL 语句合并到 David 提供的 PowerShell 脚本中,并且它按我的预期工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 2021-06-22
    • 2021-01-10
    相关资源
    最近更新 更多