本文内容
在本文中,我们将回顾 Azure SQL 数据库中的弹性作业的功能和详细信息。
- 有关配置弹性作业的教程,请参阅弹性作业教程。
- 详细了解 Azure 数据库平台中的自动化概念。
可以创建和计划可针对一个或多个 Azure SQL 数据库定期执行的弹性作业,以运行 Transact-SQL (T-SQL) 查询和执行维护任务。
可以定义要在其中执行作业的目标数据库或数据库组,并定义运行作业 的计划 。 弹性作业中的所有日期和时间均为 UTC 时区。
作业可以处理登录到目标数据库的任务。 此外,可以定义、维护以及保存要跨一组数据库执行的 Transact-SQL 脚本。
每个作业会记录执行状态,如果发生任何失败,则还会自动重试操作。
弹性作业自动化有多种使用场景:
- 自动完成管理任务,并将作业计划为在每个工作日、数小时之后或按其他频率运行。
- 部署架构更改、进行凭据管理。
- 性能数据收集或租户(客户)遥测数据收集。
- 更新引用数据(所有数据库的公用信息)。
- 从 Azure Blob 存储服务加载数据。
- 配置作业,以便定期(例如,在非高峰时段)对一系列数据库执行作业。
- 持续将一组数据库中的查询结果收集到中央表中。
- 查询可以持续执行,并可配置为触发执行其他任务。
- 收集要报告的数据
- 将数据库集合中的数据聚合到单个目标表中。
- 对大量的数据库执行长时间运行的数据处理查询,例如,收集客户遥测数据。 结果将收集到单个目标表以供进一步分析。
- 数据移动
- 适用于自定义开发的解决方案、业务自动化或其他任务管理。
- 用于在数据库中的表之间提取/处理/插入数据的 ETL 处理。
在以下情况下,可以考虑使用弹性作业:
- 有一项任务需要按计划定期运行,且目标是一个或多个数据库。
- 有一项任务只需要运行一次,但要在多个数据库上执行。
- 需要针对数据库的任意组合运行作业:可以是一个或多个单独的数据库,可以是一个服务器上的所有数据库,可以是一个弹性池中的所有数据库,而且还可以灵活地包括或排除任何特定的数据库。 任务可以跨多个服务器、多个池运行,甚至可以在不同订阅中的数据库上运行。 服务器和池会在运行时进行动态枚举,因此作业会针对执行时目标组中存在的所有数据库来运行。
- 这是与 SQL 代理的显著区别,SQL 代理无法动态枚举目标数据库,尤其是在动态添加/删除数据库的 SaaS 客户场景中。
组件 | 说明 |
---|---|
弹性作业代理 | 为了运行和管理作业而创建的 Azure 资源。 |
作业数据库 | 作业代理用来存储作业相关数据、作业定义等内容的 Azure SQL 数据库中的数据库。 |
作业 | 作业是由一个或多个作业步骤组成的工作单元。 作业步骤指定要运行的 T-SQL 脚本,以及执行脚本所需的其他详细信息。 |
目标组 | 一组服务器、池和数据库,可对其运行作业。 |
弹性作业代理是用于创建、运行和管理作业的 Azure 资源。 弹性作业代理是在门户中创建的 Azure 资源(还支持使用 PowerShell 和 REST API 创建和管理弹性作业)。
创建弹性作业代理需要现有的 Azure SQL 数据库中的数据库。 代理将这个现有的 Azure SQL 数据库配置为作业数据库。
可以通过 Azure 门户启动、禁用或取消作业。 通过 Azure 门户还可查看作业定义和执行历史记录。
在 Azure SQL 数据库中,作业数据库的费率与其他数据库相同。 弹性作业代理的成本基于为作业代理选择的服务层级的固定定价。 请参阅 Azure SQL 数据库定价页。
作业数据库用于定义作业以及跟踪作业执行操作的状态和历史记录。 在目标数据库中执行任务。 作业数据库也用于存储代理元数据、日志、结果、作业定义,并且还包含许多有用的存储过程,以及其他数据库对象,可以通过 T-SQL 创建、运行和管理作业。
创建弹性作业代理需要 Azure SQL 数据库。 作业代理将所有与作业相关的元数据存储在 作业数据库中,该数据库应该是新的空 Azure SQL 数据库。
作业数据库的建议服务目标是 DTU S1 或更高版本,但最佳选择取决于作业的性能需求:作业步骤数、作业目标数以及作业运行频率。
如果针对作业数据库的操作的速度比预期慢,则在出现速度缓慢的情况时使用 Azure 门户或 sys.dm_db_resource_stats DMV 监视作业数据库中的数据库性能和资源利用率。 如果资源(如 CPU、数据 IO 或日志写入)的使用率达到 100%,且与出现缓慢情况的时间段相关,请考虑以增量方式将数据库扩展到更高的服务目标(采用 基于 DTU 的购买模型或 vCore 购买模型),直到工作数据库性能得到充分改进。
作业数据库本身可以是弹性作业的目标。 在这种情况下,工作数据库的处理方式与任何其他目标数据库相同。 必须在作业数据库中创建作业用户并为其授予足够权限,并且该作业用户的数据库范围的凭据也必须存在于作业数据库中,就像任何其他目标数据库的情况一样。
当作业数据库本身是作业的目标时,请确保作业不会修改/删除存储在该数据库中的任何特定于作业代理的元数据。 只有 作业存储过程 或 作业视图 才可用于修改/查询作业相关信息。
重要
请勿修改现有对象或在作业数据库中创建新对象,但可以从表中读取报告和分析数据。
作业是按计划执行的或只执行一次的工作单元。 作业包含一个或多个作业步骤。
每个作业步骤都会指定一个要执行的 T-SQL 脚本、一个或多个要对其运行 T-SQL 脚本的目标组,以及作业代理连接到目标数据库所需的凭据。 每个作业步骤都有可自定义的超时和重试策略,并且可以选择性地指定输出参数。
使用弹性作业,可以按计划或按需跨大量数据库并行运行一个或多个 T-SQL 脚本。 目标可以是 Azure SQL 数据库的任何层。
可以针对数据库的任意组合运行计划作业:可以是一个或多个单独的数据库,可以是一个服务器上的所有数据库,可以是一个弹性池中的所有数据库,而且还可以灵活地包括或排除任何特定的数据库。 作业可以跨多个服务器、多个池来运行,甚至可以针对不同订阅中的数据库来运行。 服务器和池会在运行时进行动态枚举,因此作业会针对执行时目标组中存在的所有数据库来运行。
下图显示了一个跨不同类型的目标组执行作业的作业代理:
目标组定义可以在其上执行作业步骤的数据库集。 目标组可以包含任意数目和任意组合的以下项:
- 逻辑 SQL 服务器 - 如果指定了一个服务器,则在作业执行时存在于该服务器的所有数据库都会成为组的一部分。 必须提供
master
数据库凭据,然后才能在执行作业之前枚举和更新组。 有关逻辑服务器的详细信息,请参阅 Azure SQL 数据库和 Azure Synapse 中的逻辑服务器是什么?。 - 弹性池 - 如果指定一个弹性池,则在执行作业时位于该弹性池中的所有数据库都会成为组的一部分。 就服务器来说,必须提供
master
数据库凭据,然后才能在执行作业之前更新组。 - 单个数据库 - 指定一个或多个将要成为组的一部分的单独数据库。
提示
在执行作业时,动态枚举会重新评估包含服务器或池的目标组中的数据库集。 动态枚举确保在执行作业时,作业可以跨服务器或池中存在的所有数据库运行。 在运行时重新评估数据库列表对于池或服务器成员身份频繁更改的情况非常有用。
可以将池和单个数据库指定为包括在组中或从组中排除。 这样就可以使用任意数据库组合来创建目标组。 例如,可以向目标组添加一个服务器,但将弹性池中的特定数据库排除出去(也可以排除整个池)。
目标组可以包括多个区域的多个订阅中的数据库。 跨区域执行的延迟高于同一区域内的执行。
以下示例演示如何在作业执行时动态枚举不同的目标组定义,以确定要影响的数据库:
- 示例 1 演示的目标组包含一个由各个数据库组成的列表。 使用此目标组执行某个作业步骤时,作业步骤的操作会在这其中的每个数据库中执行。
- 示例 2 演示的目标组包含一个充当目标的服务器。 使用此目标组执行某个作业步骤时,会动态枚举服务器,以便确定目前在服务器中的数据库的列表。 作业步骤的操作会在这其中的每个数据库中执行。
- 示例 3 演示的目标组与示例 2 的类似,但明确排除了单个数据库。 作业步骤的操作不会在排除的数据库中执行。
- 示例 4 演示的目标组包含一个充当目标的弹性池。 与示例 2 类似,此池会在作业运行时动态枚举,以便确定池中数据库的列表。
- 示例 5 和示例 6 演示高级方案,其中的服务器、弹性池和数据库可以使用包括和排除规则进行组合。
弹性作业是云优先产品,设计为即使在计划执行时出现短暂的网络或服务可用性问题也能启动。 弹性作业计划考虑到计划开始时间和请求的间隔。 创建弹性作业计划时,作业将在每个计划间隔事件发生后立即运行。
重要
最佳做法是创建从将来开始的作业计划。
作业计划检测到错过的事件。 如果创建一个从过去的某个时间点开始的新作业计划,该作业一旦启用就会立即执行。 如果禁用或不可用,则作业将在启用或可用后立即运行。
例如,它当前为 1 月 2 日上午 9 点。 你设置了一个新作业,计划在今晚(协调世界时 1 月 2 日晚上 10:30)开始,每天运行一次。 该作业将在下午 10:30 执行。
为防止作业意外启动,请创建在未来开始的计划。 在一个可能导致作业意外启动的示例中,你设置了一个新作业,在协调世界时每天晚上 10:30 运行。 你将该作业禁用了一周。 然后,如果在协调世界时上午 8:30 启用该作业,作业将立即执行,以弥补昨晚本应执行但错过的时间间隔事件。 执行后,作业代理要到下一次计划的协调世界时晚上 10:30 执行时才会再次运行。 为了避免这种情况下在协调世界时上午 8:30 执行作业,请将作业计划的开始时间更新为 1 月 8 日协调世界时晚上 10:30,然后再启用作业。 或者,在作业可以立即运行的时间启用作业。
为弹性作业代理的所有目标选择一种方法。 例如,对于单个弹性作业代理,不能将一个目标服务器配置为使用数据库范围凭据,而将另一个服务器配置为使用 Microsoft Entra ID 进行身份验证。
弹性作业代理可以通过两个身份验证选项连接到目标组指定的服务器/数据库:
通过用户分配的托管标识 (UMI) 进行的 Microsoft Entra(前身为 Azure Active Directory)身份验证是将弹性作业连接到 Azure SQL 数据库的推荐选项。 通过 Microsoft Entra ID 的支持,作业代理使用 UMI 连接到目标数据库(包括数据库、服务器和弹性池)以及输出数据库。
或者,还可以在包含弹性作业数据库的逻辑服务器上启用 Microsoft Entra ID 身份验证,以便通过 Microsoft Entra ID 连接访问/查询该数据库。 但是,作业代理本身使用基于证书的内部身份验证来连接到其作业数据库。
可以创建一个 UMI,或使用现有的 UMI,并将相同的 UMI 分配给多个作业代理。 每个作业代理仅支持一个 UMI。 将 UMI 分配给作业代理后,该作业代理将仅使用此标识在目标数据库中连接和运行 t-SQL 作业。SQL 身份验证将不会用于该作业代理的目标服务器/数据库。
UMI 名称必须以字母或数字开头,长度介于 3 到 128 个字符之间。 可以包含 -
和 _
字符。
有关 Azure SQL 数据库 中的 UMI 的详细信息,请参阅 Azure SQL 的托管标识,包括使用 UMI 作为 Azure SQL 数据库逻辑服务器标识所需的步骤和优势。 有关更多信息,请参阅 SQL Server 的 Microsoft Entra 身份验证。
重要
使用 Microsoft Entra ID 身份验证时,请在每个目标数据库中从该 Microsoft Entra ID 创建 jobuser
用户。 向用户授予在每个目标数据库中执行作业所需的权限。
不支持使用系统分配的托管标识 (SMI)。
虽然建议使用 Microsoft Entra(以前称为 Azure Active Directory)身份验证,但可以将作业配置为使用数据库范围的凭据,以便在执行时连接到目标组指定的数据库。 在 2023 年 10 月之前,数据库范围的凭据是唯一的身份验证选项。
如果目标组包含服务器或池,则可使用这些数据库范围的凭据连接到 master
数据库,以便枚举可用的数据库。
- 必须在作业数据库中创建数据库范围的凭据。
- 所有目标数据库必须有一个具有足够权限的登录名,否则作业无法成功完成(下图中的
jobuser
)。 - 目标数据库中创建的凭据(下图中针对
masteruser
和jobuser
的LOGIN
和PASSWORD
)应与在作业数据库中创建的凭据中的IDENTITY
和SECRET
一致。 - 凭据可以跨作业反复使用,而凭据密码经过加密后,无法供只能通过只读方式访问作业对象的用户访问。
下图旨在帮助了解如何设置正确的作业凭据,以及弹性作业代理如何使用数据库凭据作为身份验证来连接到目标服务器/数据库中的登录名/用户。
备注
使用数据库作用域的凭据时,请记住在每个目标数据库中创建 jobuser
用户。
弹性作业代理支持弹性作业专用终结点。 通过创建弹性作业专用终结点,可建立弹性作业与目标服务器之间的专用链接。 弹性作业专用终结点的功能与 Azure 专用链接不同。
弹性作业专用终结点功能支持目标/输出服务器的专用连接,因此即使启用了“拒绝公共访问”选项,作业代理仍可进行连接。 如果你想要禁用“允许 Azure 服务和资源访问该服务器”选项,则使用专用终结点也是一种可行的解决方案。
弹性作业专用终结点支持弹性作业代理身份验证的所有选项。
弹性作业专用终结点功能允许选择服务托管的专用终结点,以在作业代理与其目标/输出服务器之间建立安全连接。 服务托管的专用终结点是特定虚拟网络和子网中的专用 IP 地址。 选择在其中一个作业代理的目标/输出服务器上使用专用终结点时,Microsoft 会创建服务托管的专用终结点。 然后,作业代理会独占使用此专用终结点来连接和执行作业,或用于在目标/输出数据库上写入作业输出。
可以通过 Azure 门户创建并允许使用弹性作业专用终结点。 通过专用链接连接的目标服务器可以位于 Azure 中的任何位置,即使在不同的地理位置和订阅中也是如此。 必须为每个所需的目标服务器和作业输出服务器创建专用终结点,才能启用此通信。
有关为弹性作业配置新的服务托管专用终结点的教程,请参阅配置 Azure SQL 弹性作业专用终结点。
- 若要使用弹性作业专用终结点,作业代理和目标服务器/数据库都必须托管在 Azure 中(相同或不同的区域)。
Microsoft.Network
资源提供程序必须在作业代理和目标/输出服务器的主机订阅中进行注册。- 针对每个目标/输出服务器创建弹性作业专用终结点。 必须先批准这些终结点,然后弹性作业代理才能使用它们。 可以通过该逻辑服务器或首选客户端的“网络”窗格来完成此操作。 然后,弹性作业代理将能够使用专用连接访问该服务器下的任何数据库。
- 从弹性作业代理到作业数据库的连接将不会使用专用终结点。 作业代理本身使用基于证书的内部身份验证来连接到其作业数据库。 如果你将作业数据库添加为目标组成员,则需要特别留意。 那么,它的行为与常规目标一样,你需要根据需要为其设置专用终结点。
在创建作业代理期间,会在作业数据库中创建一个架构、多个表和一个名为 jobs_reader 的角色。 此角色使用以下权限创建,旨在为管理员提供进行作业监视所需的更细致访问控制。 管理员可以通过将用户添加到作业数据库中的 jobs_reader 角色,让用户能够监视作业的执行情况。
角色名称 | jobs 架构权限 |
jobs_internal 架构权限 |
---|---|---|
jobs_reader |
SELECT |
无 |
注意
不得更新“作业数据库”中的内部目录视图,例如jobs.target_group_members。 手动更改上述目录视图可能会损坏“作业数据库”并导致失败。 上述视图仅用于只读查询。 可使用“作业数据库”中的存储过程来添加/删除目标组/成员,例如jobs.sp_add_target_group_member。
重要
在授予对“职位数据库”的提升访问权限之前,请考虑安全隐患。 有权创建或编辑作业的恶意用户可能会创建或编辑一个作业,以便使用存储的凭据连接到受其控制的数据库,从而确定凭据的密码或执行恶意命令。
弹性作业代理已与 Azure 警报集成以获得作业状态通知,从而简化了监视作业执行状态和历史记录的解决方案。
Azure 门户还有新的附加功能,用于支持弹性作业和作业监视。 在弹性作业代理的“概述”页上,将显示近期的作业执行,如以下屏幕截图所示。
可以使用 Azure 门户、Azure CLI、PowerShell 和 REST API 创建 Azure Monitor 警报规则。 失败的弹性作业指标是监视和接收有关弹性作业执行情况的警报的良好入手点。 此外,还可以选择通过 Azure 警报设施的可配置操作(如短信或电子邮件)发出警报。 有关详细信息,请参阅在 Azure 门户中为 Azure SQL 数据库创建警报。
示例见创建、配置和管理弹性作业。
针对每个目标数据库执行的作业步骤的结果会详细记录,而脚本输出则可捕获到指定的表中。 可以指定一个数据库,用于保存从作业返回的任何数据。
通过查询表 ,在作业数据库中jobs.job_executions
。 系统清除作业会清除时间超过 45 天的执行历史记录。 若要手动删除时间不到 45 天的历史记录,请在sp_purge_jobhistory
中执行 存储过程。
可以通过查询表 ,在作业数据库中jobs.job_executions
。
使用弹性数据库作业时,请考虑以下最佳实践。
- 将 API 的使用限制为受信任的个人。
- 凭据应该具有执行作业步骤所需的最低权限。 有关详细信息,请参阅授权和权限。
- 使用服务器和/或池目标组成员时,强烈建议创建另外一个凭据,该凭据有权在
master
数据库上查看/列出数据库,用于在作业执行之前展开服务器和/或池的数据库列表。
弹性作业在等待长时间运行的作业完成时使用极少的计算资源。
根据目标数据库组的大小和作业所需执行时间(并发辅助角色数)的不同,代理需要的计算量和作业数据库性能也会有所不同(目标数和作业数越多,所需计算量越大)。
从 2023 年 10 月开始,弹性作业代理具有多层性能,从而可以增加容量。
容量增量表示作业代理可以连接到和启动作业的并发目标数据库的总数。 如果执行作业时需要建立更多的并发目标连接,请从默认的 JA100 层(限制为 100 个并发目标连接)开始升级作业代理的层级。
在任何时候,大多数环境需要执行少于 100 个并发作业,因此默认设置为 JA100。
弹性作业代理层 | 最大并发作业数 |
---|---|
JA100 |
100 |
JA200 |
200 |
JA400 |
400 |
JA800 |
800 |
当作业目标数超过作业代理的并发容量层级时,将导致部分目标数据库/服务器的队列延迟。 例如,假设在 JA100 层中启动具有 110 个目标的作业,则有 10 个目标将会等到其他目标完成后才会开始。
可以通过 Azure 门户、PowerShell 或作业代理 REST API 修改弹性作业代理的层级或服务目标。 有关示例,请参阅缩放作业代理。
若要确保针对 Azure SQL 数据库弹性池中的数据库运行作业时资源不会超负荷,可以对作业进行配置,限制可以在同一时间对其运行作业的数据库数。
通过在 T-SQL 中设置 sp_add_jobstep
存储过程的 @max_parallelism
参数来设置作业运行时所在的并发数据库的数目。
弹性作业的 T-SQL 脚本必须幂等。 幂等是指如果脚本成功,则再次运行时,会出现相同的结果。 脚本可能由于暂时性网络问题而失败。 在此情况下,作业会自动重试运行脚本,达到默认的次数才停止。 即使幂等脚本已成功运行两次(或更多次),也仍会返回相同的结果。
一个简单的策略是在创建对象之前测试其是否存在。 下面是一个假设的示例:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE [name] = N'some_object')
print 'Object does not exist'
-- Create the object
ELSE
print 'Object exists'
-- If it exists, drop the object before recreating it.
同样地,脚本必须以逻辑方式测试并反驳它所找到的任何条件,才能成功执行。
弹性作业服务目前存在以下限制。 我们正在尽一切努力消除其中的许多限制。
问题 | 说明 |
---|---|
故障转移/移动到新的 Azure 区域后,需要在新区域中重新创建和启动弹性作业代理。 | 弹性作业服务将其所有作业代理和作业元数据存储在作业数据库中。 Azure 资源的任何故障转移或移动到新的 Azure 区域时,作业数据库、作业代理和作业元数据也将被移到新的 Azure 区域。 但是,弹性作业代理是仅计算资源,需要在新区域中显式重新创建和启动,然后作业才能在新区域中再次开始执行。 启动后,弹性作业代理将根据先前定义的作业计划继续在新区域中执行作业。 |
作业数据库产生过多的审核日志 | 弹性作业代理通过不断轮询作业数据库来检查新作业的到达情况以及其他增删改查 (CRUD) 操作。 如果在作业数据库所在的服务器上启用审核,则作业数据库可能会生成大量的审核日志。 可以使用带有谓词表达式的 Set-AzSqlServerAudit 命令筛选掉这些审核日志,从而缓解该问题。例如: Set-AzSqlServerAudit -ResourceGroupName "ResourceGroup01" -ServerName "Server01" -BlobStorageTargetState Enabled -StorageAccountResourceId "/subscriptions/7fe3301d-31d3-4668-af5e-211a890ba6e3/resourceGroups/resourcegroup01/providers/Microsoft.Storage/storageAccounts/mystorage" -PredicateExpression "database_principal_name <> '##MS_JobAccount##'" 此命令仅筛选作业代理到作业数据库的审核日志,而不会筛选作业代理到任何目标数据库的审核日志。 |
使用超大规模数据库作为作业数据库 | 不支持使用超大规模数据库作为作业数据库。 但是,弹性作业可将超大规模数据库用作目标,就如同将 Azure SQL 数据库中的任何其他数据库用作目标一样。 |
无服务器数据库与弹性作业的自动暂停功能。 | 不支持将已启用自动暂停功能的无服务器数据库用作作业数据库。 弹性作业所针对的无服务器数据库确实支持自动暂停,并且会在作业连接时恢复运行。 |
将作业数据库导出到 BACPAC 文件 | 不支持将作业数据库导出到 BACPAC 文件。 如果需要导出包含作业数据库的 SQL 服务器,则应在导出服务器之前先删除作业数据库。 |