错误 9002:由于 SQL Server 中出现 AVAILABILITY_REPLICA 错误消息,数据库的事务日志已满

本文可帮助你解决当事务日志变大或耗尽 SQL Server 空间时发生的 9002 错误。

原始产品版本: SQL Server 2017、SQL Server 2016、SQL Server 2014、SQL Server 2012
原始 KB 数: 2922898

现象

假设出现了下面这种情景:

  • 已在服务器上安装Microsoft SQL Server 2012 或更高版本。
  • SQL Server 实例是 AlwaysOn 可用性组环境中的主要副本。
  • 事务日志文件的自动增长选项在 SQL Server 中设置。

在此方案中,事务日志可能会变得很大,磁盘空间不足,或者超出了 在主副本上为事务日志设置的 MaxSize 选项,并且你收到类似于以下内容的错误消息:

错误:9002,严重性:17,状态:9。 由于“AVAILABILITY_REPLICA”,数据库 '%.*ls' 的事务日志已满

原因

当主要副本上的记录更改尚未在次要副本上强化时,将发生这种情况。 有关 AlwaysOn 环境中数据同步过程的详细信息,请参阅数据同步时间化过程

故障排除

有两种情况可能导致可用性数据库中的日志增长和 'AVAILABILITY_REPLICA' log_reuse_wait_desc

  • 方案 1:将记录的更改传送到辅助数据库的延迟

    当事务更改主副本中的数据时,这些更改会封装到日志记录块中,这些记录块将传送并强化到次要副本上的数据库日志文件。 在将日志块传递到所有辅助副本中的相应数据库日志文件之前,主副本无法覆盖其自己的日志文件。 在将这些块传送或强化到可用性组中的任何副本时,任何延迟都会阻止在主副本的数据库中截断这些记录的更改,并导致其日志文件使用量增加。

    有关详细信息,请参阅 高网络延迟或低网络吞吐量导致主副本上的日志生成。

  • 方案 2:恢复延迟

    强化到辅助数据库日志文件后,辅助副本实例中的专用重做线程会将包含的日志记录应用到相应的数据文件(s)。 在所有次要副本中的所有重做线程都已应用包含的日志记录之前,主副本无法覆盖其自己的日志文件中的日志块。

    如果任何次要副本上的重做操作无法跟上在该次要副本上强化日志块的速度,则会导致主副本的日志增长。 主副本只能截断并重复使用其自己的事务日志,直到所有辅助副本的重做线程都已应用。 如果有多个辅助数据库,请比较 truncation_lsn 多个辅助数据库之间的动态管理视图列 sys.dm_hadr_database_replica_states ,以确定哪个辅助数据库延迟日志截断最多。

    可以使用 AlwaysOn 仪表板和 sys.dm_hadr_database_replica_states 动态管理视图来帮助监视日志发送队列和重做队列。 一些关键字段包括:

    字段 说明
    log_send_queue_size 未到达次要副本的日志记录量
    log_send_rate 将日志记录发送到辅助数据库的速率。
    redo_queue_size 尚未重做次要副本的日志文件中的日志记录量(KB)。
    redo_rate 在给定辅助数据库(KB)/秒内重新创建日志记录的速率。
    last_redone_lsn 在辅助数据库上重做的上一个日志记录的实际日志序列号。 last_redone_lsn 始终小于 last_hardened_lsn
    last_received_lsn 标识承载此辅助数据库的辅助副本已接收所有日志块的点的日志块 ID。 反映用零填充的日志块 ID。 这不是实际的日志序列号。

    例如,对主副本执行以下查询以报告最早 truncation_lsn 的副本,并且是主副本可以在其自己的事务日志中回收的上限:

    SELECT ag.name AS [availability_group_name]
    , d.name AS [database_name]
    , ar.replica_server_name AS [replica_instance_name]
    , drs.truncation_lsn , drs.log_send_queue_size
    , drs.redo_queue_size
    FROM sys.availability_groups ag
    INNER JOIN sys.availability_replicas ar
        ON ar.group_id = ag.group_id
    INNER JOIN sys.dm_hadr_database_replica_states drs
        ON drs.replica_id = ar.replica_id
    INNER JOIN sys.databases d
        ON d.database_id = drs.database_id
    WHERE drs.is_local=0
    ORDER BY ag.name ASC, d.name ASC, drs.truncation_lsn ASC, ar.replica_server_name ASC
    

    纠正措施可能包括,但并不限于以下各项:

    • 确保辅助数据库没有资源或性能瓶颈。
    • 确保恢复线程未在辅助数据库上被阻止。 lock_redo_blocked使用扩展事件确定何时发生,以及重做线程被阻止的对象。

解决方法

确定导致此问题的辅助数据库后,请尝试以下一个或多个方法暂时解决此问题:

  • 将数据库从可用性组中取出,以获取有问题的辅助数据库。

    注意

    此方法将导致辅助数据库的高可用性/灾难恢复方案丢失。 将来可能需要再次设置可用性组。

  • 如果重做线程经常被阻止,则通过将副本的参数SECONDARY_ROLE更改为 ALLOW_CONNECTIONS NO 来禁用Readable Secondary该功能。

    注意

    这将阻止用户读取次要副本中的数据,这是阻止的根本原因。 重做队列降至可接受的大小后,请考虑再次启用该功能。

  • 如果禁用了自动增长设置,并且有可用的磁盘空间,请启用自动增长设置。

  • 如果已达到事务日志文件的 MaxSize 值,并且有可用的磁盘空间,则增加该值。

  • 如果当前事务日志文件已达到系统最大 2 TB 或其他可用卷上可用空间,则添加其他事务日志文件。

详细信息

适用于

  • SQL Server 2012 企业版
  • SQL Server 2014 Enterprise
  • SQL Server 2014 Business Intelligence
  • SQL Server 2014 Standard
  • SQL Server 2016 Enterprise
  • SQL Server 2016 Standard
  • SQL Server 2017 Enterprise
  • SQL Server 2017 标准 Windows