SQL 超大规模服务层级性能故障排除诊断

适用于: Azure SQL 数据库

若要排查超大规模数据库中的性能问题,请根据常规 SQL 性能优化方法着手调查任何性能问题。 但是,由于超大规模数据库采用分布式体系结构,可能需要考虑其他诊断数据。 本文将描述超大规模数据库特定的诊断数据。

减少日志速率等待

Azure SQL 数据库中的每个数据库和弹性池通过日志速率治理来管理日志生成速率。 在超大规模中,无论计算大小如何,日志速率治理限制都设置为 105 MB/秒。 此值在 sys.dm_user_db_resource_governanceprimary_max_log_rate 列中公开。

有时,必须降低主计算副本上的日志生成速率以维持可恢复性 SLA。 例如,当页面服务器或另一个计算副本在从日志服务应用新日志记录方面明显落后时,就会发生这种情况。 如果没有超大规模组件落后,日志速率治理机制允许日志生成速率达到 100 MB/秒。 这是所有超大规模计算大小中有效的最大日志生成速率。

当日志速率降低时,sys.dm_os_wait_stats 中会出现以下等待类型:

等待类型 原因
RBIO_RG_STORAGE 页面服务器的延迟日志消耗
RBIO_RG_DESTAGE 长期日志存储的延迟日志消耗
RBIO_RG_REPLICA HA 次要副本或命名副本的延迟日志消耗
RBIO_RG_GEOREPLICA 异地次要副本的延迟日志消耗
RBIO_RG_DESTAGE 日志服务的延迟日志消耗
RBIO_RG_LOCALDESTAGE 日志服务的延迟日志消耗
RBIO_RG_STORAGE_CHECKPOINT 由于数据库检查点缓慢,页面服务器的延迟日志消耗
RBIO_RG_MIGRATION_TARGET 反向迁移期间非超大规模数据库的延迟日志消耗

sys.dm_hs_database_log_rate() 动态管理函数 (DMF) 提供了额外详细信息来帮助你了解日志速率降低(如果有)。 例如,它可以告诉你哪个特定次要副本在应用日志记录方面落后,以及尚未应用的事务日志的总大小是多少。

页面服务器读取

计算副本不会在本地缓存数据库的完整副本。 计算副本本地的数据存储在缓冲池中(内存中)以及包含一部分最常访问的数据页的本地弹性缓冲池扩展 (RBPEX) 缓存中。 此本地 SSD 缓存的大小与计算大小成比例。 另一方面,每个页面服务器都有一个完整的 SSD 缓存,用于存储其维护的数据库部分。

当在计算副本上发出读取 IO 时,如果缓冲池或本地 SSD 缓存中不存在数据,则将从相应的页面服务器提取请求的日志序列号 (LSN) 处的页面。 从页面服务器读取是远程的,并且比从本地 SSD 缓存读取更慢。 排查 I/O 相关的性能问题时,我们需要能够通过相对较慢的页面服务器读取来判断已完成的 IO 数。

多个动态管理视图 (DMV) 和扩展事件包含的列与字段指定了从页面服务器执行的远程读取数,可将其与读取总数进行比较。 查询存储还会在查询运行时统计信息中捕获页面服务器读取。

  • 执行 DMV 和目录视图中提供了用于报告页面服务器读取的列:
  • 页面服务器读取字段存在于以下扩展事件中:
    • sql_statement_completed
    • sp_statement_completed
    • sql_batch_completed
    • rpc_completed
    • scan_stopped
    • query_store_begin_persist_runtime_stat
    • query_store_execution_runtime_info
  • ActualPageServerReads/ActualPageServerReadAheads 属性存在于包含运行时统计信息的计划的查询计划 XML 中。 例如:
    <RunTimeCountersPerThread Thread="8" ActualRows="90466461" [...] ActualPageServerReads="0" ActualPageServerReadAheads="5687297" ActualLobPageServerReads="0" ActualLobPageServerReadAheads="0" />
    

    提示

    若要在查询计划属性窗口中查看这些属性,需要安装 SSMS 18.3 或更高版本。

虚拟文件统计信息和 IO 记帐

在 Azure SQL 数据库中,sys.dm_io_virtual_file_stats() DMF 是监视数据库 I/O 统计信息(如 IOPS、吞吐量和延迟)的一种方法。 由于超大规模的分布式体系结构,其 I/O 特性有所不同。 本部分重点介绍在此 DMF 中看到的读写 I/O。 在超大规模中,此 DMF 中显示的每个数据文件对应于一个页面服务器。 DMF 还为计算副本上的本地 SSD 缓存和事务日志提供 I/O 统计信息。

本地 SSD 缓存使用情况

由于本地 SSD 缓存存在于数据库引擎处理查询的同一计算副本上,因此针对此缓存的 I/O 比针对页面服务器的 I/O 更快。 在超大规模数据库或弹性池中,sys.dm_io_virtual_file_stats() 有一个特殊行报告本地 SSD 缓存的 I/O 统计信息。 对于 database_idfile_id 列,此行的值为 0。 例如,以下查询返回自数据库启动以来的本地 SSD 缓存 I/O 统计信息。

