你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

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

适用于:Azure SQL 数据库

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

缩短了日志速率等待

Azure SQL 数据库中的每个数据库和弹性池通过 日志速率治理管理日志生成率。 日志速率限制在primary_max_log_ratesys.dm_user_db_resource_governance的列中公开。

有时,必须减少主要计算副本上的日志生成率,以维护可恢复性服务级别协议(SLA)。 例如,在应用日志服务中的新日志记录后,很久才出现页面服务器或其他计算副本,则会发生此情况。 如果没有超大规模组件,日志速率治理机制允许每个数据库的日志生成速率达到 150 MiB/秒,适用于高级系列和高级系列内存优化硬件。 对于标准系列硬件,每个数据库的最大日志速率为 100 MiB/秒。 对于弹性池,高级系列和高级系列内存优化硬件的每个池的最大日志速率为 150 MiB/秒,对于其他硬件,每个池的最大日志速率为 125 MiB/秒。

当日志写入速率下降时,以下等待类型会出现在 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。

对于超大规模架构,sys.dm_io_virtual_file_stats() 中的相关数据如下:

  • database_idDB_ID 函数返回的值匹配且 file_id 值不是 2 的行对应于页面服务器。 通常,每行对应于一个页面服务器。 但是,对于较大的文件,使用多个页面服务器。

    • 包含 file_id 2 的行对应于事务日志。
  • 列中值 database_id 为 0 的行对应于计算副本上的本地 SSD 缓存。

本地 SSD 缓存使用情况

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

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

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

数据读取

  • 当数据库引擎在计算副本上发出读取请求时,它们可能由本地SSD缓存或页面服务器提供服务,或者在读取多个页面时由两者组合提供服务。

  • 当计算副本从特定数据文件(例如,包含 file_id 1 的文件)读取某些页面时,如果此数据仅驻留在本地 SSD 缓存中,则此读取的所有 IO 将计入本地 SSD 缓存文件(即 database_id 0)。 如果该数据的某些部分位于本地 SSD 缓存中,并且某些部分位于页面服务器上,则 IO 将部分计入本地 SSD 缓存文件,部分用于对应于页面服务器的数据文件。

  • 当计算副本从页面服务器请求特定LSN上的页面时,如果页面服务器尚未达到所请求的LSN,则计算副本上的读取请求会等待,直到页面服务器达到该LSN后再返回页面。 对于从计算副本上的页面服务器读取的任何读取,如果它正在等待该 IO,则会看到 PAGEIOLATCH_* 等待类型。 在“超大规模”中,此等待时间包括捕获到页面服务器上位于所需 LSN 处的请求页面的时间,以及将该页面从页面服务器传输到计算副本所需的时间。

  • 大型读取(例如预读)通常是使用“分散/集中”读取完成的。 这样就可在一次读取 IO 中读取高达 4 MB 内容。 但是,当读取的数据位于本地 SSD 缓存中时,这些读取被视为多个单独的 8 KB 读取,因为缓冲池和本地 SSD 缓存始终使用 8 KB 页。 因此,针对本地 SSD 缓存看到的读取 IO 数可能大于引擎执行的实际 IO 数。

数据写入

  • 主计算副本不会直接写入页服务器。 而是在相应的页面服务器上重播日志服务中的日志记录。

  • 计算副本上的写入主要是写入本地 SSD 缓存 (database_id 0)。 对于大于 8 KB 的写入,(即使用集中写入完成的写入),每个写入操作都会转换为对本地 SSD 缓存的多个单独 8-KB 写入,因为缓冲池和本地 SSD 缓存始终使用 8-KB 页面。 因此,针对本地 SSD 缓存看到的写入 IO 数可能大于引擎执行的实际 IO 数。

  • database_id 0 以外的对应于页面服务器的数据文件可能也会显示写入。 在“超大规模”中,这些写入是模拟的,因为计算副本永远不会直接写入页面服务器。 I/O 统计信息在出现在计算副本上时会被记录。 其它的数据文件非 database_id 0 的计算副本上观察到的写入 IOPS、吞吐量和延迟并不反映页面服务器上发生的写入的实际 I/O 统计信息。

日志写入

  • 在主计算副本上,日志写入会在 sys.dm_io_virtual_file_stats() 下的 file_id 2 中进行记录。

  • 与可用性组不同,在主计算机副本上提交事务时,次要副本上日志记录不会被硬化。 在“超大规模”中,日志在日志服务中强化,并异步应用于辅助副本。 由于日志写入实际上不会发生在辅助副本上,因此不应将辅助副本上 sys.dm_io_virtual_file_stats() 中的日志 IO 的任何计帐用作事务日志 I/O 统计数据。

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

在非超大规模数据库中,针对数据文件的读取和写入 IOPS(相对于 资源治理中的数据 IO 限制),在 sys.dm_db_resource_statssys.resource_stats 视图的 avg_data_io_percent 列中进行报告。 弹性池的相应 DMV 是 sys.dm_elastic_pool_resource_statssys.elastic_pool_resource_stats。 相同的值会被报告为数据库和弹性池的“数据 IO 百分比”Azure Monitor 指标

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

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