使用只读副本卸载只读的查询工作负荷

applies to:Azure SQL DatabaseAzure SQL Managed Instance

作为高可用性体系结构的一部分,“高级”和“业务关键”服务层级中的每个单一数据库或弹性池数据库会自动预配有一个主读写副本和一个或多个次要只读副本。 为次要副本预配的计算大小与主要副本相同。 “读取扩展”功能允许使用一个只读副本的计算容量而不是在读写副本上运行它们来卸载只读工作负荷。 这样,一些只读工作负载可与读写工作负载隔离,并且不会影响其性能。 该功能适用于包含逻辑隔离的只读工作负荷(例如分析)的应用程序。 在“高级”和“业务关键”服务层级中,应用程序可以使用此额外的容量获得性能优势,而无需额外付费。

在超大规模服务层级中,如果至少添加了一个次要副本,也可以使用读取扩展功能。 超大规模次要命名副本提供独立扩展、访问隔离、工作负载隔离、对各种读取扩展场景的支持以及其他优势。 多个辅助 高可用性(HA)副本 可用于负载均衡只读工作负荷,这些工作负荷需要的资源多于一个辅助 HA 副本上的可用资源。

“基本”、“标准”和“常规用途”服务层级的高可用性体系结构不包含任何副本。 读负载扩展功能在这些服务层级中不可用。 但是,使用 Azure SQL Database 时,geo-replicas可以在这些服务层级中提供类似的功能。 在使用 Azure SQL 托管实例和故障转移组时,故障转移组的只读侦听器可以分别提供类似的功能。

下图演示了高级和业务关键型数据库和 SQL 托管实例的功能。

显示只读副本的示意图。

新的“高级”、“业务关键”和“超大规模”数据库中默认已启用读取扩展功能。

注意

读取横向扩展始终在SQL Managed Instance的业务关键服务层级中启用,并且对于具有至少一个次要副本的超大规模数据库。

如果 SQL 连接字符串配置为 ApplicationIntent=ReadOnly,则应用程序将被重定向到数据库或托管实例的只读副本。 有关如何使用 ApplicationIntent 属性的信息,请参阅指定应用程序意向

仅对于 Azure SQL Database,如果希望确保应用程序连接到主副本,而不考虑 SQL 连接字符串中的 ApplicationIntent 设置,则必须在创建数据库或更改其配置时显式禁用读扩展。 例如,如果你将数据库从标准层级或常规用途层级升级到高级版或业务关键,并且要确保所有连接继续转到主副本,请禁用读取横向扩展。有关禁用方法的详细信息,请参阅启用和禁用读取横向扩展

注意

只读副本不支持 SQL Profiler 功能。

数据一致性

对主要副本进行的数据更改根据副本类型以同步或异步方式在只读副本上持久保存。 但是,对于所有副本类型,从只读副本执行的读取操作始终是相对于主要副本的异步操作。 在连接到只读副本的会话中,读取始终在事务上保持一致。 由于数据传播延迟是可变的,因此不同的副本可能会在相对于主要副本和其他副本略微不同的时间点返回数据。 如果只读副本变得不可用并且会话重新连接,它可能会连接到与原始副本位于不同时间点的副本。 同样,如果应用程序在主要副本上使用读写会话更改数据,并立即使用只读会话在只读副本上读取该数据,则最新的更改可能不会在只读副本中立即可见。

主要副本和只读副本之间的典型数据传播延迟在几十毫秒到几秒的范围内变化。 但是,数据传播延迟没有固定的上限。 副本中的高资源利用率等条件会显著增加延迟。 如果应用程序需要保证跨会话数据一致性或需要提交的数据立即可读,则应使用主要副本。

注意

数据传播延迟包括将日志记录发送和保存(如果适用)到次要副本所需的时间。 它还包括将这些日志记录恢复(应用)到数据页所需的时间。 为了确保数据一致性,在应用事务提交日志记录之前,更改将不可见。 当工作负载使用更大的事务时,有效的数据传播延迟会增加。

若要监视数据传播延迟,请参阅对只读副本进行监视和故障排除

连接到只读副本

为数据库启用扩展读功能时,客户端提供的连接字符串中的 ApplicationIntent 选项决定了连接是路由到写入副本还是只读副本。 具体而言,如果 ApplicationIntent 值为 ReadWrite(默认值),则连接会定向到读写副本。 这与connection string中不包含 ApplicationIntent 时的行为相同。 如果 ApplicationIntent 值为 ReadOnly,则连接将路由到只读副本。

例如,以下connection string将客户端连接到只读副本(将尖括号中的项替换为环境的正确值并删除尖括号):

