如何创建具有参数化筛选器的合并发布的快照(RMO 编程)
为使用参数化筛选器的合并发布生成快照时,必须先生成一个包含订阅的所有订阅服务器元数据的标准(架构)快照。 然后,才可以生成包含特定于订阅服务器的已发布数据分区的快照部分。 有关详细信息,请参阅如何创建初始快照(RMO 编程)。
可以使用复制管理对象 (RMO) 通过以下方法以编程的方式生成分区快照:
允许订阅服务器在第一次同步时请求快照生成和应用。
为每个分区预生成快照。
通过运行快照代理为每台订阅服务器手动生成一个快照。
注意 |
---|
如果对项目进行筛选后,生成对于每个订阅都唯一的非重叠分区(通过在创建合并项目时将 PartitionOption 的值指定为 NonOverlappingSingleSubscription),则只要合并代理运行,就会清除元数据。 这意味着分区快照会过期得更快。 使用此选项时,应考虑允许订阅服务器请求快照生成。 有关详细信息,请参阅主题参数化行筛选器中的“使用适当的筛选选项”部分。 |
安全说明 |
---|
如果可能,请在运行时提示用户输入安全凭据。 如果必须存储凭据,请使用 Microsoft Windows .NET Framework 提供的 Cryptographic Services(加密服务)。 |
创建允许订阅服务器启动快照生成和传递的发布
使用 ServerConnection 类创建与发布服务器的连接。
为发布数据库创建 ReplicationDatabase 类的实例,将 ConnectionContext 属性设置为步骤 1 中的 ServerConnection 实例,然后调用 LoadProperties 方法。 如果 LoadProperties 返回 false,请确认该数据库是否存在。
如果 EnabledMergePublishing 属性为 false,则将其设置为 true,然后调用 CommitPropertyChanges。
创建 MergePublication 类的实例,然后为此对象设置下列属性:
将 ConnectionContext 设置为步骤 1 中的 ServerConnection。
用于 DatabaseName 的已发布的数据库的名称。
将 Name 属性设置为发布的名称。
将 MaxConcurrentDynamicSnapshots 设置为要运行的动态快照作业的最大数目。 因为订阅服务器启动的快照请求随时都可以发生,所以在多个订阅服务器同时请求其分区快照时,此属性会限制可以同时运行的快照代理作业的数目。 运行的作业达到最大数目时,其他分区快照请求会进行排队,直到其前面的一个作业运行完才开始运行。
使用逻辑“位或”(在 Visual C# 中为 |,在 Visual Basic 中为 Or)运算符将值 AllowSubscriberInitiatedSnapshot 添加到 Attributes。
SnapshotGenerationAgentProcessSecurity 的 Login 字段和 Password 字段,用于提供快照代理作业运行时所用的 Microsoft Windows 帐户的凭据。
注意 如果发布是由 sysadmin 固定服务器角色的成员创建的,则建议设置 SnapshotGenerationAgentProcessSecurity。 有关详细信息,请参阅复制代理安全性模式。
调用 Create 方法创建发布。
安全说明 使用远程分发服务器配置发布服务器时,为所有属性(包括 SnapshotGenerationAgentProcessSecurity)提供的值都将以纯文本格式发送到分发服务器。 在调用 Create 方法之前,应该对发布服务器与其远程分发服务器之间的连接进行加密。 有关详细信息,请参阅加密与 SQL Server 的连接。
使用 MergeArticle 属性将项目添加到发布。 至少为一个项目指定 FilterClause 属性以定义参数化筛选器。 (可选)创建 MergeJoinFilter 对象以定义项目之间的联接筛选器。 有关详细信息,请参阅如何定义项目(RMO 编程)。
如果 SnapshotAgentExists 的值为 false,请调用 CreateSnapshotAgent 为此发布创建初始快照代理作业。
调用步骤 4 中创建的 MergePublication 对象的 StartSnapshotGenerationAgentJob 方法。这将启动生成初始快照的代理作业。 有关生成初始快照和为快照代理定义自定义计划的详细信息,请参阅如何创建初始快照(RMO 编程)。
(可选)检查 SnapshotAvailable 属性的值是否为 true,以确定初始快照何时可以使用。
如果订阅服务器的合并代理是第一次连接,则会自动生成一个分区快照。
创建发布并预生成快照或自动刷新快照
使用 MergePublication 类的实例定义一个合并发布。 有关详细信息,请参阅如何创建发布(RMO 编程)。
使用 MergeArticle 属性将项目添加到发布。 至少为一个项目指定 FilterClause 属性以定义参数化筛选器,然后创建任何 MergeJoinFilter 对象以定义项目之间的联接筛选器。 有关详细信息,请参阅如何定义项目(RMO 编程)。
如果 SnapshotAgentExists 的值为 false,请调用 CreateSnapshotAgent 为此发布创建快照代理作业。
调用步骤 1 中创建的 MergePublication 对象的 StartSnapshotGenerationAgentJob 方法。此方法将启动生成初始快照的代理作业。 有关生成初始快照和为快照代理定义自定义计划的详细信息,请参阅如何创建初始快照(RMO 编程)。
检查 SnapshotAvailable 的值是否为 true,以确定初始快照何时可以使用。
创建 MergePartition 类的实例,然后使用下列属性的一个或两个设置订阅服务器的参数化筛选条件:
如果订阅服务器的分区是通过 SUSER_SNAME (Transact-SQL) 的结果定义的,请使用 DynamicFilterLogin。
如果订阅服务器的分区是通过 HOST_NAME (Transact-SQL) 的结果或此功能的重载定义的,请使用 DynamicFilterHostName。
创建 MergeDynamicSnapshotJob 类的实例,然后设置与步骤 6 相同的属性。
使用 ReplicationAgentSchedule 类定义用于生成订阅服务器分区的筛选快照的计划。
使用步骤 1 中的 MergePublication 实例,调用 AddMergePartition。 传递步骤 6 中的 MergePartition 对象。
使用步骤 1 中的 MergePublication 实例,调用 AddMergeDynamicSnapshotJob 方法。 传递步骤 7 中的 MergeDynamicSnapshotJob 对象和步骤 8 中的 ReplicationAgentSchedule 对象。
调用 EnumMergeDynamicSnapshotJobs,然后在返回的数组中为新添加的分区快照作业找到 MergeDynamicSnapshotJob 对象。
为此作业获取 Name 属性。
使用 ServerConnection 类创建与分发服务器的连接。
创建 SQL Server 管理对象 (SMO) Server 类的实例,并传递步骤 13 中的 ServerConnection 对象。
创建 Job 类的实例,并传递步骤 14 中的 Server 对象的 JobServer 属性和步骤 12 中的作业名称。
调用 Start 方法以启动分区快照作业。
为每个订阅服务器重复步骤 6-16。
创建发布并为每个分区手动创建快照
使用 MergePublication 类的实例定义一个合并发布。 有关详细信息,请参阅如何创建发布(RMO 编程)。
使用 MergeArticle 属性将项目添加到发布。为至少一个项目指定 FilterClause 属性以定义参数化筛选器,然后创建任何 MergeJoinFilter 对象以定义项目之间的联接筛选器。 有关详细信息,请参阅如何定义项目(RMO 编程)。
生成初始快照。 有关详细信息,请参阅如何创建初始快照(RMO 编程)。
创建 SnapshotGenerationAgent 类的实例,并设置下列所需属性:
Publisher - 发布服务器的名称
PublisherDatabase - 发布数据库的名称
Publication - 发布的名称
Distributor - 分发服务器的名称
PublisherSecurityMode - 若使用 Windows 集成身份验证,则值为 Integrated;若使用 SQL Server 身份验证,则值为 Standard。
DistributorSecurityMode - 若使用 Windows 集成身份验证,则值为 Integrated;若使用 SQL Server 身份验证,则值为 Standard。
将 ReplicationType 的值设置为 Merge。
设置一个或多个下列属性以定义分区参数:
如果订阅服务器的分区是通过 SUSER_SNAME (Transact-SQL) 的结果定义的,请使用 DynamicFilterLogin。
如果订阅服务器的分区是通过 HOST_NAME (Transact-SQL) 的结果或此功能的重载定义的,请使用 DynamicFilterHostName。
调用 GenerateSnapshot 方法。
为每个订阅服务器重复步骤 4-7。
示例
此示例创建一个允许订阅服务器请求快照生成的合并发布。
// Set the Publisher, publication database, and publication names.
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks";
ReplicationDatabase publicationDb;
MergePublication publication;
// Create a connection to the Publisher.
ServerConnection conn = new ServerConnection(publisherName);
try
{
// Connect to the Publisher.
conn.Connect();
// Enable the database for merge publication.
publicationDb = new ReplicationDatabase(publicationDbName, conn);
if (publicationDb.LoadProperties())
{
if (!publicationDb.EnabledMergePublishing)
{
publicationDb.EnabledMergePublishing = true;
}
}
else
{
// Do something here if the database does not exist.
throw new ApplicationException(String.Format(
"The {0} database does not exist on {1}.",
publicationDb, publisherName));
}
// Set the required properties for the merge publication.
publication = new MergePublication();
publication.ConnectionContext = conn;
publication.Name = publicationName;
publication.DatabaseName = publicationDbName;
// Enable precomputed partitions.
publication.PartitionGroupsOption = PartitionGroupsOption.True;
// Specify the Windows account under which the Snapshot Agent job runs.
// This account will be used for the local connection to the
// Distributor and all agent connections that use Windows Authentication.
publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin;
publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword;
// Explicitly set the security mode for the Publisher connection
// Windows Authentication (the default).
publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;
// Enable Subscribers to request snapshot generation and filtering.
publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
publication.Attributes |= PublicationAttributes.DynamicFilters;
// Enable pull and push subscriptions.
publication.Attributes |= PublicationAttributes.AllowPull;
publication.Attributes |= PublicationAttributes.AllowPush;
if (!publication.IsExistingObject)
{
// Create the merge publication.
publication.Create();
// Create a Snapshot Agent job for the publication.
publication.CreateSnapshotAgent();
}
else
{
throw new ApplicationException(String.Format(
"The {0} publication already exists.", publicationName));
}
}
catch (Exception ex)
{
// Implement custom application error handling here.
throw new ApplicationException(String.Format(
"The publication {0} could not be created.", publicationName), ex);
}
finally
{
conn.Disconnect();
}
' Set the Publisher, publication database, and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks"
Dim publicationDb As ReplicationDatabase
Dim publication As MergePublication
' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)
Try
' Connect to the Publisher.
conn.Connect()
' Enable the database for merge publication.
publicationDb = New ReplicationDatabase(publicationDbName, conn)
If publicationDb.LoadProperties() Then
If Not publicationDb.EnabledMergePublishing Then
publicationDb.EnabledMergePublishing = True
End If
Else
' Do something here if the database does not exist.
Throw New ApplicationException(String.Format( _
"The {0} database does not exist on {1}.", _
publicationDb, publisherName))
End If
' Set the required properties for the merge publication.
publication = New MergePublication()
publication.ConnectionContext = conn
publication.Name = publicationName
publication.DatabaseName = publicationDbName
' Enable precomputed partitions.
publication.PartitionGroupsOption = PartitionGroupsOption.True
' Specify the Windows account under which the Snapshot Agent job runs.
' This account will be used for the local connection to the
' Distributor and all agent connections that use Windows Authentication.
publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin
publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword
' Explicitly set the security mode for the Publisher connection
' Windows Authentication (the default).
publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = True
' Enable Subscribers to request snapshot generation and filtering.
publication.Attributes = publication.Attributes Or _
PublicationAttributes.AllowSubscriberInitiatedSnapshot
publication.Attributes = publication.Attributes Or _
PublicationAttributes.DynamicFilters
' Enable pull and push subscriptions
publication.Attributes = publication.Attributes Or _
PublicationAttributes.AllowPull
publication.Attributes = publication.Attributes Or _
PublicationAttributes.AllowPush
If Not publication.IsExistingObject Then
' Create the merge publication.
publication.Create()
' Create a Snapshot Agent job for the publication.
publication.CreateSnapshotAgent()
Else
Throw New ApplicationException(String.Format( _
"The {0} publication already exists.", publicationName))
End If
Catch ex As Exception
' Implement custom application error handling here.
Throw New ApplicationException(String.Format( _
"The publication {0} could not be created.", publicationName), ex)
Finally
conn.Disconnect()
End Try
此示例为带有参数化行筛选器的合并发布手动创建订阅服务器分区和筛选快照。
// Define the server, database, and publication names
string publisherName = publisherInstance;
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks";
string distributorName = publisherInstance;
MergePublication publication;
MergePartition partition;
MergeDynamicSnapshotJob snapshotAgentJob;
ReplicationAgentSchedule schedule;
// Create a connection to the Publisher.
ServerConnection publisherConn = new ServerConnection(publisherName);
// Create a connection to the Distributor to start the Snapshot Agent.
ServerConnection distributorConn = new ServerConnection(distributorName);
try
{
// Connect to the Publisher.
publisherConn.Connect();
// Set the required properties for the publication.
publication = new MergePublication();
publication.ConnectionContext = publisherConn;
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() || publication.SnapshotAvailable)
{
// Set a weekly schedule for the filtered data snapshot.
schedule = new ReplicationAgentSchedule();
schedule.FrequencyType = ScheduleFrequencyType.Weekly;
schedule.FrequencyRecurrenceFactor = 1;
schedule.FrequencyInterval = Convert.ToInt32(0x001);
// Set the value of Hostname that defines the data partition.
partition = new MergePartition();
partition.DynamicFilterHostName = hostname;
snapshotAgentJob = new MergeDynamicSnapshotJob();
snapshotAgentJob.DynamicFilterHostName = hostname;
// Create the partition for the publication with the defined schedule.
publication.AddMergePartition(partition);
publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule);
}
else
{
throw new ApplicationException(String.Format(
"Settings could not be retrieved for the publication, " +
" or the initial snapshot has not been generated. " +
"Ensure that the publication {0} exists on {1} and " +
"that the Snapshot Agent has run successfully.",
publicationName, publisherName));
}
}
catch (Exception ex)
{
// Do error handling here.
throw new ApplicationException(string.Format(
"The partition for '{0}' in the {1} publication could not be created.",
hostname, publicationName), ex);
}
finally
{
publisherConn.Disconnect();
if (distributorConn.IsOpen) distributorConn.Disconnect();
}
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks"
Dim distributorName As String = publisherInstance
Dim publication As MergePublication
Dim partition As MergePartition
Dim snapshotAgentJob As MergeDynamicSnapshotJob
Dim schedule As ReplicationAgentSchedule
' Create a connection to the Publisher.
Dim publisherConn As ServerConnection = New ServerConnection(publisherName)
' Create a connection to the Distributor to start the Snapshot Agent.
Dim distributorConn As ServerConnection = New ServerConnection(distributorName)
Try
' Connect to the Publisher.
publisherConn.Connect()
' Set the required properties for the publication.
publication = New MergePublication()
publication.ConnectionContext = publisherConn
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() Or publication.SnapshotAvailable) Then
' Set a weekly schedule for the filtered data snapshot.
schedule = New ReplicationAgentSchedule()
schedule.FrequencyType = ScheduleFrequencyType.Weekly
schedule.FrequencyRecurrenceFactor = 1
schedule.FrequencyInterval = Convert.ToInt32("0x001", 16)
' Set the value of Hostname that defines the data partition.
partition = New MergePartition()
partition.DynamicFilterHostName = hostname
snapshotAgentJob = New MergeDynamicSnapshotJob()
snapshotAgentJob.DynamicFilterHostName = hostname
' Create the partition for the publication with the defined schedule.
publication.AddMergePartition(partition)
publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule)
Else
Throw New ApplicationException(String.Format( _
"Settings could not be retrieved for the publication, " + _
" or the initial snapshot has not been generated. " + _
"Ensure that the publication {0} exists on {1} and " + _
"that the Snapshot Agent has run successfully.", _
publicationName, publisherName))
End If
Catch ex As Exception
' Do error handling here.
Throw New ApplicationException(String.Format( _
"The partition for '{0}' in the {1} publication could not be created.", _
hostname, publicationName), ex)
Finally
publisherConn.Disconnect()
If distributorConn.IsOpen Then
distributorConn.Disconnect()
End If
End Try
此示例手动启动快照代理,为带有参数化行筛选器的合并发布的订阅服务器生成筛选数据快照。
// Set the Publisher, publication database, and publication names.
string publicationName = "AdvWorksSalesOrdersMerge";
string publicationDbName = "AdventureWorks";
string publisherName = publisherInstance;
string distributorName = publisherInstance;
SnapshotGenerationAgent agent;
try
{
// Set the required properties for Snapshot Agent.
agent = new SnapshotGenerationAgent();
agent.Distributor = distributorName;
agent.DistributorSecurityMode = SecurityMode.Integrated;
agent.Publisher = publisherName;
agent.PublisherSecurityMode = SecurityMode.Integrated;
agent.Publication = publicationName;
agent.PublisherDatabase = publicationDbName;
agent.ReplicationType = ReplicationType.Merge;
// Specify the partition information to generate a
// filtered snapshot based on Hostname.
agent.DynamicFilterHostName = hostname;
// Start the agent synchronously.
agent.GenerateSnapshot();
}
catch (Exception ex)
{
// Implement custom application error handling here.
throw new ApplicationException(String.Format(
"A snapshot could not be generated for the {0} publication."
, publicationName), ex);
}
' Set the Publisher, publication database, and publication names.
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks"
Dim publisherName As String = publisherInstance
Dim distributorName As String = publisherInstance
Dim agent As SnapshotGenerationAgent
Try
' Set the required properties for Snapshot Agent.
agent = New SnapshotGenerationAgent()
agent.Distributor = distributorName
agent.DistributorSecurityMode = SecurityMode.Integrated
agent.Publisher = publisherName
agent.PublisherSecurityMode = SecurityMode.Integrated
agent.Publication = publicationName
agent.PublisherDatabase = publicationDbName
agent.ReplicationType = ReplicationType.Merge
' Specify the partition information to generate a
' filtered snapshot based on Hostname.
agent.DynamicFilterHostName = hostname
' Start the agent synchronously.
agent.GenerateSnapshot()
Catch ex As Exception
' Implement custom application error handling here.
Throw New ApplicationException(String.Format( _
"A snapshot could not be generated for the {0} publication." _
, publicationName), ex)
End Try