表8显示了主服务器和镜像服务器safety为FULL时的一个事件序列示例。
表8:Safety为FULL (同步传输)事件序列的示例
Server A |
Server B |
Principal, Synchronized |
Mirror, Synchronized |
开始一个包含数据更新的多语句事务 |
|
主数据库的事务日志记录被放入事务日志缓冲区 |
|
事务日志缓冲区内容被写入磁盘(硬化),日志记录块被发送到镜像服务器,主服务器记录日志块的 mirroring_failover_lsn,然后等待镜像服务器的确认。 |
|
|
镜像服务器接收日志记录并放入事务日志缓冲区 |
|
镜像服务器将日志缓冲区输出到磁盘,记录 mirroring_failover_lsn,然后通知主服务器日志块已被硬化 |
主服务器接收日志记录已被镜像服务器硬化到磁盘的通知 |
镜像服务器继续重新执行REDO队列中的事务日志 |
包含了COMMIT的日志写入事务日志缓冲区 |
|
事务日志缓冲区内容被写入磁盘(硬化), 包含了COMMIT的日志记录块被发送到镜像服务器,主服务器记录日志块的 mirroring_failover_lsn,然后等待镜像服务器的确认。 |
|
|
镜像服务器接收日志记录并放入事务日志缓冲区 |
|
镜像服务器将日志缓冲区输出到磁盘,记录the mirroring_failover_lsn,然后通知主服务器日志块已被硬化 |
主服务器接收日志记录已被镜像服务器硬化到磁盘的通知,至此整个事务提交 |
镜像服务器继续重新执行REDO队列中包含了COMMIT的事务日志,修改数据页面 |
新事务被写入主服务器的日志缓冲区 |
|
以上事件序列中关键的一点就是:当 safety设置为FULL时,主服务器硬化日志缓冲区以及将日志缓冲区中日志记录的副本发送到镜像服务器,二者是同时进行的。然后主服务器开始等待自己的I/O以及镜像服务器的I/O,两个I/O都完成后才认为事务完成了。当主服务器接收到来自镜像的答复后,再开始处理下一次硬化。
当safety设置为FULL时,尽管主服务器和镜像服务器之间协调紧密,但是数据库镜像不是分布式事务,也不使用两阶段提交协议。
◆在数据库镜像中,两个事务分别在两台服务器上执行,并不是一个跨服务器的分布式事务。
◆数据库镜像不使用伙伴服务器作为分布式事务中的资源管理器。
◆数据库镜像事务不经历准备和提交阶段。
◆最重要的是,镜像服务器上事务提交失败不会导致主服务器上的事务会滚,这一点与分布式事务不同。
2. 当safety设置为OFF时,主服务器不等待来自镜像服务器的确认消息,因此主服务器上已提交事务数量可能多于镜像服务器,如图9所示:
表9:Safety为OFF (异步传输)事件序列的示例
Server A |
Server B |
Principal, Synchronizing |
Mirror, Synchronizing |
开始一个包含数据更新的多语句事务 |
|
数据更新的事务日志记录被写入事务日志缓冲区 |
|
事务日志缓冲区内容被强制输出到磁盘(硬化),日志记录块被发送到镜像服务器,主服务器记录日志块的 mirroring_failover_lsn |
|
包含了COMMIT的日志被写入事务日志缓冲区,加上其他的事务活动 |
镜像服务器接收日志记录并放入事务日志缓冲区 |
事务日志缓冲区内容被写入磁盘, 包含了COMMIT的日志记录块被发送到镜像服务器 |
镜像服务器将日志缓冲区输出到磁盘,记录the mirroring_failover_lsn,然后通知主服务器日志块已被硬化 |
提交事务 |
镜像服务器继续重新执行REDO队列中的事务日志 |
|
镜像服务器接收日志记录并放入事务日志缓冲区 |
|
镜像服务器将日志缓冲区输出到磁盘,记录the mirroring_failover_lsn,然后通知主服务器日志块已被硬化 |
数据库镜像角色转换
可以从数据库镜像服务器或者应用程序的角度来思考数据库镜像故障转移问题。从数据库镜像服务器角度,故障转移就是将镜像服务器转换为主服务器,以及使用新恢复的数据库作为主数据库。故障转移可以是自动的、手动的、或者forced service。
◆自动的 – 只有高可用模式下才会产生(safety设置为FULL以及见证服务器的参与)
◆手动的 - 只有高可用和高保护操作模式下才会产生(safety设置为FULL),两个伙伴数据库都是SYNCHRONIZED。
◆Forced service (允许数据丢失) - 主要是在高性能模式下(safety OFF)用于立刻和手动的恢复镜像数据库
当safety设置为FULL时,用于互换服务器角色的最好的方式是使用手动故障转移,而不是forced service。
自动故障转移
自动故障转移是高可用模式下(safety为FULL使用见证服务器)数据库镜像的功能。大多数情况下,SQL Server可以在几秒钟内完成自动故障转移。SQL Server可以进行局部自动故障转移,因为包含在数据库镜像会话中的SQL服务器会彼此测试对方的存在。该过程称为“ping”,但包含的操作远不止一个普通的 IP地址ping。镜像服务器和见证服务器联系主服务器以检查主物理服务器是否存在、SQL Server是否存在、以及主数据库是否可用。类似的, 主服务器和见证服务器ping镜像服务器以检查镜像物理服务器和SQL Server实例的可用性,以及镜像数据库的还原状态。
假设使用safety FULL和见证服务器配置了数据库镜像。镜像服务器即Server B通过ping发现主服务Server A不可用。Server B与见证服务器通信并收到见证服务器也看不到Server A的确认消息。那么Server B将和见证服务器组成quorum并将自己提升为主服务器角色。它将恢复它的数据库并且通知见证服务器如今自己担当了主服务器的角色(尽管数据库处于disconnected状态,新主数据库的事务日志也不能被截断)。
Server B的新主数据库继续重新执行事务日志中的活动,但是它将持续redo状态而且大多数情况下只有很少的工作需要完成。在所有SQL Server版本中,新主数据库只要完成redo过程就立刻可用了。当数据库进入undo状态时将可以接收用户连接了。完成redo通常只需几秒钟,尽管余下的undo阶段时间可能很长。在数据库镜像中,新的主数据库只要redo阶段完成就可以为用户连接提供服务。新主服务器B的数据库处于DISCONNECTED状态而且是exposed,但是只要redo过程完成就可以提供数据库服务。
通常将整个应用程序从主服务器重新定向到新主服务器花费的时间要多于数据库镜像的自动故障转移。应用程序必须检测和重试连接,这样也会增加该过程的整体时间。此外,如果将新的SQL Server验证登陆账号添加到服务器,还需要使用系统存储过程sp_change_users_login将这些登陆账户映射到新主数据库的用户账户。如果旧的主服务器上一些关键对象,如SQL Agent作业还没有拷贝到新主服务器上,也会耽误应用程序故障转移的完成。(更多信息请阅读该白皮书实现数据库镜像部分的“为故障转移准备镜像服务器”)
现在假设旧的主服务器联机了。如果是手动故障转移,或者旧的主服务器被快速修复的自动故障转移场景,两台服务器需要进行角色互换,那么就必须进行一个协商过程。在数据库镜像重新开始之前,两台伙伴服务器需要决定彼此怎样进行同步。镜像故障转移lsn这个过程中扮演了一个关键角色。
Server A (新镜像服务器)落后了,但它并不清楚自己落后了多少。Server A向server B(新主服务器)报告它从server B接收的最后的镜像故障转移lsn。另一方面,Server B由于某些提交的工作而导致它有最新的镜像故障转移lsn,server A必须要追赶上server B。Server B将足够数量的事务日志发送给server A,使server A通过重新这些执行事务并与Server B同步。
手动故障转移
手动故障转移就是依次交换两个伙伴服务器的角色。它要求safety设置为FULL,并且主服务器和镜像服务器处于SYNCHRONIZED状态。
在主服务器上使用下面的ALTER DATABASE命令进行手动故障转移:
|
或者在Management Studio的Database Properties/Mirroring对话框中单击Failover按钮。手动故障转移在旧的主数据库上断开所有用户连接并回滚所有未完成的事务。通过完成所有redo队列中已提交的事务,回滚所有未完成的事务(在undo阶段)来恢复镜像数据库。旧的旧的镜像数据库被分配了主数据库角色,而旧的主数据库则担当新的镜像数据库角色。两台服务器根据它们的镜像故障转移lsn协商数据库镜像的新起点,然后处理角色互换。
可以使用手动故障转移作为实现操作系统或者SQL SERVER实例的‘滚动升级’的一种方式来,假如您在初始化镜像服务器之前首先升级镜像服务器。更多信息请参阅SQL Server Books Online中'Manual Failover' 主题。
Forced Service
在镜像服务器上使用ALTER DATABASE命令进行forced Service:
|
通常只有当safety为OFF并且主服务器再也无法运转时才使用这种方式。也可以在safety为FULL使使用该命令,但是如果恢复的镜像服务器无法组成quorum,它也不能提供数据库服务。因此最好在safety为OFF(高性能操作模式)是使用该命令。由于异步的数据传输无法保证镜像数据库包含所有主服务器上提交的最新事务,因此有些数据可能会丢失。
数据库镜像可用性场景
在这一部分,您将根据以下两类事件对数据库镜像预期的可用性结果进行研究:
◆一个或多个服务器或者数据库失败
◆服务器之间一条或多条通信连路失败
服务器失败可能是由于某个镜像伙伴数据库、或者某个SQL SERVER实例不可用。此外,即使服务器本身可以继续运转,但是数据库镜像伙伴服务器之间的通信连路可能中断。
以下场景中,两个组件的同时失败被视为一个组件紧接着另一个组件的顺序失败。例如,Server A和B出现了同时失败,镜像系统将该事件视为一个顺序事件:Server A失败然后Server B失败,或者反过来。
使用下面的规则来判定一个不可用事件的预期结果:
1.当safety设置为FULL时,主服务器需要至少一台其他服务器才能形成quorum来保持数据库可用。
如果主服务器无法组成quorum,也就无法再提供数据库服务了。
2.当safety设置为FULL,如果镜像服务器和见证服务器都无法联系到主服务器,那么镜像服务器可以和见证服务器组成quorum并且改变其角色,使之成为新的主服务器。
这就是自动的故障转移。
3.当safety设置为FULL,如果主服务器和见证服务器合作组成quorum,但是断开了和镜像服务器的连接,那么主服务器失败将不允许镜像服务器和见证服务器组成quorum,也不允许镜像服务器承担主服务器的角色。
这样可以防止所做的工作由于会话中断而丢失。
4.当safety设置为FULL,如果失败的主服务器在停机或者孤立后重新加入会话,同时旧的镜像服务器已经承担了主服务器的角色(和见证服务器组成quorum),那么旧的主服务器将在此次会话中承担新镜像服务器角色。
在故障转移过程中,镜像服务器和见证服务器会增加镜像角色顺序计数器。因为主服务器的镜像角色顺序计数器 小于另一个伙伴服务器和见证服务器的顺序计数器,因此那两台服务器会在旧的主服务器重新加入会话之前组成quorum并开始工作。旧的主服务器担当起镜像的角色。
5.当safety设置为FULL并且会话中没有见证服务器,或者见证不知何故退出了会话,镜像伙伴服务器的失败将导致无法组成quorum,主服务器也因此不再保持主数据库可以使用。
无法组成quorum,因此不可能进行自动的故障转移,如果见证服务器不包含在safety为FULL的会话中。
高可用场景中服务器失败
高可用操作模式下的数据库镜像其目的就是尽可能增加数据库的可用性。在这种模式下,如果主数据库无法访问,那么数据库镜像将迅速使镜像数据库可以接受访问。在下面的一组场景中,我们的讨论将从高可用配置加上三台独立的服务器开始。
在下面的高可用场景中,Server A作为主服务器启动,Server B是镜像服务器,而Server W是见证服务器,如图1所示:
图1:示例数据库镜像会话在高可用操作模式下启动
所有这三台服务器可以在同一个站点使用局域网连接,也可以在不同的站点使用WAN进行连接。Server A和Server B可以互换角色,但是Server W始终作为见证服务器。
现在来考虑如果其中一台服务器出现故障时产生的结果。
场景 HASL1.1:主服务器失败
下面的场景分析了在高可用模式下主服务器失败时会发生什么。图 2显示了不同的角色,以及镜像伙伴之间如何做角色转换。
图2:在高可用模式下,当主服务器Server A失败,故障转移发生
主服务器Server A失败后,镜像和见证服务器组成quorum,自动的故障转移产生。如果重新恢复了原始的主服务器,它将担当起镜像服务器的角色。
注意:要导致高可用模式下的故障转移,失败可以发生在不同的级别上:服务服务器可能停机、主服务器上的SQL SERVER实例可能停止或者失败、服务器上的主数据库可能不可用或状态可疑。在下面场景中,主服务器失败可能由这些事件中的任何一个引起。
因为Server B和W可以组成quorum,并且二者均无法联系Server A,那么Server B可以将自己提升为新的主服务器。但是如果没有镜像服务器,镜像会话就被认为是exposed。
Server A恢复后,它成为新的主服务器,镜像会话也不再是exposed。
单服务器失败事件并不多见,两台服务器失败就更少见了,因此研究在这种情况下出现的结果十分有用。
两台服务器可以同时或者几乎同时失败,但从数据库镜像的角度来看,其结果被视为一台服务器失败紧接着另一台也失败了。因此这些场景只考虑当多台服务器顺序失败时的后果。
接下来的两个场景分析主服务器 Server A失败,紧接着其他两台服务器也失败时会产生的结果。
◆新的主服务器 Server B失败;
◆见证服务器 Server W失败;
场景 HASL1.2:主服务器失败,随后新的主服务器失败
同前面的场景一样,在高可用操作模式下,如果主服务器首先失败,那么故障转移发生。图3显示了如果新的主服务器接下来也失败了,那么无论怎样恢复这些服务器,新的主服务器(Server B)始终保持其主服务器的角色。
图3:由于主服务器失败,接着新主服务器也失败而导致角色转换
Server A失败后,Server B成为新的主服务器,但是无法将数据发送给镜像服务器,因此主服务器处于exposed,即使它仍然提供数据库服务。当Server A失败紧接着Server B也失败,那么就不存在数据库镜像了,因为Server B已经停工了。
如果Server A首先恢复,它从见证服务器的mirroring_role_sequence号中检测到见证服务器已经组成了新的quorum。
Server A接纳了镜像服务器的角色,然后等待Server B恢复。Server B一旦恢复,立刻开始了和Server A的数据库镜像过程。如果Server B先恢复,那么就重新回到了在HASL1。1中显示的初始场景。
注意:如果Server W在Server A和Server B相继失败后也宣告失败,导致所有三台服务器均停工,那么无论以什么次序恢复见证服务器,已经转换完成的Server A和Server B的角色将保持不变。
场景 HASL1.3:主服务器失败,随后见证服务器失败
主服务器失败后发生故障转移。见证服务器可能接下来也失败,如图4所示:
图4:见证服务器紧随原始主服务器出现失败,那么新主服务器无法提供数据库服务
当见证服务器 Server W主服务器 Server A失败后也出现失败,那么新主服务器 Server B依然为主服务器但被孤立,无法组成quorum,也不能提供数据库服务。
如果Server A首先恢复,Server B的mirroring_role_sequence号将比Server A的大1,因为产生了故障转啤U庑┬畔⒅甘維erver A如今Server B在Server A只有担当了主服务器的角色。Server A和Server B组成quorum 并成为一对镜像,此后两台服务器保持同步。除非Server W恢复,否则不会产生自动故障转移。
注意: 如果Server W在Server A和Server B相继之后也宣告失败,那么无论以什么次序恢复见证服务器,已经转换完成的Server A和Server B的角色将保持不变。
场景 HASL2.1:镜像服务器失败
如果镜像服务器首先失败,那么主服务器被视为exposed,因为它无法发送数据给镜像服务器。图 5显示了Server B,即镜像服务器失败时的行为。
图5:在高可用模式下,当镜像服务器Server B失败时不产生故障转移
没有自动故障转移发生,镜像伙伴也不会交换角色。当Server B恢复时,所有三台服务器还原到其初始角色和状态。
下表显示了镜像服务器Server B失败以及恢复时数据库状态。
由于没有镜像服务器,数据无法存放在冗余数据库中,因此会话处于exposed。
Server B一旦恢复立刻重新担当起它的镜像服务器角色。只要两台服务器同步,镜像会话就不再被视为exposed。
接下来的两个场景考虑镜像服务器Server B失败,紧接着主服务器Server A或者见证服务器Server W失败时产生的结果。
场景 HASL2.2:镜像服务器失败,随后主服务器失败
紧随镜像服务器之后主服务器也失败了,镜像伙伴服务器的角色保持不变。图6显示了采用不同方式还原服务器时角色将如何转换。
图6:镜像服务器失败随后主服务器主失败,那么见证服务器被孤立
在Server B和Server A都失败后,各服务器状态显示在图中的右上角处。
如果Server B首先恢复,它将从见证服务器Server W处检测到Server A依然为主服务器并且还没有产生故障转移,mirroring_failover_lsn也没有增加。其结果为,Server B依然为镜像服务器。Server W恢复后将会话还原到初始状态。
注意:如果Server W在Server B和Server A相继失败之后也宣告失败了,那么以任何顺序还原这些服务器将导致相同结果。
场景 HASL2.3:镜像服务器失败,随后见证服务器失败
镜像服务器失败,随后见证服务器也失败,那么主服务器被孤立并且无法和任何其他服务器组成quorum。因此它必须停止数据库的工作,如图7右上角所示。
图7:A镜像服务器失败,随后见证服务器失败,导致主服务器无法提供数据库服务
由于镜像服务器故障以及随后的见证服务器失败,主服务器 Server A保持其主服务器角色,由于无法和任何其他服务器组成quorum,而safety又被设置成FULL,因此不再为数据库提供服务,并断开所有的用户连接。
如果Server B首先恢复,那么数据库镜像将重新开始工作,尽管由于缺失见证服务器而不会产生自动故障转移。
如果Server W首先恢复,那么情况与图5中显示的一样。
注意:如果Server A在Server B和Server W相继失败之后也宣告失败,那么以任何次序还原这些服务器其最终结果保持不变。
场景 HASL3.1:见证服务器失败
见证服务器失败时,数据库镜像继续进行但是不可能产生自动的故障转移。如果再有一台或多台服务器失败,就意味着没法组成quorum,那么主服务器上的数据库也不再服务于数据库用户。
图8:在高可用模式下,见证服务器Server W首先失败,那么数据库镜像继续
Server W恢复后,两个伙伴服务器Server A和Server B维持它们的初始角色。
下表显示了见证服务器失败以及恢复后,数据库状态以及quorum的变化。
下面的两个场景考虑见证服务器Server W失败,紧接着主服务器 Server A或者镜像服务器Server B失败时产生的结果。
场景 HASL3.2:见证服务器失败,随后主服务器失败
见证服务器首先失败,那么数据库镜像将继续进行,但是不可能产生自动的故障转移。其余两台服务器中任何一台失败将导致无法组成quorum,余下的那台服务器将被孤立。
图9:原始见证服务器失败,随后主服务器失败,镜像伙伴角色保持不变
如果Server W首先恢复,那么Server B将从见证服务器那里检测到最后的主服务器是Server A,同时Server B依然是镜像服务器。最终Server A恢复时,它将保持其主服务器角色。
注意: 如果Server B在Server W和Server A相继失败后也宣告失败了,那么以任意次序还原这些服务器都不会影响最终结果。
场景 HASL3.3:见证服务器失败,随后镜像服务器失败
如果见证服务器失败,随后镜像服务器也失败,那么主服务器被孤立。由于safety设置为FULL并且主服务器无法组成quorum,它将不再提供数据库服务,如图10所示。
图10:见证服务器失败,随后镜像服务器失败,主服务器必须停止其数据库服务
注意: 如果Server A在Server W和Server B相继失败之后也宣告失败, 那么以任意次序还原这些服务器都不会影响最终结果。
总结:高可用场景中服务器失败
从这些场景中可以得出几个结论。在高可用操作模式下:
1.如果主服务器首先不可用,那么产生自动的故障转移,原先的镜像服务器将担当主服务器角色,并使其数据库服务于用户活动。后续的服务器失败和恢复不会影响使用新主服务器的数据库镜像的整体配置。数据库镜像将以相反的方向继续进行。
2.如果镜像首先不可用,那么产生自动的故障转移 。后续的服务器失败以及恢复次序都不会影响镜像伙伴角色。
3.如果见证服务器首先不可用,那么不可能产生自动的故障转移,镜像伙伴服务器将保持其初始角色。后续的服务器失败以及恢复都不会影响镜像伙伴角色。
下表总结了在高可用场景中出现一台或两台服务器失败时产生的结果。表中假设的条件是safety设置为FULL并且镜像会话中的服务器满足下列条件:
A:主服务器, SYNCHRONIZED
B:镜像服务器,SYNCHRONIZED
W:见证服务器,CONNECTED
表中使用灰色加亮显示故障转移场景。
表10:总结:单服务器或者双服务器失败,显示伙伴服务器角色和数据库状态
高可用场景中通信失败
高可用操作模式需要三个SQL Sever实例。如果这些服务器位于两个或三个独立的物理站点并且相距很远,那么这些站点间的通信就很可能出现问题。换句话说,服务器依然运转但是彼此间的通信连路中断了。这种情况比前面的那些场景要复杂一些,但原理是一样的。
下面高可用操作场景中通信失败的研究将通过两组来完成。第一组是基于三个来自不同站点的SQL SERVER实例,因此有三条独立的通信连路。第二组是基于两个独立站点上的服务器,第一个站点上的一对服务器和第二个站点上的第三台服务器之间有一条通信连路。
先从第一组开始,假设一个数据库会话中所有三台服务器之间有三条独立的通信连路。例如,主服务器、镜像服务器和见证服务器位于三个独立的协作站点上(也有可能三台服务器位于同一个站点,但使用私有网络连接)
初始条件是Server A上运行主数据库并且与其镜像伙伴Server B保持同步。
Server B上是镜像数据库Safety设置为FULL,见证服务器 (Server W)也包含在数据库镜像会话中。图11显示了初始配置。
图11:高可用配置中三台独立服务器、三条独立通信连路的初始状态
注意:要获得页面上图表的解释,请参阅前面介绍的“高可用场景中服务器失败”
根据图11,三条链路可能首先中断:A/B, A/W和B/W。注意当某条通信连路中断时,所有三台服务器依然运转正常。只有主服务器和镜像服务器之间的通信连路有一些影响,如表11所示。
表11:总结:单条通信连路中断
初始条件 |
事件 |
Quorum |
结果 |
条件 |
A: 主服务器, SYNCHRONIZED B: 镜像服务器, SYNCHRONIZED W: 见证服务器, CONNECTED |
A/B连路中断
|
A和W |
A上的数据库提供服务, exposed |
A: 主服务器, DISCONNECTED B: 镜像服务器, DISCONNECTED W: 见证服务器, CONNECTED |
A/W |
A和B |
A上的数据库提供服务 |
A: 主服务器, SYNCHRONIZED B: 镜像服务器, SYNCHRONIZED W: 见证服务器, CONNECTED |
|
B/W |
A和B |
A上的数据库提供服务 |
A: 主服务器, SYNCHRONIZED B: 镜像服务器, SYNCHRONIZED W: 见证服务器, CONNECTED |
场景 |
第一条连路中断 |
场景 |
第一条连路中断 |
结果 |
其余服务器的等价场景 |
参阅场景 |
HACL1.1 |
A/B |
HACL1.2 |
A/W |
Server A被孤立 |
Server A停机 |
无 |
|
|
HACL1.3 |
B/W |
Server B 被孤立 |
Server B 停机 |
HASL2.1 |
HACL2.1 |
A/W |
HACL2.1 |
A/B |
Server A 被孤立 |
Server A 停机 |
HASL1.1 |
|
|
HACL2.2 |
B/W |
Server W 被孤立 |
Server W 停机 |
HASL3.1 |
HACL3.1 |
B/W |
HACL3.1 |
A/W |
Server W 被孤立 |
Server W 停机 |
HASL3.1 |
|
|
HACL3.2 |
A/B |
Server B 被孤立 |
Server B 停机 |
HASL2.1 |