Server=tcp:<server>.database.chinacloudapi.cn;Database=<mydatabase>;ApplicationIntent=ReadOnly;User ID=<myLogin>;Password=<password>;Trusted_Connection=False; Encrypt=True;

若要使用 SQL Server Management Studio(SSMS)连接到只读副本,请选择 Options

SSMS 选项按钮的屏幕截图。

选择 “其他连接参数 ”并输入 ApplicationIntent=ReadOnly,然后选择“ 连接

显示 SSMS“其他连接参数”的屏幕截图。

以下连接字符串之一将客户端连接到读写副本(请将尖括号中的项替换为环境的正确值,并删除尖括号):

Server=tcp:<server>.database.chinacloudapi.cn;Database=<mydatabase>;ApplicationIntent=ReadWrite;User ID=<myLogin>;Password=<password>;Trusted_Connection=False; Encrypt=True;

Server=tcp:<server>.database.chinacloudapi.cn;Database=<mydatabase>;User ID=<myLogin>;Password=<password>;Trusted_Connection=False; Encrypt=True;

验证连接到只读副本

可通过在数据库上下文中运行以下查询来验证是否连接到只读副本。 连接到只读副本时,它将返回 READ_ONLY。

SELECT DATABASEPROPERTYEX(DB_NAME(), 'Updateability');

注意

在“高级”和“业务关键”服务层级中,只有一个只读副本随时可供访问。 “超大规模”层级支持多个只读副本。

对只读副本进行监视和故障排除

当连接到只读副本时,动态管理视图 (DMV) 反映副本的状态,并可对其进行查询以进行监视和故障排除。 数据库引擎提供了多个视图来公开各种监视数据。

以下视图通常用于副本监视和故障排除:

名称 目的
sys.dm_db_resource_stats 提供最近一小时的资源利用率指标,包括相对于服务目标限制的 CPU、数据 IO 和日志写入使用率。
sys.dm_os_wait_stats 提供数据库引擎实例的聚合等待统计信息。
sys.dm_database_replica_states 提供副本运行状况状态和同步统计信息。 重做日志队列大小和重做日志速率用作只读副本数据传播延迟的指标。
sys.dm_os_performance_counters 提供数据库引擎性能计数器。
sys.dm_exec_query_stats 提供每个查询的执行统计信息,例如执行次数、已用 CPU 时间等。
sys.dm_exec_query_plan() 提供缓存的查询计划。
sys.dm_exec_sql_text() 提供缓存的查询计划的查询文本。
sys.dm_exec_query_profiles 提供正执行查询时的实时查询进度。
sys.dm_exec_query_plan_stats() 提供最近的已知实际执行计划,包括查询的运行时统计信息。
sys.dm_io_virtual_file_stats() 提供所有数据库文件的存储 IOPS、吞吐量和延迟统计信息。

注意

逻辑 sys.resource_stats 数据库中的 sys.elastic_pool_resource_statsmaster DMV 返回主要副本的资源利用率数据。

监视具有扩展事件的只读副本

连接到只读副本时,无法创建扩展事件会话。 但是,在Azure SQL Database和Azure SQL Managed Instance中,数据库范围的Extended Event会话定义在主副本上创建和更改后被复制到只读副本,包括异地副本,并在这些只读副本上捕获事件。

在Azure SQL Database中,基于主副本的会话定义的只读副本上的扩展事件会话可以独立于主副本上的会话启动和停止。

在Azure SQL Managed Instance中,若要在只读副本上启动跟踪,必须先在主副本上启动跟踪,然后才能在只读副本上启动跟踪。 如果没有先在主要副本上启动跟踪,则会在尝试在只读副本上启动跟踪时收到以下错误:

Msg 3906,级别 16,状态 2,行 1 无法更新数据库“master”,因为该数据库为只读。

首先在主副本上启动跟踪,然后在只读副本上启动跟踪,然后可以在主副本上停止跟踪。

要删除只读副本上的事件会话,请执行以下步骤:

  1. Connect SSMS Object Explorer或只读副本的查询窗口。
  2. 通过在Object Explorer的会话上下文菜单上选择 Stop Session,或者通过在查询窗口中执行 ALTER EVENT SESSION [session-name-here] ON DATABASE STATE = STOP; 来停止只读副本上的会话。
  3. 将Object Explorer或查询窗口连接到主副本。
  4. 通过选择会话上下文菜单中的“删除”或执行DROP EVENT SESSION [session-name-here] ON DATABASE;,来在主要副本上删除会话。

只读副本上的事务隔离级别

