博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PowerShell应用之-可更新订阅的事务复制
阅读量:6260 次
发布时间:2019-06-22

本文共 13476 字,大约阅读时间需要 44 分钟。

开始


在上一篇,描述了如何通过PowerShell脚本配置发布&分发服务器、创建事务发布&发布项目、和创建推送&请求订阅。而且上篇订阅是只读的(ReadOnly),在这篇,将会讲述可更新订阅的事务复制,涉及到两种基本的订阅类型:队列更新(QueuedUpdate) & 即时更新(ImmediateUpdate )。本篇使用的例子会沿用上一篇的部分脚本及测试数据库。在这边我们省略了配置发布&分发服务器部分,直接从创建事务发布和发布项目(TransPublication & TransArticle)开始。

 

创建事务发布和设置发布项目(TransPublication & TransArticle)


在原来的代码中,我们会在开始的输入部分多加两个变量描述可更新订阅的订阅类型,是否队列更新 & 是否即时更新

#
#允许队列更新订阅
#
------------------------------------------------------------
$AllowQueuedTransactions=
$True
#
#允许即时更新订阅
#
------------------------------------------------------------
$AllowSynchronousTransactions=
$True

在TransPublication创建之前,需要补上下面的简短代码,描述添加队列更新 & 即时更新到TransPublication可更新订阅选项中。

        #
允许队列更新订阅
        
if(
$AllowQueuedTransactions 
-eq 
$true)
        {
            
$TransPublication.Attributes =
$TransPublication.Attributes 
-bor [Microsoft.SqlServer.Replication.PublicationAttributes]::AllowQueuedTransactions
        }
        
        
#
允许即时更新订阅
        
if(
$AllowSynchronousTransactions 
-eq 
$true)
        {
            
$TransPublication.Attributes =
$TransPublication.Attributes 
-bor [Microsoft.SqlServer.Replication.PublicationAttributes]::AllowSynchronousTransactions
        }

 

这部分的完整代码,我们可以查看PowerShell脚本:

Replication-5-Create a Publication(AllowQueuedTransactions).ps1

 

