使用 Kusto 查询语言脚本配置数据库

在 Azure 资源管理器 (ARM) 模板部署期间,可运行 Kusto 查询语言脚本来配置数据库。 该脚本是包含一个或多个管理命令的列表,其中的每个命令由一个换行符分隔。该脚本创建为通过 ARM 模板访问的资源。

脚本只能运行以下列谓词开头的数据库级管理命令:

  • .create
  • .create-or-alter
  • .create-merge
  • .alter
  • .alter-merge
  • .add

注意

受支持的命令必须在数据库级别运行。 例如,你可以使用命令 .create-or-alter table 更改表。 群集级命令(例如 .alter cluster 策略)不受支持。

通常,建议使用命令的幂等版本。这样的话,如果使用相同的输入参数多次调用它们,它们没有额外的效果。 换句话说,多次运行命令与运行你一次的效果相同。 例如,如果可能,建议使用幂等命令 .create-or-alter 而不是常规的 .create 命令。

可使用多种方法通过脚本来配置数据库。 本文重点介绍使用 ARM 模板部署的以下方法:

  1. 内联脚本:脚本作为 JSON ARM 模板的参数内联提供。
  2. Bicep 脚本:脚本作为 Bicep ARM 模板使用的单独文件提供。
  3. 存储帐户:脚本在 Azure 存储帐户中创建为 Blob,其详细信息(URL 和共享访问签名 (SaS))作为 ARM 模板的参数提供。

注意

每个群集最多可以有 50 个脚本(更多脚本将触发 Code:TooManyScripts 错误)。建议在删除现有脚本后将多个小型脚本合并为较少的大型脚本,为新脚本释放空间。 删除脚本不会回滚从该脚本执行的命令。

管理命令的脚本示例

以下示例是一个脚本,其中包含用于创建 MyTable 和 MyTable2 这两个表的命令

.create-merge table MyTable (Level:string, Timestamp:datetime, UserId:string, TraceId:string, Message:string, ProcessId:int32)

.create-merge table MyTable2 (Level:string, Timestamp:datetime, UserId:string, TraceId:string, Message:string, ProcessId:int32)

请注意,这两个命令是幂等的。 首次运行时,它们会创建表,在后续运行中,它们不起作用。

先决条件

安全性

用于部署脚本的主体(例如用户或服务主体)必须具有以下安全角色:

重要

预配群集的主体会自动获得群集上的 All Databases Admin 角色。

内联脚本

使用此方法创建一个将脚本定义为内联参数的 ARM 模板。 如果脚本具有一个或多个管理命令,请用至少一个换行符分隔这些命令。

使用 ARM 模板运行内联脚本

以下模板演示如何使用 JSON Azure 资源管理器模板运行脚本。

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "kqlScript": {
            "defaultValue": ".create-merge table MyTable (Level:string, Timestamp:datetime, UserId:string, TraceId:string, Message:string, ProcessId:int32)\n\n.create-merge table MyTable2 (Level:string, Timestamp:datetime, UserId:string, TraceId:string, Message:string, ProcessId:int32)",
            "type": "String"
        },
        "forceUpdateTag": {
            "defaultValue": "[utcNow()]",
            "type": "String"
        },
        "continueOnErrors": {
            "defaultValue": false,
            "type": "bool"
        },
        "clusterName": {
            "type": "String"
        },
        "databaseName": {
            "type": "String"
        },
        "scriptName": {
            "type": "String"
        }
    },
    "variables": {
    },
    "resources": [
        {
            "type": "Microsoft.Kusto/Clusters/Databases/Scripts",
            "apiVersion": "2022-02-01",
            "name": "[concat(parameters('clusterName'), '/', parameters('databaseName'), '/', parameters('scriptName'))]",
            "properties": {
                "scriptContent": "[parameters('kqlScript')]",
                "continueOnErrors": "[parameters('continueOnErrors')]",
                "forceUpdateTag": "[parameters('forceUpdateTag')]"
            }
        }
    ],
    "outputs": {
    }
}

使用以下设置:

设置 说明
kqlScript 内联的 Kusto 查询语言脚本。 使用 \n 添加换行符。
forceUpdateTag 唯一的字符串。 如果已更改,则会再次应用脚本。
continueOnErrors 一个标志,指示当某个命令失败时是否继续。 默认值:false。
clusterName 运行脚本的群集的名称。
databaseName 运行脚本的数据库的名称。
scriptName 使用外部文件提供脚本时脚本的名称。 这是 script 类型的实际 ARM 模板资源的名称。

省略更新标记

建议不要在部署每个 ARM 模板时运行 KQL 脚本,因为它会消耗群集资源。 可使用以下方法阻止在连续部署中运行脚本:

  • 指定 forceUpdateTag 属性并在部署之间保留相同的值。
  • 省略 forceUpdateTag 属性或将其留空,并在部署之间使用相同的脚本。

最佳做法是省略 forceUpdateTag 属性,以便在下次部署模板时运行任何脚本更改。 仅在需要强制运行脚本时才使用 forceUpdateTag 属性。

Bicep 脚本

