使用后继数据库

使用后继数据库功能可将另一群集中的数据库附加到 Azure 数据资源管理器群集。 后继数据库以只读模式附加,因此可以查看其数据,并针对已引入先导数据库的数据运行查询。 后继数据库会同步先导数据库中的更改。 由于同步的缘故,数据可用性方面会存在几秒钟到几分钟的数据延迟。 具体的延迟时长取决于先导数据库元数据的总体大小。 先导数据库和后继数据库使用相同的存储帐户来提取数据。 存储由先导数据库拥有。 后继数据库无需引入数据即可查看数据。 由于附加的数据库是只读的数据库,因此无法修改数据库中除缓存策略主体权限以外的其他数据、表和策略。 无法删除附加的数据库。 这些数据库必须先由先导数据库或后继数据库分离,然后才能将其删除。

使用后继功能将数据库附加到不同群集是在组织与团队之间共享数据的基础结构。 此功能可用于隔离计算资源,以防止将生产环境用于非生产用例。 后继功能还可用于将 Azure 数据资源管理器群集的成本关联到对数据运行查询的一方。

有关基于以前的 SDK 版本的代码示例,请参阅存档的文章

哪些数据库是后继数据库?

  • 一个群集可以后继先导群集中的一个数据库、多个数据库或所有数据库。
  • 单个群集可以后继多个先导群集中的数据库。
  • 一个群集可以同时包含后继数据库和先导数据库。

先决条件

  • Azure 订阅。 创建 Azure 帐户
  • 先导者和后继者的 Azure 数据资源管理器群集和数据库。 创建群集和数据库
  • 先导数据库应包含数据。 可以使用引入概述中所述的方法之一引入数据。

附加数据库

可以使用多种方法来附加数据库。 本文介绍如何使用 C#、Python、PowerShell 或 Azure 资源管理器模板来附加数据库。 若要附加数据库,必须在先导群集和后继群集上拥有至少具有参与者角色的用户、组、服务主体或托管标识。 使用 Azure 门户PowerShellAzure CLIARM 模板来添加或删除角色分配。 深入了解 Azure 基于角色的访问控制 (Azure RBAC)不同角色

表级别共享

附加数据库时,还会附加所有表、外部表和具体化视图。 可以通过配置“TableLevelSharingProperties”来共享特定表/外部表/具体化视图。

“TableLevelSharingProperties”包含八个字符串数组:tablesToIncludetablesToExcludeexternalTablesToIncludeexternalTablesToExcludematerializedViewsToIncludematerializedViewsToExcludefunctionsToIncludefunctionsToExclude。 所有数组中的最大条目数之和为 100。

注意

  • 使用“*”所有数据库表示法时,不支持表级共享。
  • 如果包含具体化视图,则也会包含它们的源表。

示例

  1. 包括所有表。 无需“*”,因为默认情况下所有表都遵循:

    tablesToInclude = []
    
  2. 包含名称以“Logs”开头的所有表:

    tablesToInclude = ["Logs*"]
    
  3. 排除所有外部表:

    externalTablesToExclude = ["*"]
    
  4. 排除所有具体化视图:

    materializedViewsToExclude=["*"]
    

数据库名称替代

可以选择性地使后继群集中的数据库名称不同于先导群集中的数据库名称。 例如,你可能希望将同一数据库名称从多个先导群集附加到后继群集。 若要指定其他数据库名称,请配置“DatabaseNameOverride”或“DatabaseNamePrefix”属性。

使用 C# 附加数据库

所需的 NuGet 包

C# 示例