ExpandedBlockStart.gif
View Code
<
#
===========================创建事务发布&发布项目===========================#>
#
#配置发布、分发服务器者登录用户名&密码,这里发布与分发使用同一个实例
#
------------------------------------------------------------
$serverInstance=
"
WINSERVER01\SQL2008DE01
"
$userName=
"
sa
"
$password=
"
sql20081
"
#
#设置域账号,应用于同步复制
#
------------------------------------------------------------
$RAccount=
"
TN\SQLAccount
"
$RPassword=
"
Sql123456
"
#
#发布数据库
#
------------------------------------------------------------
$DataBase=
"
ReplicationDB
"
#
#项目名称
#
------------------------------------------------------------
$TransPublicationName=
$DataBase+“_Tran_”
#
#项目对应的是表,使用"Select * Form TableName Where ...;"格式
#
------------------------------------------------------------
$SQL=
"
Select * From DataOwner Where ID=2;
Select * From Data1 Where OwnerID=2;
Select * From Data2 Where ParentID In(Select ID From dbo.Data1 Where OwnerID=2);
Select * From DataRelation Where ParentID In(Select dbo.Data2.ID From dbo.Data1 Inner Join dbo.Data2 On dbo.Data1.ID = dbo.Data2.ParentID And dbo.Data1.OwnerID=2);
"
#
#发行项目选项
#
------------------------------------------------------------
$PreCreationMethod=
"
drop
" 
#
当名称已被使用时的操作.可以选择“none”,“delete”,“drop”,"truncate"
#
#允许队列更新订阅
#
------------------------------------------------------------
$AllowQueuedTransactions=
$True
#
#允许即时更新订阅
#
------------------------------------------------------------
$AllowSynchronousTransactions=
$True
<
#
================================================================#>
[System.Reflection.Assembly]::LoadWithPartialName(
"
Microsoft.SqlServer.Rmo
") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName(
"
Microsoft.SqlServer.ConnectionInfo
") | Out-Null
#
Step 1: 创建连接
$ServerConnection =New-object 
"
Microsoft.SqlServer.Management.Common.ServerConnection
" 
$serverInstance,
$userName
$password  
#
Step 2:
Try
{
    
$ServerConnection.Connect()
    
if (
$ServerConnection.IsOpen)
    {
        
$ReplicationDatabase =New-object 
"
Microsoft.SqlServer.Replication.ReplicationDatabase
" 
$DataBase,
$ServerConnection
        
$ReplicationDatabase.EnabledTransPublishing=
$true
        
        
#
创建队列读取器代理
        
if (
$ReplicationDatabase.LogReaderAgentExists 
-eq 
$false)
        {
            
$ReplicationDatabase.LogReaderAgentProcessSecurity.Login=
$RAccount
            
$ReplicationDatabase.LogReaderAgentProcessSecurity.Password=
$RPassword            
            
$ReplicationDatabase.LogReaderAgentPublisherSecurity.WindowsAuthentication=
$true
            
            
$ReplicationDatabase.LogReaderAgentPublisherSecurity.SqlStandardLogin=
$userName
            
$ReplicationDatabase.LogReaderAgentPublisherSecurity.SqlStandardPassword=
$password
            
$ReplicationDatabase.LogReaderAgentPublisherSecurity.WindowsAuthentication=
$false
            
$ReplicationDatabase.CreateLogReaderAgent()
        }
        
        
#
创建事务发布   
        
$TransPublication=New-object 
"
Microsoft.SqlServer.Replication.TransPublication
" 
$TransPublicationName,
$DataBase,
$ServerConnection
        
        
$TransPublication.SnapshotGenerationAgentProcessSecurity.Login=
$RAccount
        
$TransPublication.SnapshotGenerationAgentProcessSecurity.Password=
$RPassword
        
$TransPublication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication=
$true
        
        
$TransPublication.SnapshotGenerationAgentPublisherSecurity.SqlStandardLogin=
$userName
        
$TransPublication.SnapshotGenerationAgentPublisherSecurity.SqlStandardPassword=
$password
        
$TransPublication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication=
$false
        
        
#
允许队列更新订阅
        
if(
$AllowQueuedTransactions 
-eq 
$true)
        {
            
$TransPublication.Attributes =
$TransPublication.Attributes 
-bor [Microsoft.SqlServer.Replication.PublicationAttributes]::AllowQueuedTransactions
        }
        
        
#
允许即时更新订阅
        
if(
$AllowSynchronousTransactions 
-eq 
$true)
        {
            
$TransPublication.Attributes =
$TransPublication.Attributes 
-bor [Microsoft.SqlServer.Replication.PublicationAttributes]::AllowSynchronousTransactions
        }
        
        
if (
$TransPublication.IsExistingObject 
-eq 
$false)
        {
            
$TransPublication.Create()
        }        
        
        
        
#
定义发布项目               
                
        
While(
$SQL.IndexOf(“`r”) 
-gt 0)   
#
处理Select列表
            {
$SQL=
$SQL.Replace(
"
`r
",
"")}
        
While(
$SQL.IndexOf(“`n”) 
-gt 0)
            {
$SQL=
$SQL.Replace(
"
`n
",
"")}
            
        
While(
$SQL.IndexOf(“`t”) 
-gt 0)
            {
$SQL=
$SQL.Replace(
"
`t 
",
"
 
")}
                
        
While(
$SQL.IndexOf(
"
  
"
-gt 0)
            {
$SQL=
$SQL.Replace(
"
  
",
"
 
")}
        
$SQL=
$SQL.ToLower()
                    
        
Foreach (
$SqlLine 
In 
$SQL.split(
"
;
"))
        {
            
if (
$SqlLine.IndexOf(
"
from
"
-gt 0)
            {          
                
$Where=
""     
                
$TB=
$SqlLine.split(
"
 
")[3]
                
If (
$SqlLine.LastIndexOf(
"
where
"
-gt 0)
                {
                    
$Where=
$SqlLine.substring([int32](
$SqlLine.IndexOf(
"
where
")+6))
                }
                
$Article=New-object 
"
Microsoft.SqlServer.Replication.TransArticle
" 
$TB,
$TransPublicationName,
$DataBase,
$ServerConnection
                
$Article.SourceObjectName=
$TB
                
$article.FilterClause=
$Where
                
$article.PreCreationMethod=
$PreCreationMethod
                
if (
$Article.IsExistingObject 
-eq 
$false)
                {
                    
$Article.Create()
                }                
            }
        }  
        
        Write-Host 
"
事务发布 '$TransPublicationName' 已创建!
"                              
    }
}
Catch
{
    Write-Error 
$_
}

 

执行上面的完整代码,我们就可以看到在事务发布ReplicationDB_Tran_的属性,查看可更新订阅选项内容:

 

 

 

如何创建推送订阅(Push Subscription)


创建可更新订阅的时候,与上篇创建订阅的有些不同,在这过程,我们代码开头位置多一个变量来描述可更新订阅类型。

#
#可更新订阅类型
#
------------------------------------------------------------
$SubscriberType=“ImmediateUpdate”

 

 

在创建订阅之前会,根据开头设置的变量$SubscriberType,来描述订阅类型,

#
更新类型                
$TransSubscription.SubscriberType=[Microsoft.SqlServer.Replication.TransSubscriberType]::
$SubscriberType

 

 

当要使用即时更新的时候,我们还需要设置在连接到发布服务器时立即更新订阅的同步触发器所使用的配置和安全信息。这里将应用到类"Microsoft.SqlServer.Replication.ReplicationDatabase"中的方法LinkPublicationForUpdateableSubscription。此方法类似T-SQL中的sp_link_publication系统存储过程。

                #
在订阅端,设置连接发行服务器验证
                
#
在订阅端,确保登录账户“repllinkproxy”對订阅数据库具有db_onwer權限
               
                
$ReplicationDatabase =New-object 
"
Microsoft.SqlServer.Replication.ReplicationDatabase
" 
$DataBase,
$SubServerConnection
                
If(
$ReplicationDatabase.LoadProperties())
                {
                    
$Publisher=
$serverInstance
                    
$PublisherDB =
$TransSubscription.SubscriptionDBName
                    
$Publication=
$TransPublication.Name
                    
$Distributo=
$null
                    
$PublisherConnectionSecurityContext=New-object 
"
Microsoft.SqlServer.Replication.PublisherConnectionSecurityContext
"
                    
                     <
#
--SqlStandard模式--#>  
                     
#
<#                
                    
$PublisherConnectionSecurityContext.SecurityMode=[Microsoft.SqlServer.Replication.ReplicationSecurityMode]::SqlStandard
                    
$PublisherConnectionSecurityContext.SqlStandardLogin=
$userName
                    
$PublisherConnectionSecurityContext.SqlStandardPassword=
$password
                    
#
#>    
                                     
                    <
#
--PredefinedServer模式--#> #需要创建一个固定的链接服务器,名字与$serverInstance相同
                    
#
$PublisherConnectionSecurityContext.SecurityMode=[Microsoft.SqlServer.Replication.ReplicationSecurityMode]::PredefinedServer                                       
                    
                    
                    
$ReplicationDatabase.LinkPublicationForUpdateableSubscription(
$Publisher,
$PublisherDB,
$Publication,
$Distributo,
$PublisherConnectionSecurityContext )
                }

 

,在上面的即时更新脚本中,我们要确保发布服务器与订阅服务器的MSTDC要启动,要是存在防火墙需要开启135端口。

我们要注意”<#--SqlStandard模式—#>” 和“ <#--PredefinedServer模式--#>”两部分。使用”<#--SqlStandard模式—#>” 会指定动态远程过程调用 (RPC)。“ <#--PredefinedServer模式--#>”需要固定的链接服务器。是于这两者具体的差异,可能要另写一篇来详细描述,比较有意思的。

 

订阅的完整PowerShell脚本,我们可以参考:

Replication-5-Create a Publication(AllowQueuedTransactions).ps1

ExpandedBlockStart.gif
View Code
<
#
===========================创建推送订阅===========================#>
#
#分发代理程序执行账户
#
------------------------------------------------------------
$serverInstance=
"
WINSERVER01\SQL2008DE01
"
$userName=
"
sa
"
$password=
"
sql20081
"
#
#设置域账号,应用于同步复制
#
------------------------------------------------------------
$RAccount=
"
TN\SQLAccount
"
$RPassword=
"
Sql123456
"
#
#连接到订阅服务器账户
#
------------------------------------------------------------
$SubserverInstance=
"
TON-WINXP001\SQL2008DE
"
$SubuserName=
"
sa
"
$Subpassword=
"
WinXP00120081
"
#
#发布对象
#
------------------------------------------------------------
$DataBase=
"
ReplicationDB
"
$TransPublicationName=“ReplicationDB_Tran_”
#
#是否要初始化
#
------------------------------------------------------------
$invalidate=
$true
#
#可更新订阅类型
#
------------------------------------------------------------
$SubscriberType=“ImmediateUpdate”
<
#
ReadOnly        : 该订阅是只读的。在订阅服务器上所做的更改不会发送到发布服务器。
QueuedUpdate    : 启用排队更新的订阅。可以在订阅服务器上进行数据修改,将其存储在队列中,然后传播到发布服务器。Oracle 发布服务器不支持
ImmediateUpdate : 启用对即时更新订阅的支持。Oracle 发布服务器不支持。
QueuedFailover  : 将订阅启用为排队更新订阅,并允许更改为立即更新模式。
                  在订阅服务器和发布服务器之间建立连接之前,可以在订阅服务器上修改数据,并将数据修改存储在队列中。
                  建立起持续连接后,即可将更新模式更改为立即更新。Oracle 发布服务器不支持。
Failover        : 将排队更新作为故障转移的情况下启用用于即时更新的订阅。可以在订阅服务器上进行数据修改并立即传播到发布服务器。
                  如果发布服务器与订阅服务器未连接在一起,则可以更改更新模式以便将在订阅服务器上所做的数据修改存储在队列中,
                  直到订阅服务器与发布服务器重新连接在一起。Oracle 发布服务器不支持。
                  
#
>
<
#
================================================================#>
[System.Reflection.Assembly]::LoadWithPartialName(
"
Microsoft.SqlServer.Rmo
") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName(
"
Microsoft.SqlServer.ConnectionInfo
") | Out-Null
#
Step 1: 创建连接
$ServerConnection =New-object 
"
Microsoft.SqlServer.Management.Common.ServerConnection
" 
$serverInstance,
$userName
$password  
$SubServerConnection =New-object 
"
Microsoft.SqlServer.Management.Common.ServerConnection
" 
$SubserverInstance,
$SubuserName
$Subpassword  
#
Step 2:
Try
{
    
$ServerConnection.Connect()
    
$SubServerConnection.Connect()
    
    
if (
$ServerConnection.IsOpen 
-and 
$SubServerConnection.IsOpen)
    {
        
$TransPublication=New-object 
"
Microsoft.SqlServer.Replication.TransPublication
" 
$TransPublicationName,
$DataBase,
$ServerConnection
        
if (
$TransPublication.LoadProperties() 
-eq 
$true)
        {
            
#
#设置推送订阅
            
if(
$TransPublication.Attributes 
-notmatch  
"
AllowPush
")
            {
                
#
#使用到位運算OR(inclusive) "-bor" ,如果要刪除某一特征就使用"-bxor"
                
$TransPublication.Attributes =
$TransPublication.Attributes 
-bor [Microsoft.SqlServer.Replication.PublicationAttributes]::AllowPush
            }
            
            
$subscriptionDBName=
$TransPublication.DatabaseName
            
$publicationDBName=
$TransPublication.DatabaseName
            
$publicationName=
$TransPublication.Name
            
            
$TransSubscription=New-object 
"
Microsoft.SqlServer.Replication.TransSubscription
" 
$publicationName,
$publicationDBName,
$SubserverInstance,
$subscriptionDBName,
$ServerConnection                  
            
            
if(
$TransSubscription.LoadProperties() 
-eq 
$false)
            {
                
#
#设置分发代理程序账号(Windows账号)
                
$TransSubscription.SynchronizationAgentProcessSecurity.Login=
$RAccount
                
$TransSubscription.SynchronizationAgentProcessSecurity.Password=
$RPassword
                
                
#
#设置订阅服务器登录账号(SQL Server账号)
                
$TransSubscription.SubscriberSecurity.WindowsAuthentication=
$false
                
$TransSubscription.SubscriberSecurity.SqlStandardLogin=
$SubuserName
                
$TransSubscription.SubscriberSecurity.SqlStandardPassword=
$Subpassword           
                
                
$TransSubscription.CreateSyncAgentByDefault=
$true
                
                
#
每天执行
                
$TransSubscription.AgentSchedule.FrequencyType=[Microsoft.SqlServer.Replication.ScheduleFrequencyType]::Daily
                
                
#
分钟
                
$TransSubscription.AgentSchedule.FrequencySubDay=[Microsoft.SqlServer.Replication.ScheduleFrequencySubDay]::Minute
                
                
#
多少分钟执行一次
                
$TransSubscription.AgentSchedule.FrequencySubDayInterval=1
                
                
#
#是否初始化
                
if(
$invalidate 
-eq 
$false)
                {
                    
$TransSubscription.SyncType=[Microsoft.SqlServer.Replication.SubscriptionSyncType]::ReplicationSupportOnly
                }
                
                
#
更新类型                
                
$TransSubscription.SubscriberType=[Microsoft.SqlServer.Replication.TransSubscriberType]::
$SubscriberType
                
                
#
在订阅端,设置连接发行服务器验证
                
#
在订阅端,确保登录账户“repllinkproxy”對订阅数据库具有db_onwer權限
               
                
$ReplicationDatabase =New-object 
"
Microsoft.SqlServer.Replication.ReplicationDatabase
" 
$DataBase,
$SubServerConnection
                
If(
$ReplicationDatabase.LoadProperties())
                {
                    
$Publisher=
$serverInstance
                    
$PublisherDB =
$TransSubscription.SubscriptionDBName
                    
$Publication=
$TransPublication.Name
                    
$Distributo=
$null
                    
$PublisherConnectionSecurityContext=New-object 
"
Microsoft.SqlServer.Replication.PublisherConnectionSecurityContext
"
                    
                     <
#
--SqlStandard模式--#>  
                     
#
<#                
                    
$PublisherConnectionSecurityContext.SecurityMode=[Microsoft.SqlServer.Replication.ReplicationSecurityMode]::SqlStandard
                    
$PublisherConnectionSecurityContext.SqlStandardLogin=
$userName
                    
$PublisherConnectionSecurityContext.SqlStandardPassword=
$password
                    
#
#>    
                                     
                    <
#
--PredefinedServer模式--#> #需要创建一个固定的链接服务器,名字与$serverInstance相同
                    
#
$PublisherConnectionSecurityContext.SecurityMode=[Microsoft.SqlServer.Replication.ReplicationSecurityMode]::PredefinedServer                                       
                    
                    
                    
$ReplicationDatabase.LinkPublicationForUpdateableSubscription(
$Publisher,
$PublisherDB,
$Publication,
$Distributo,
$PublisherConnectionSecurityContext )
                }
                
                
$TransSubscription.Create()                                            
                 
                               
                 
#
启动快照代理作业
                
if (
$TransPublication.SnapshotAvailable 
-eq 
$false )
                {
                    
$TransPublication.StartSnapshotGenerationAgentJob()
                }
                
                
                Write-Host 
"
订阅 
"
$TransSubscription.Name
"
 创建完成!
"
            }
            
Else
            {
                Write-Host 
"
订阅 
"
$TransSubscription.Name
"
 已创建!
"
            }
            
        }
        
Else
        {
            Write-Host 
"
发布对象 $TransPublicationName  不存在!
"
        }
    }
}
Catch
{
    Write-Error 
$_
}

 

小结


本篇描述了PowerShell应用之-可更新订阅的事务复制,在我们测试过程中可能会发现一些问题,特别是即时更新类型的订阅,注意上面提到的注意内容。因时间问题,订阅部分只测试了Push订阅.如果你在测试过程还有其他不明白的地方,可以在文章的后面留言或直接发Email到我的邮箱。

转载地址:http://phqsa.baihongyu.com/

你可能感兴趣的文章
005-ant design -结合echart
查看>>
TCP交互数据流 成块数据流
查看>>
位置+推荐
查看>>
PEP python enhanced prposals
查看>>
retools 0.1 : Python Package Index
查看>>
python模块——logging 这篇讲得比较能懂
查看>>
【017】◀▶ C#学习(九) - ADO.NET
查看>>
English
查看>>
解剖SQLSERVER 第二篇 对数据页面头进行逆向(译)
查看>>
ZeroMQ接口函数之 :zmq_bind - 绑定一个socket
查看>>
数据库产生的背景
查看>>
python XML
查看>>
html3秒跳转
查看>>
机器学习与R语言
查看>>
反距离权重插值inverse distance weighting,IDW
查看>>
2017第18周六
查看>>
Postman 网络调试工具
查看>>
hive建表范例
查看>>
【转】svn 的开发目录结构和流程
查看>>
水晶报表使用IEnumerable<T>数据源
查看>>