SQL Server 2012 新一代的高可用技术AlwaysOn 之五 AlwaysOn的故障转移形式

前面我们介绍了AlwaysOn是如何实现副本之间的数据同步的。那它的另一大功能:故障转移又是怎么实现的呢?

首先,来了解下AlwaysOn是如何发现可用性组出现问题的。

由于AlwaysOn可用性组是建立在Windows故障转移群集之上的,因此和SQLServer群集类似的,AlwaysOn可用性组也需要一个群集resourceDLL来连接Windows群集和SQLServer实例。由于可用性组是一个群集资源,Windows群集需要透过AlwaysOnresourceDLL来控制资源的上线/离线,检查资源是否失败,更改资源的状态和属性,以及发生各种命令给可用性副本实例。你可以透过故障转移群集管理器查看可用性组资源的各种属性。

 

AlwaysOn可用性组的资源类型是“SQLServer Availability Group”,该资源类型使用的resourceDLL的叫做hadrres.dll,在hadrres.exe中定义了如何对AlwaysOn可用性组经行Isalive检查的方法。和SQLServer群集的resourceDLL sqsrvres.dll)一样,hadrres.dll也是由群集的RHS.exe进程加载的。由于AlwaysOn可用性组使用的是非Windows群集自带的资源类型和resourceDLL,默认情况下Windows群集单独产生一个RHS.exe来专门加载hadrres.dll。这样即使该RHS.exe由于异常而崩溃,整个群集的其他资源也不会受到影响。

那么AlwaysOn可用性组是如何执行Isalive检查来判断它的健康状况的呢?还记得之前讲到过SQLServer 2012群集使用了存储过程sp_server_diagnostics来进行群集的健康检查吗?其实Always也是使用了sp_server_diagnostics来检查可用性组的健康状况。Hadrres.dll会建立并保持一个连接到SQLServer,并通过这个连接运行sp_server_diagnostics,然后不断的获得诊断信息。sp_server_diagnostics的评估结果会被用来和AlwaysOn可用组的FailureConditionLevel设置向比较,来约定是够符合发生故障转移的条件。一旦条件满足,则可用性组就被切换到新的可用性副本上。更多关于sp_server_diagnostics存储过程的介绍,你可以参考第二章。

有几点需要注意的是:

1.      可用性组也是一种群集资源,但是它的HealthCheckTimeout属性默认是30000毫秒,而不像群集资源那样是60000毫秒。所以可用性组的获取诊断信息并记录到扩展事件日志的频率更高。

2.      无论你在一个实例上配置多少个可用性组,该实例上只会运行一条sp_server_diagnostics语句来诊断所有的可用性组。如果每个可用性组的HealthCheckTimeout设置不同,hadrres.dll会挑选最小的那个值并除以3来作为sp_serevr_diagnostics返回诊断信息的间隔(max(5, min(HealthCheckTimeout/3)))。这个最小的HealthCheckTimeout值被称为“有效HealthCheckTimeout”。

3.      Sp_server_diagnostics只是检测实例的健康状态,而不是检测每个数据库的状态。所以如果当前SQL Server实例还能正常工作,但可用性组所包含的数据库发生诸如数据文件损坏、置疑等问题而不能被正常使用,sp_server_diagnostics是无法发现问题的。就算你为当前的可用性副本配置了自动故障转移,这种情况下也是不会触发故障转移的。

Windows群集触发故障转移后,故障转移目标(原先的辅助副本)能够接管主副本角色,恢复自己管理的数据库,使它们作为新的主数据库。原先的主副本如果在故障转移后还可用的话,就会成为辅助副本,它上面的数据库就成为了辅助数据库。

AlwaysOn发现故障之后,是否会立刻触发故障转移呢?这取决于可用性副本的可用性模式和故障转移模式。

根据副本间数据同步的模式,可用性模式有两种:同步提交和异步提交。根据故障转移的方式,可用性副本也有两种故障转移模式:自动故障转移和手动故障转移。自动故障转移模式只有当副本的可用性模式为“同步提交”时才可以选择。

可用性模式和故障转移模式的组合形成了可用组的三种故障转移形式:自动故障转移、计划的手动故障转移(通称为“手动故障转移)、强制手动故障转移(通称为“强制故障转移”)。

 