SELECT *
FROM sys.dm_io_virtual_file_stats(0, NULL);

来自本地 SSD 缓存的读取次数与来自所有其他数据文件的聚合读取次数之比是本地 SSD 缓存命中率。 此指标由 sys.dm_os_performance_counters DMV 中提供的 RBPEX cache hit ratioRBPEX cache hit ratio base 性能计数器提供。

数据读取

  • 当计算副本上的数据库引擎发出读取请求时,这些请求可由本地 SSD 缓存或页面服务器提供服务,如果读取多个页面,则还可以通过两者的组合来提供服务。
  • 当计算副本从特定数据文件(例如 file_id 为 1 的文件)读取某些页面时,如果此数据仅驻留在本地 SSD 缓存中,则此读取的所有 IO 都将计入 file_id 0。 如果部分数据位于本地 SSD 缓存中,而部分数据位于页面服务器上,则从本地 SSD 缓存提供服务的部分的 IO 将计入 file_id 0,而从页面服务器提供服务的部分的 IO 将计入其相应的文件。
  • 当计算副本从页面服务器请求位于特定 LSN 的页面时,如果页面服务器未捕获到请求的 LSN,则计算副本上的读取将等到页面服务器赶上后再返回页面。 对于从计算副本上的页面服务器执行的任何读取,如果该操作正在等待该 IO,则会出现 PAGEIOLATCH_* 等待类型。 在“超大规模”中,此等待时间包括捕获到页面服务器上位于所需 LSN 处的请求页面的时间,以及将该页面从页面服务器传输到计算副本所需的时间。
  • 大型读取(例如预读)通常是使用分散-聚集读取完成的。 这样可以通过一次读取 IO 读取最多 4 MB 的数据。 但是,当读取的数据位于本地 SSD 缓存中时,这些读取将被视为多个单独的 8 KB 读取,因为缓冲池和本地 SSD 缓存始终使用 8 KB 页面。 因此,针对本地 SSD 缓存看到的读取 IO 数可能大于引擎执行的实际 IO 数。

数据写入

  • 主计算副本不会直接写入页面服务器, 而是在相应的页面服务器上重播日志服务中的日志记录。
  • 计算副本上的写入将优先写入本地 SSD 缓存 (file_id 0)。 对于大于 8 KB 的写入(即使用聚集-写入完成的写入),每个写入操作都会转换为对本地 SSD 缓存的多个 8 KB 单独写入,因为缓冲池和本地 SSD 缓存始终使用 8 KB 页面。 因此,针对本地 SSD 缓存看到的写入 IO 数可能大于引擎执行的实际 IO 数。
  • 与页面服务器对应的除 file_id 0 之外的数据文件也可能显示写入。 在超大规模中,这些写入是模拟的,因为计算副本永远不会直接写入页面服务器。 I/O 统计信息在计算副本上发生时进行统计。 在除 file_id 0 之外的数据文件的计算副本上看到的 IOPS、吞吐量和延迟不能反映页面服务器上发生的写入的实际 I/O 统计数据。

日志写入

  • 在主计算副本上,日志写入记录在 file_id 2 下的 sys.dm_io_virtual_file_stats() 中。
  • 与 AlwaysOn 可用性组不同,当事务在主计算副本上提交时,不会在次要副本上强化日志记录。 在超大规模中,日志在日志服务中强化,并异步应用于次要副本。 由于日志写入实际上不是在次要副本上发生的,因此次要副本上 sys.dm_io_virtual_file_stats() 中日志 IO 的任何计帐都不应用作事务日志 I/O 统计信息。

资源利用率统计信息中的数据 IO

在非超大规模数据库中,有关相对于资源管理数据 IOPS 限制的针对数据文件的组合读取和写入 IOPS,可查看 avg_data_io_percent 列中的 sys.dm_db_resource_statssys.resource_stats 视图。 弹性池的相应 DMV 是 sys.dm_elastic_pool_resource_statssys.elastic_pool_resource_stats。 报告的值与数据库和弹性池的“数据 IO 百分比”Azure Monitor 指标相同。

在超大规模数据库中,这些列和指标仅报告相对于计算副本上的本地 SSD 存储限制的数据 IOPS 利用率,其中包括针对本地 SSD 缓存和 tempdb 数据库的 I/O。 此列中的值 100% 表示资源管理限制了本地存储 IOPS。 如果这与性能问题相关,请优化工作负载以生成较少的 IO,或者提高计算大小以提高资源治理“最大数据 IOPS限制。 对于本地 SSD 缓存读取和写入的资源治理,系统会对单个 8 KB IO 进行计数,而不是计算可能由数据库引擎发出的较大 IO。

针对页面服务器的数据 IO 不会在资源利用率视图中或通过 Azure Monitor 指标进行报告,但会在 sys.dm_io_virtual_file_stats() 中进行报告,如前所述。