var tenantId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Directory (tenant) ID
var clientId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Application ID
var clientSecret = "PlaceholderClientSecret"; //Client Secret
var followerSubscriptionId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx";
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var resourceManagementClient = new ArmClient(credentials, followerSubscriptionId);
var followerResourceGroupName = "followerResourceGroup";
var followerClusterName = "follower";
var subscription = await resourceManagementClient.GetDefaultSubscriptionAsync();
var resourceGroup = (await subscription.GetResourceGroupAsync(followerResourceGroupName)).Value;
var cluster = (await resourceGroup.GetKustoClusterAsync(followerClusterName)).Value;
var attachedDatabaseConfigurations = cluster.GetKustoAttachedDatabaseConfigurations();
var attachedDatabaseConfigurationName = "attachedDatabaseConfiguration"
var leaderSubscriptionId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx";
var leaderResourceGroup = "leaderResourceGroup";
var leaderClusterName = "leader";
var attachedDatabaseConfigurationData = new KustoAttachedDatabaseConfigurationData
{
    ClusterResourceId = new ResourceIdentifier($"/subscriptions/{leaderSubscriptionId}/resourceGroups/{leaderResourceGroup}/providers/Microsoft.Kusto/Clusters/{leaderClusterName}"),
    DatabaseName = "<databaseName>", // Can be a specific database name in a leader cluster or * for all databases
    DefaultPrincipalsModificationKind = KustoDatabaseDefaultPrincipalsModificationKind.Union,
    Location = AzureLocation.chinaeast2
};
// Table level sharing properties are not supported when using '*' all databases notation.
if (attachedDatabaseConfigurationData.DatabaseName != "*")
{
    // Set up the table level sharing properties - the following is just an example.
    attachedDatabaseConfigurationData.TableLevelSharingProperties = new KustoDatabaseTableLevelSharingProperties();
    attachedDatabaseConfigurationData.TableLevelSharingProperties.TablesToInclude.Add("table1");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.TablesToExclude.Add("table2");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.ExternalTablesToExclude.Add("exTable1");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.ExternalTablesToInclude.Add("exTable2");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.MaterializedViewsToInclude.Add("matTable1");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.MaterializedViewsToExclude.Add("matTable2");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.FunctionsToInclude.Add("func1");
    attachedDatabaseConfigurationData.TableLevelSharingProperties.FunctionsToExclude.Add("func2");
}
await attachedDatabaseConfigurations.CreateOrUpdateAsync(WaitUntil.Completed, attachedDatabaseConfigurationName, attachedDatabaseConfigurationData);

验证是否已成功附加数据库

若要验证是否已成功附加数据库,请在 Azure 门户中找到附加的数据库。 可以验证数据库是否已成功附加到后继群集或先导群集。

检查后继群集

  1. 浏览到后继群集并选择“数据库”。

  2. 在数据库列表中搜索新的只读数据库。

    Screenshot of read-only follower databases in portal.

    还可以在数据库概述页中查看此列表:

    Screenshot of databases overview page with list of follower clusters.

检查先导群集

  1. 浏览到先导群集并选择“数据库”

  2. 检查相关数据库是否标记为“与其他数据库共享”“是”

  3. 切换关系链接以查看详细信息。

    Screenshot of databases shared with others to check leader cluster.

    还可以在数据库概述页中查看此信息:

    Screenshot of overview with list of databases shared with others.

分离后继数据库

注意

若要从后继或先导方拆离数据库,必须在分离数据库的群集上拥有至少具有参与者角色的用户、组、服务主体或托管标识。 在下面的示例中,我们使用服务主体。

使用 C# 从后继群集中拆离已附加的后继数据库**

后继群集可按如下所示拆离任何附加的后继数据库:

var tenantId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Directory (tenant) ID
var clientId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Application ID
var clientSecret = "PlaceholderClientSecret"; //Client Secret
var followerSubscriptionId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx";
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var resourceManagementClient = new ArmClient(credentials, followerSubscriptionId);
var followerResourceGroupName = "testrg";
//The cluster and database attached database configuration are created as part of the prerequisites
var followerClusterName = "follower";
var attachedDatabaseConfigurationsName = "attachedDatabaseConfiguration";
var subscription = await resourceManagementClient.GetDefaultSubscriptionAsync();
var resourceGroup = (await subscription.GetResourceGroupAsync(followerResourceGroupName)).Value;
var cluster = (await resourceGroup.GetKustoClusterAsync(followerClusterName)).Value;
var attachedDatabaseConfiguration = (await cluster.GetKustoAttachedDatabaseConfigurationAsync(attachedDatabaseConfigurationsName)).Value;
await attachedDatabaseConfiguration.DeleteAsync(WaitUntil.Completed);

使用 C# 从先导群集中分离已附加的后继数据库

先导群集可按如下所示分离任何附加的数据库:

