在这种奇怪的 SQL Server 镜像情况下会发生什么?

usr*_*usr 6 sql-server mirroring availability-groups

假设两个 SQL Server 实例(S1 和 S2)处于同步镜像或同步可用性组中。现在发生以下情况:

  1. 写入发生在 S1 上,事务提交由客户端发起
  2. 写入已在 S2 上硬化(但尚未在 S1 上硬化
  3. S1 掉电,提交日志记录永不写入
  4. S2 断电(交易已经硬化)
  5. S1 启动并撤消事务
  6. S2启动并保持交易

现在 S2 更进一步了!它有一个 S1 没有的写操作。两个复制品已经分道扬镳。

在这种情况下会发生什么?当更多写入到达 S1 并将 S1 带入与 S2 不兼容的历史时会发生什么?写历史看起来像一个叉子。

小智 6

首先,我应该说一个很好的问题 usr。Sean、Robert 和 Max 都正确地声明,由于主要和次要之间的重新协商,正确的 LSN 始终得到解决,因此在这种情况下不可能出现任何差异。

为了回应与 Shanky 的讨论,在同步模式下,提交首先必须发生在镜像上(正如您正确假设的 usr),这确实意味着必须将日志写入(分别将日志缓冲区刷新到磁盘提交时)。请记住,这仅意味着日志文件已将事务强化到它,但在此阶段,事务仍将“在重做队列中”。这允许非常快速地提交到镜像,这意味着在主节点上的提交也可以在之后非常快地发生 - 这从而进一步降低了首先出现差异的可能性。

另一件要考虑的事情是,如果您使用延迟持久性,这会进一步改变机制,并且实际上可能导致整个镜像数据库丢失事务(由于日志缓冲区刷新行为的变化 - 不再刷新在提交时),但仍然可以在两者之间进行解析以找到正确的 lsn 点。


Sha*_*nky 2

我正在谈论数据库镜像,因为我不确定这个讨论是否适用于我认为适用的 AG。我正在谈论同步镜像,据我所知,实际发生了以下情况

假设在数据库主体上启动 DML 时会发生以下情况

1.来自DML事务的事务日志记录将被插入到事务日志缓冲区中。

2.然后,事务日志缓冲区将被写入已硬化的磁盘,同时日志缓冲区将被发送到镜像服务器,主体将等待镜像服务器的确认。

请注意,日志缓冲区中的事务尚未提交

3.镜像将在其事务日志缓冲区中接收日志记录,并将其写入磁盘并通知主体它已硬化该日志记录

4.Principal将收到确认,然后事务的COMMIT将被输入到日志记录缓冲区中

正如你所看到的,现在事务的提交被输入到日志缓冲区并被强化,但 SQL Server 仍然不确认这是已提交的事务

5.现在将遵循与上面相同的提交过程,它将被硬化到磁盘,并且包含提交的日志记录将被发送到镜像,然后它将硬化它发送确认并重放事务日志。

现在事务已实际提交

下面我不同意

写入已在 S2 上硬化(但尚未在 S1 上硬化)

你必须说提交而不是硬化。就像我上面所说的,包含提交的日志记录的强化首先在主体上完成,同时将其发送到镜像,但只有在主体从镜像接收到包含提交的日志记录的信息后,事务实际上才被视为已提交它发送到镜像的内容已被硬化。它还记录镜像故障转移 LSN,然后向主体发送确认。

委托人等待自己的 I/O 和镜像的 I/O 完成后才认为事务完成。当主体收到来自镜像的响应时,主体就可以进行下一次强化。

S1断电并且提交日志记录永远不会被写入

不,这个 IMO 不是正确的推论,就像我上面所说的,在发送包含提交主体的日志记录之前,首先将其硬化到磁盘上。如果 SQL Server 没有收到来自镜像的确认,则不会回滚事务,事务仍将打开

非常重要的一点是,在镜像上提交失败不会导致主体上的事务回滚。

我希望您阅读此链接中的表 9 部分

  • 肖恩在这里是正确的。每当合作伙伴离线时,当其重新上线时,合作伙伴都会比较其日志文件并同步它们。在镜像恢复之前,提交将始终在两个伙伴上回滚或提交。 (4认同)
  • @usr,问题是您假设当数据库启动备份时主体和镜像之间没有发生任何协商。协商将会发生,并且数据库将在 LSN 上“达成一致”。在您的情况下,不会向客户端发送成功,数据库将协商一个起点,并且它将继续进行。客户端认为连接被切断并且事务丢失,所以一切都在同一个地方。 (2认同)
  • @usr - 有一种回滚的方法,日志就在那里。我不知道具体细节,但谈判确实发生了。在“大多数”情况下,由于额外的线路时间,S2 不会在 S1 之前提交,但在极少数情况下,“可以”有内置机制来处理它。现在,如果您说写入发生在 S2 上,并且在 S1 上硬化之前立即进行手动故障转移,导致数据丢失,那么您的问题就会发生巨大变化。在“那种”情况下,这些值将存在于 S@ 上,并且当 S1 恢复时,将协商 LSN,并且如果可能的话,镜像将赶上。 (2认同)