只读副本上的事务始终使用快照事务隔离级别,无论会话的事务隔离级别是什么,也不管有什么查询提示。 快照隔离使用行版本控制,以避免在读取器阻止写入器的情况下发生阻止。

在极少数情况下,如果快照隔离事务访问另一个并发事务中已修改的对象元数据,则可能会收到错误 3961快照隔离事务在数据库“database-name”中失败,因为该语句访问的对象已由另一个并发事务中的 DDL 语句修改,因为自此事务启动以来, 该语句访问的对象已被另一个并发事务中。不允许使用,因为元数据未进行版本控制。如果与快照隔离混合,则元数据的并发更新可能会导致不一致。

只读副本上的长时间运行的查询

在只读副本上运行的查询需要访问查询中引用的对象的元数据(表、索引、统计信息等)。在极少数情况下,如果在主副本上修改了对象元数据,而查询在只读副本上持有对同一对象的锁定,则查询能会阻止将主副本中的更改应用到只读副本的过程。 如果此类查询长时间运行,会导致只读副本与主要副本明显不同步。 对于那些可能成为故障转移目标的副本(在高级版和业务关键服务层的辅助副本、超大规模 HA 副本和所有地理副本),如果发生故障转移,这将导致数据库恢复时间延长,从而导致比预期更长的停机时间。

如果只读副本上的长时间运行的查询直接或间接导致此类阻塞,则可能会自动终止,以避免数据延迟过多和潜在的数据库可用性影响。 会话收到错误 1219, 会话已断开连接,因为高优先级 DDL操作,或错误 3947,事务因辅助计算未能完成重做而中止。请重试该事务。

由于只读副本上的事务始终使用快照 事务隔离级别,因此,只读副本上的长时间运行的查询可能会阻止主副本上的虚影或永久性版本存储(PVS)清理(如果它读取最近删除的行或较旧的行版本)。 幽灵或 PVS 清理的延迟可能会影响主副本上的工作负载。 有关排查 PVS 清理延迟问题的详细信息,请参阅 监视和排查加速数据库恢复问题

相反,如果只读副本上的长时间运行的查询读取最近删除的行或较旧的行版本,并且这些行或版本可能不再可用于主副本(例如,由于缩放操作),则查询将终止并出现错误3948,事务因可用性副本配置/状态更改而终止,或者主副本和辅助可用性副本上可能需要的虚影记录正在被删除,而这些记录可能是快照隔离下运行的查询所需。重试事务。

注意

如果针对只读副本运行查询时收到错误 3961、1219、3947 或 3948,请重试查询。 或者,避免在主副本上进行修改对象元数据的操作(例如架构更改、索引维护、统计信息更新等),或在对次要副本执行长时间运行的查询时调整主副本。

提示

在高级和业务关键服务层级中,连接到只读副本时,可以使用 redo_queue_size DMV 中的 redo_rate 列来监视数据同步过程,作为只读副本上的数据传播延迟指标。

为 SQL 数据库启用和禁用读取扩展

对于SQL Managed Instance,读取横向扩展在业务关键服务层级上自动启用,在“常规用途”服务层级中不可用。 无法禁用再重新启用读取扩展。

对于 SQL 数据库,“高级”、“业务关键”和“超大规模”服务层默认已启用读取扩展功能。 无法在“基本”、“标准”或“常规用途”服务层级中启用读取扩展。 在配置了 0 个次要副本的“超大规模”数据库上会自动禁用“读取扩展”。

对于Azure SQL Database中的单一数据库和共用数据库,可以使用 Azure 门户和Azure PowerShell在高级或业务关键服务层级中禁用和重新启用读取横向扩展。 这些选项不适用于 SQL 托管实例,因为不能禁用可读性横向扩展。

注意

对于单一数据库和弹性池数据库,禁用读取扩展的功能是出于后向兼容性而提供的。 无法在“业务关键”托管实例上禁用读取扩展。

Azure门户

Compute + storage 数据库窗格中的 设置下,可以管理 Azure SQL Database 的读取扩展设置。 使用 Azure 门户无法启用或禁用 Azure SQL 托管实例的读取扩展功能。

PowerShell

重要

仍支持 PowerShell Azure Resource Manager 模块,但所有未来的开发都适用于 Az.Sql 模块。 Azure Resource Manager (AzureRM) PowerShell 模块不再收到 bug 修复。 Az 模块和Azure Resource Manager模块中命令的参数基本相同。 有关其兼容性的详细信息,请参阅 Introducing the new Azure PowerShell Az module

在 Azure PowerShell 中管理读横向扩展需要 Azure PowerShell 2016年12月版本或更高版本。 有关最新的 PowerShell 版本,请参阅 Azure PowerShell