需要注意的是,故障转移形式是由主副本和故障转移目标两者的模式所共同决定的。两个副本间要能发生自动故障转移,需要两者都配置为同步提交模式+自动故障转移模式。两者中有一个配置了手动故障转移,则自动故障转移就不能发生。两者间有一个配置了异步提交模式,则它们之间就只能发生强制故障转移。

三种故障转移形式中,只有强制故障转移可能会丢失数据。自动故障转移和手动故障转移会保证数据的安全。为了防止丢失数据,自动故障转移和手动故障转移都要求故障转移目标是使用同步提交模式的辅助副本且当时处于SYNCHRONIZED状态。如果已处于SYNCHRONIZED状态的辅助副本发出强制故障转移命令,其行为与手动故障转移时的行为相同。对于异步提交模式的辅助副本,无论数据是否已经达到同步,它永远只会处于 SYNCHRONIZING状态,于是它只能支持强制故障转移这一种形式。

自动故障转移形式

自动故障转移使得AlwaysOn可用组成为了一种高可用方案,确保在丢失主副本之后快速使数据库再次变为可用。要发生自动故障转移,要满足这些条件:

·        当前主副本和一个辅助副本都设置为同步提交模式以及自动故障转移模式。

·        辅助副本必须与主副本同步。即辅助数据库处于SYNCHRONIZED状态.

·        主副本变得不可用,此时将发生自动故障转移。

当发生自动故障转移时,整个步骤是:

1.       如果运行当前主副本的副本实例仍在运行,则它会将主副本和辅助副本的连接状态更改为 DISCONNECTED 并断开所有客户端的连接。

2.       如果在故障转移目标副本上还有任何日志记录处于重做队列中,辅助副本会继续执行重做,以完成对辅助数据库的前滚操作。

3.       完成前滚操作后,辅助副本就转换为了主副本,其数据库成为了主数据库。新的主副本将尽快回滚任何未提交的事务。

4.       新的主副本在连接到一个辅助副本形成新的对话之前,会把自己置为 NOT SYNCHRONIZED状态。无论回滚操作是否已经结束,只要有辅助副本可以连接到新的主副本,主数据库就会转换为 SYNCHRONIZED 状态。

5.       当原来的主副本解决了故障重新开始运行后,它会发现其他某个可用性副本现在变成了主副本,于是它就把自己转换为辅助副本,将其数据库将成为辅助数据库。当新的辅助数据库连接上新的主数据库后,辅助数据库就开始进行同步来赶上主数据库的日志末尾。

手动故障转移形式

当主副本和辅助副本连接在一起并且数据库处于SYNCHRONIZED状态,就可以执行手动故障转移。如果辅助副本停止运行,主副本不会受到影响。如果主副本停止运行,辅助副本将进入一种特殊的角色 –“ RESOLVING”角色(注意,RESOLVING是可用性副本的一种角色,而不是它所处的状态)。此时该副本既不是主副本也不是辅助副本,但你可以执行强制故障转移把辅助副本转换成主副本,不过你可能会因此承受数据损失。

当发生手动故障转移时,整个步骤和自动故障转移基本是一样的。它们的区别仅仅是在“谁触发了故障转移”。

你有四种途径来执行手动故障转移:

1.      通过Windows的故障转移群集管理器来切换可用性组所在的资源组

2.       通过T-SQL语句

3.       通过SQL Server ManagementStudio使用UI来进行手动故障转移。

4.       使用Powershell脚本。

只有设置为自动故障转移模式的可用性副本才允许通过Windows的故障转移管理器来切换主副本所在的实例。如果辅助副本没有设置自动故障转移模式,那么你只能使用其余三种途径来执行手动故障转移。

 

强制故障转移形式

从数据安全的角度来讲,强制故障转移是一个风险很大的操作。一旦执行了强制故障转移,主副本尚未发送到原来的辅助副本的任何事务日志都会丢失。这意味着,新的主数据库可能会缺少一些最近提交的数据。需要特别注意的是,强制故障转移后,剩余的所有辅助副本上的辅助数据库都处于挂起状态。在最坏的情况下,你可能需要重新初始化所有的辅助副本才能重新恢复可用性组。举例来说,假设你有三个可用性副本,主副本A和一个辅助副本B是同步提交模式,另一个辅助副本C是异步提交模式。当主副本A和辅助副本B的日志都比辅助副本C更加新的时候(这很容易发生),你执行了强制故障转移把主副本转移到C上。于是新的主副本C的日志晚于其余两个副本,这使得副本AB无论如何都无法继续和副本C的对话。要重新恢复三个副本的配置,你必须以某个副本上的数据库为基础,重新在三个副本上配置可用性组。