var tenantId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Directory (tenant) ID
var clientId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx"; //Application ID
var clientSecret = "PlaceholderClientSecret"; //Client Secret
var leaderSubscriptionId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx";
var credentials = new ClientSecretCredential(tenantId, clientId, clientSecret);
var resourceManagementClient = new ArmClient(credentials, leaderSubscriptionId);
var leaderResourceGroupName = "testrg";
var leaderClusterName = "leader";
var subscription = await resourceManagementClient.GetDefaultSubscriptionAsync();
var resourceGroup = (await subscription.GetResourceGroupAsync(leaderResourceGroupName)).Value;
var cluster = (await resourceGroup.GetKustoClusterAsync(leaderClusterName)).Value;
var followerSubscriptionId = "xxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxx";
var followerResourceGroupName = "followerResourceGroup";
//The cluster and attached database configuration that are created as part of the Prerequisites
var followerClusterName = "follower";
var attachedDatabaseConfigurationsName = "attachedDatabaseConfiguration";
var followerDatabaseDefinition = new KustoFollowerDatabaseDefinition(
    clusterResourceId: new ResourceIdentifier($"/subscriptions/{followerSubscriptionId}/resourceGroups/{followerResourceGroupName}/providers/Microsoft.Kusto/Clusters/{followerClusterName}"),
    attachedDatabaseConfigurationName: attachedDatabaseConfigurationsName
);
await cluster.DetachFollowerDatabasesAsync(WaitUntil.Completed, followerDatabaseDefinition);

管理主体、权限和缓存策略

管理主体

附加数据库时,请指定“默认主体修改类型”。 默认设置是将替代授权主体与已授权主体的先导数据库集合组合使用

种类 说明
联合 附加的数据库主体将会始终包括原始数据库主体,以及添加到后继数据库的其他新主体。
不会从原始数据库继承主体。 必须为附加的数据库创建新主体。
附加的数据库主体只包括原始数据库的主体,而不包括其他主体。

若要详细了解如何使用管理命令来配置已授权的主体,请参阅用于管理后继群集的管理命令

管理权限

所有只读数据库类型的权限管理方式都是相同的。 若要分配权限,请参阅在 Azure 门户中管理数据库权限或使用管理命令管理数据库安全角色

配置缓存策略

后继数据库管理员可以修改附加数据库或者该数据库在托管群集上的任何表的缓存策略。 默认设置是将先导群集中的源数据库的数据库级和表级缓存策略将与数据库级和表级替代策略中定义的策略组合使用。 例如,可对先导数据库使用一个 30 天缓存策略以运行每月报告,并对后继数据库使用一个 3 天缓存策略,以仅查询最近的数据进行故障排除。 若要详细了解如何使用管理命令对后继数据库或表配置缓存策略,请参阅用于管理后继群集的管理命令

说明

  • 如果先导/后继群集的数据库之间存在冲突,则在所有数据库都被该后继群集后继时,这些数据库的解析方式如下:
    • 在后继群集上创建的名为 DB 的数据库优先于在先导群集上创建的同名数据库。 因此,需要删除或重命名后继群集中的数据库 DB,以使后继群集包括先导群集的数据库 DB 。
    • 将会从某一个先导群集中任意选择两个或多个先导群集中被后继的名为 DB 的数据库,并且该数据库被后继的次数不会多于一次 。
  • 在某个后继群集上运行的用于显示群集活动日志和历史记录的命令将会显示该后继群集上的活动和历史记录,并且这些命令的结果集不会包括一个或多个先导群集的相应结果。
    • 例如:在后继群集上运行的 .show queries 命令将只显示在由后继群集后继的数据库上运行的查询,而不会显示针对先导群集中同一数据库运行的查询。

限制

  • 后继和先导群集必须位于同一区域。
  • 如果对后继数据库使用了流式引入,则应启用后继群集进行流式引入,以允许流式引入数据跟随。
  • 支持使用客户托管密钥 (CMK) 跟踪具有数据加密的群集,并且具有以下限制:
    • 追随者群集和领导者群集都不会跟踪其他群集。
    • 如果追随者群集正在跟踪启用了 CMK 的领导者群集,并且已撤销领导者对密钥的访问权限,则将会暂停领导者群集和追随者群集。 在这种情况下,你或者可以解决 CMK 问题,然后恢复追随者群集,或者从追随者群集中分离追随者数据库,然后独立于领导者群集进行恢复。
  • 在分离已附加到其他群集的数据库之前,无法删除该数据库。
  • 在分离包含已附加到其他群集的数据库的群集之前,无法删除该群集。
  • 在跟随所有数据库时,表级共享属性不受支持。
  • 在后继数据库中,若要查询使用托管标识作为身份验证方法的外部表,则必须将托管标识添加到后继群集。 当先导群集和后继群集预配在不同的租户中时,此功能不起作用。

后续步骤