将脚本作为参数传递给模板可能比较繁琐。 通过 Bicep Azure 资源管理器模板,可在单独的文件中保留和维护脚本,然后使用 loadTextContent Bicep 函数将脚本加载到模板中。

假设脚本存储在文件 script.kql 中,该文件与 Bicep 文件位于同一文件夹中,则以下模板将生成与前面的示例相同的结果:

param forceUpdateTag string = utcNow()
param continueOnErrors bool = false
param clusterName string
param databaseName string
param scriptName string

resource cluster 'Microsoft.Kusto/clusters@2022-02-01' existing = {
    name: clusterName
}

resource db 'Microsoft.Kusto/clusters/databases@2022-02-01' existing = {
    name: databaseName
    parent: cluster
}

resource perfTestDbs 'Microsoft.Kusto/clusters/databases/scripts@2022-02-01' = {
    name: scriptName
    parent: db
    properties: {
        scriptContent: loadTextContent('script.kql')
        continueOnErrors: continueOnErrors
        forceUpdateTag: forceUpdateTag
    }
}

使用以下设置:

设置 说明
forceUpdateTag 唯一的字符串。 如果已更改,则会再次应用脚本。
continueOnErrors 一个标志,指示当某个命令失败时继续。 默认值:false。
clusterName 运行脚本的群集的名称。
databaseName 运行脚本的数据库的名称。
scriptName 使用外部文件提供脚本时脚本的名称。

可使用与 JSON ARM 模板类似的工具部署 Bicep 模板。 例如,可使用以下 Azure CLI 命令来部署模板:

az deployment group create -n "deploy-$(uuidgen)" -g "MyResourceGroup" --template-file "json-sample.json" --parameters clusterName=MyCluster databaseName=MyDb

Bicep 模板在部署前会转译为 JSON ARM 模板。 在此示例中,脚本文件内联嵌入 JSON ARM 模板中。 有关详细信息,请参阅 Bicep 概览

存储帐户脚本

此方法假设你在 Azure 存储帐户中已有一个 Blob,并且你在 ARM 模板中直接提供其详细信息(URL 和共享访问签名 (SaS))。

备注

无法从配置有 Azure 存储防火墙或虚拟网络规则的存储帐户中加载脚本。

创建脚本资源

第一步是创建脚本并将其上传到存储帐户。

  1. 创建包含要用于在数据库中创建表的管理命令的脚本

  2. 将脚本上传到 Azure 存储帐户。 可使用 Azure 门户PowerShell 或 Azure CLI 创建存储帐户。

  3. 使用共享访问签名 (SaS) 提供对此文件的访问权限。 可以使用 PowerShell、Azure CLI.NET 提供访问权限。

使用 ARM 模板运行脚本

本部分介绍如何使用 Azure 资源管理器模板运行存储在 Azure 存储中的脚本。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "scriptUrl": {
      "type": "String"
    },
    "scriptUrlSastoken": {
      "type": "SecureString"
    },
    "forceUpdateTag": {
      "defaultValue": "[utcNow()]",
      "type": "String"
    },
    "continueOnErrors": {
      "defaultValue": false,
      "type": "bool"
    },
    "clusterName": {
      "type": "String"
    },
    "databaseName": {
      "type": "String"
    },
    "scriptName": {
      "type": "String"
    }
  },
  "variables": {
  },
  "resources": [
    {
      "type": "Microsoft.Kusto/Clusters/Databases/Scripts",
      "apiVersion": "2021-01-01",
      "name": "[concat(concat(parameters('clusterName'), '/'), concat(parameters('databaseName'), '/'), parameters('scriptName'))]",
      "properties": {
        "scriptUrl": "[parameters('scriptUrl')]",
        "scriptUrlSasToken": "[parameters('scriptUrlSasToken')]",
        "continueOnErrors": "[parameters('continueOnErrors')]",
        "forceUpdateTag": "[parameters('forceUpdateTag')]"
      }
    }
  ],
  "outputs": {
  }
}

使用以下设置:

设置 说明
scriptUrl Blob 的 URL。 例如,“https://myaccount.blob.core.chinacloudapi.cn/mycontainer/myblob”。
scriptUrlSastoken 一个包含共享访问签名 (SaS) 的字符串。
forceUpdateTag 唯一的字符串。 如果已更改,则会再次应用脚本。
continueOnErrors 一个标志,指示当某个命令失败时是否继续。 默认值:false。
clusterName 运行脚本的群集的名称。
databaseName 运行脚本的数据库的名称。
scriptName 使用外部文件提供脚本时脚本的名称。

限制

  • 仅 Azure 数据资源管理器支持脚本;Synapse 数据资源管理器池不支持脚本。
  • 不能在同一群集上并行添加、修改或删除两个脚本。 如果出现这种情况,会引发错误 Code="ServiceIsInMaintenance"。 要解决此问题,可以在两个脚本之间放置依赖项,以便按顺序创建或更新两个脚本。
  • 若要使用脚本创建具有跨群集查询的函数,必须在 .create 函数命令 中将 skipvalidation 属性设置为 true

疑难解答

脚本资源运行的命令不会出现在 .show commands-and-queries 命令的结果中。 可使用 .show journal 命令跟踪脚本执行。