你只能通过SQLServer Management Studio来执行强制故障转移。在转移开始前,SQLServer Management Studio会通过向导来和你确认你是否已经了解且愿意接受强制故障转移可能带来的后果。

 

多子网可用性组的故障转移

可用性组支持多子网环境,即可用性副本可以处于不同的子网当中。在2.2.5节介绍过,多子网的SQLServer群集一旦发生了故障转移,为了使得客户端能够更快的重新连接到新的活跃节点,你可以在连接字符串中使用MultiSubnetFailover参数并将其置为true。对于多子网的可用性组而言,在客户端程序中使用MultiSubnetFailover参数也能帮助客户端在可用性组发生不同子网间的故障转移时快速的恢复连接。要使用MultiSubnetFailover参数,除了客户端要使支持该参数的驱动程序之外,你还必须要使用TCP协议并通过Listener来连接可用性副本。

无论可用性组是单子网还是多子网,都建议在客户端的连接字符串中将MultiSubnetFailover设置为true。对于单子网的环境,MultiSubnetFailover能够为迁移至多子网环境做好预先准备。一旦发生这样的迁移,你无需再去更改连接字符串。

Split Brain(大脑分裂)

在理论上,如果发生故障转移,原先的主副本会先离线,然后某个辅助副本会上线。网络里不会同时出现两个主副本。但是在意外情况下,如果原先的主副本还没有离线,新的主副本就上线了,那一个可用组就出现了两个主副本。客户端可以连接其中的任何一个,做数据修改动作。就像人的大脑,被分裂成了两个。所以这种情况被起名为SplitBrain(大脑分裂),是AlwaysOn要坚决杜绝的。所以在可用性组资源的属性中,你还能看到一个叫做LeaseTimeout的属性。Windows群集服务会定期跟它认为的主副本通信。如果主副本在”LeaseTimeout”之前没有收到Windows群集服务的消息,它就自认为自己已经被群集服务切换掉了。这个SQLServer会自动终止自己的运行。因为Windows群集服务在任何一个时间点只会认定一个主副本,所以这样的方法可以避免“大脑分裂”。

连接、可用性副本和可用性数据库的状态

在前面的介绍中,你会发现AlwaysOn中的各种对象在不同的情况会处于各自不同的状态。如果你已经眼花缭乱的话,这里我们做一个小小的归纳。

连接状态:

·        Disconnected – 说明辅助副本和主副本间已经断开了连接。

o   如果主副本发现辅助副本断开了和它的连接,在主副本上会将那些辅助副本上的辅助数据库标记为未同步,主副本等待辅助副本重新连接。

o   当辅助副本检测到它和主副本的连接断开后,辅助副本会尝试重新连接主副本。

·        Connected - 辅助副本和主副本间连接正常

可用性副本状态:

·        NotSynchronized -  副本中的一个或多个数据库未同步或尚未联接到可用性组。

·        Synchronizing - 正在同步副本中的一个或多个数据库。

·        Synchronized - 辅助副本中的所有数据库均与主副本主副本上的相应主数据库同步。

注意,不要将可用性副本的状态和可用性副本的角色(Primary,secondary, resolving)搞混。

可用性数据库状态:

·        Not synchronizing

o   如果是主数据库处于该状态,说明该数据库未做好准备将其事务日志与相应的辅助数据库进行同步。

o   如果是辅助数据库处于该状态,说明数据库可能(1)由于连接问题或者重做失败,不再进行日志同步,(2)和主数据库的日志同步被“挂起”,(3)由于角色切换,正处于转换的中间状态。

·        Synchronizing

o   如果是主数据库处于该状态,说明该数据库已做好接受来自辅助数据库的同步请求的准备。

o   如果是辅助数据库处于该状态,说明该辅助数据库和主数据之间有正在进行同步的数据。

·        Synchronized

o   如果是主数据库处于该状态,说明它至少同步了一个辅助数据库。

o   如果是辅助数据库处于该状态,说明该数据库与相应的主数据库保持同步。

要注意,在异步提交模式下,可用性数据库和可用性副本永远不会处于“Synchronized”状态。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值