在 Azure SQL Database 中,可以调用 Set-AzSqlDatabase cmdlet 并传入所需值来禁用或重新启用读扩展。为 -ReadScale 参数指定 EnabledDisabled 即可。 在 SQL 托管实例中禁用读取横向扩展功能是不可用的。

若要对现有数据库禁用读取扩展(请将尖括号中的项替换为环境的正确值,并删除尖括号):

Set-AzSqlDatabase -ResourceGroupName <resourceGroupName> -ServerName <serverName> -DatabaseName <databaseName> -ReadScale Disabled

若要对新数据库禁用读取扩展(请将尖括号中的项替换为环境的正确值,并删除尖括号):

New-AzSqlDatabase -ResourceGroupName <resourceGroupName> -ServerName <serverName> -DatabaseName <databaseName> -ReadScale Disabled -Edition Premium

要对现有数据库重新启用读取扩展(请将尖括号中的项替换为环境的正确值,并删除尖括号):

Set-AzSqlDatabase -ResourceGroupName <resourceGroupName> -ServerName <serverName> -DatabaseName <databaseName> -ReadScale Enabled

REST API

若要创建已禁用读取扩展的数据库,或更改现有数据库的设置,请在将 readScale 属性设置为 EnabledDisabled 的情况下使用以下方法,如以下示例请求所示。

Method: PUT
URL: https://management.chinacloudapi.cn/subscriptions/{SubscriptionId}/resourceGroups/{GroupName}/providers/Microsoft.Sql/servers/{ServerName}/databases/{DatabaseName}?api-version= 2014-04-01-preview
Body: {
   "properties": {
      "readScale":"Disabled"
   }
}

有关详细信息,请参阅数据库 - 创建或更新

在只读副本上使用 tempdb 数据库

主要副本上的 tempdb 数据库不会复制到只读副本。 每个副本具有自身的 tempdb 数据库,该数据库是创建该副本时创建的。 这确保 tempdb 可更新,并可以在执行查询期间进行修改。 如果只读工作负荷依赖于使用 tempdb 对象,则应该在连接到只读副本时,在同一个工作负荷中创建这些对象。

结合使用读取扩展与异地复制的数据库

异地复制的辅助数据库具有与主数据库相同的高可用性体系结构。 如果您连接到已启用读取扩展功能的异地复制辅助数据库,则配置了 ApplicationIntent=ReadOnly 的会话会被路由到一个高可用性副本,与在主要可写数据库上的路由方式相同。 未包含 ApplicationIntent=ReadOnly 的会话将被路由到地理复制次级数据库的主副本,该副本也是只读的。

这样,创建异地副本可以为读写主数据库提供多个额外的只读副本。 其他每个异地副本提供另一组只读副本。 可以在任何Azure区域中创建异地副本,包括主数据库的区域。

注意

异地复制辅助数据库的副本之间没有自动轮循机制或任何其他负载均衡路由,但具有多个 HA 副本的超大规模异地副本除外。 在这种情况下,具有只读意向的会话分布在异地副本的所有 HA 副本上。

只读副本上的功能支持

在 Azure SQL Database 中支持在辅助副本上使用 Query Store。 有关详细信息,请参阅 适用于可读次要副本的查询存储

  • 已自动启用对只读副本的审核。 有关存储文件夹、命名约定和日志格式的层次结构的详细信息,请参阅 SQL 数据库审核日志格式

  • Query Performance Insight for Azure SQL Database 依赖于来自 Query Store 的数据。 查询性能见解does not 当前支持与 replica_group_id 概念相关的 可读辅助数据库的 Query Store 功能。 查询性能分析仪表板中显示的数据将聚合来自所有副本的运行时和等待统计数据。

  • 只读副本支持自动优化功能的自动计划更正组件。 需要启用每个数据库以支持自动计划更正。 有关辅助副本的自动计划修正的详细信息, 请参阅相关内容

  • Azure Monitor中的诊断设置支持通过Azure 诊断设置流式传输 Query Store运行时统计信息。 包括两列来帮助标识遥测数据的副本源:

    • is_primary_b:一个布尔值,该值指示数据源自主副本(true)还是次要副本(false)
    • replica_group_id:对应于副本角色的整数

    在跨副本集分析工作负载时,这些列对于澄清指标和性能数据至关重要。 配置诊断设置以将 Query Store 运行时统计信息流式传输到 Log Analytics、事件中心 (Event Hubs) 或 Azure Storage 时,请确保您的查询和仪表板能够正确划分数据,以便按照副本角色对数据进行分段。