使用 AlwaysOn 可用性组只读辅助副本执行事务日志备份 - 第 1 部分

发布时间 2023-07-29 12:14:32作者: 雪竹子

什么是日志序列号 (LSN)?

在对 AlwaysOn 可用性组进行故障排除时,有多个 DMV 引用各种 LSN(日志序列号)。此外,备份和恢复操作经常引用并输出LSN值。

那么什么是LSN呢?LSN 是一个序列号,用于维护数据库内的顺序和跟踪操作。LSN 可以是十进制形式或十六进制形式,具体取决于引用它的位置。大多数 DMV 引用十进制格式的 LSN。LSN 的十进制格式由三个串联的
信息组成。这三块分别是(从左到右):

  • VLF 序列号:最多 10 位数字(4 字节),不带前导零。(VLF = 虚拟日志文件。有关详细信息,请参阅事务日志物理体系结构)。
  • 日志块编号:10 位十进制数字(4 字节),以前导零填充。
  • 日志记录编号:5 位十进制数(2 个字节),带前导零

 

十六进制格式只是用冒号 (:) 分隔的每个部分(VLF、日志块号和日志记录号)的十六进制表示形式。例如:十进制的 34 是十六进制的 22,十进制的 156 是十六进制的 9C,十进制的 65 是十六进制的 41。因此,以十进制表示的 34000000015600065 表示的 LSN 在十六进制中将显示为 22:9C:41。

什么是日志块?

在上一节中,LSN 的定义被提到为 VLF(虚拟日志文件)、日志块号和日志记录号的组合。什么是“Lob 块”以及什么是“日志记录”?就本文而言,日志块是一起写入磁盘的日志记录的集合。“日志记录”是 SQL 引擎内活动的单个原子记录。“日志记录”、“日志块”和虚拟日志文件(VLF)之间的关系如下:

  • VLF 由 1 个或多个日志块组成,每个日志块都是 512 字节的整数倍,但总大小不超过 60KB。
  • 一个日志块由1个或多个日志记录组成。日志块可以与数据文件中的数据页进行比较,其中包含带有元数据信息的标头、槽数组、“数据”(日志记录)以及从 Microsoft SQL Server 2005 开始的校验和。
  • 最后,日志记录是事务日志文件中的最小单元,包含数据库中活动记录的信息。下图显示了物理日志文件、虚拟日志文件、日志块和日志记录之间的关系。

 

 

现在是时候查看一个重要的 DMV 来检查数据库副本的当前状态。这与数据库备份的关系将在本系列的第二部分“描述 ROSR 上的日志备份过程”中更加清楚。目前,DMV 中有很多值得关注的内容。

sys.dm_hadr_database_replica_states

 

DMV sys.dm_hadr_database_replica_states有几个列的名称中包含“LSN”,这些列有助于解决处理 AlwaysOn 复制的问题。尽管这些字段的名称中带有“lsn”,但事实上,它们并不都是真正的LSN。在上表列出的LSN中,只有last_redone_lsnend_of_log_lsn是真正的LSN。其他的实际上是日志块ID。

下图描述了查看主副本和相应辅助副本时这些“LSN”值之间的关系。点“B”、“C”和“E”指向日志块本身,表示这些值是日志块 ID。相反,点“A”和“D”指向日志记录并代表真实的LSN。

 

 

 

正如博客AlwaysON - HADRON 学习系列:- AlwaysON 如何处理同步提交请求 中所述,AlwaysOn 不传送单个日志记录,而是传送日志块。日志块用作日志记录的容器,因此通过日志块跟踪,也会发生单独的 LSN 跟踪。此外,值得注意的是,last_hardened_lsn是一个“刷新 LSN”,这意味着它代表已存储在稳定介质上的块之后的下一个块的开始。换句话说,小于last_hardened_lsn的LSN值已被保存到稳定介质中。任何大于或等于last_hardened_lsn值的LSN 尚未被刷新。

结合到目前为止讨论的所有内容,我们现在可以查询sys.dm_hadr_database_replica_states并开始分析获得的信息。

在充当主副本的实例上,执行以下查询:

SELECT ar.replica_server_name as ServerName,
 drs.synchronization_state_desc as SyncState,
 drs.last_hardened_lsn, drs.last_redone_lsn
FROM sys.dm_hadr_database_replica_states drs
LEFT JOIN sys.availability_replicas ar 
 ON drs.replica_id = ar.replica_id
ORDER BY ServerName

  

您应该看到类似于以下内容的结果:

在此结果集中,有几个因素可以确定。

首先,LC2SQLAOLB1 充当主副本。我们知道这一点是因为last_redone_lsn是NULL。REDO 操作仅发生在辅助副本上。(我们也可以通过与其他DMV 合作来明确其角色来确定这一点。

其次,查看所有三个服务器的last_hardened_lsn值,我们发现它们是相同的。为了使同步状态为“SYNCHRONIZED”,主节点和辅助节点都必须配置为“SYNCHRONOUS COMMIT”,并且提交策略处于“ WaitForHarden ”状态,这意味着辅助节点已通知主节点它已硬化到结束日志并被“捕获”。然而,从 DMV 的视觉效果来看,我们通常会看到last_hardened_lsn是相同的 - 尽管取决于有多少活动以及 DMV 是否拥有来自辅助设备的所有最新确认,辅助设备可能“不完全”是查询 DMV 时也是如此。

另一方面,LC2SQLAOLB3 配置为异步提交,因此即使其last_hardened_lsn与主副本相同,其状态也永远不会是 SYNCHRONIZED,而是 SYNCHRONIZING。换句话说,即使 LC2SQLAOLB3 将所有日志记录作为主日志记录,它也永远不会处于 SYNCHRONIZED 状态。

最后,比较last_redone_lsnlast_hardened_lsn的值,我们发现last_redone_lsn小于last_hardened_lsn从我们之前对LSN各个部分的讨论中,我们可以看到last_hardened_lsn (块ID:0000066325)比last_redone_lsn( 0000066324)领先一个块。
请记住,根据定义,last_hardened_lsn是一个“flush lsn”,指向已写入稳定介质的下一个块。

总之

本文试图解释几个基础点,这些基础点将使后续对辅助副本上的日志备份的研究更容易理解。LSN 由三个连接在一起的部分组成:

  • 虚拟日志文件序列号
  • 日志块ID号
  • 日志记录数

在主副本上执行时,DMV sys.dm_hadr_database_replica_states 可用于显示各个辅助副本的状态。此外,为了使辅助副本同步,必须将其配置为同步提交,并且 last_hardened_lsn必须是

与初级相同。对于配置为异步提交的辅助副本,即使它具有相同的last_hardened_lsn值,它也永远不会处于 SYNCHRONIZED 状态。

最后证明,即使辅助副本 LC2SQLAOLB2 已同步,last_redone_lsn仍比last_hardened_lsn小一个日志块 ID 。这是因为last_hardened_lsn不是真正的LSN,而是一个“刷新LSN”,根据定义,它指向已写入稳定介质的日志记录之后的下一个日志块ID。