SQL Server AlwaysOn可用性及故障转移
杜飞
在 AlwaysOn 可用性组中,“可用性模式”是一个副本属性,该属性确定某一给定可用性副本是否可在同步提交模式下运行。AlwaysOn的可用性模式决定了各副本之间是否允许存在数据差异,SQL Server2012的可用性组使用异步提交模式和同步提交模式来决定主副本在提交事务之前是否等待辅助副本将事务日志记录固化到磁盘。如果主副本配置为“异步提交模式”,则它不会等待任何辅助副本将传入的事务日志记录写入磁盘(以便“强制写入日志”)。 如果某一给定的辅助副本配置为异步提交模式,则主副本不会等待该辅助副本强制写入日志。 如果主副本和某一给定辅助副本都配置为“同步提交模式”,则主副本将等待辅助副本,以便确认它已强制写入日志(除非辅助副本在主副本的“会话超时期限”内未能使用 ping 命令联系上主副本)。
同步提交模式
在同步提交模式下,主数据库在提交事务之前,主副本要等待同步提交辅助副本确认它已将日志固化到磁盘上。只要辅助副本还没有告诉主副本日志固化完成,主副本上的事务就不能提交。这样就保证两边的数据始终是同步的。只要一直在进行数据同步,辅助数据库就会保持“已同步”(SYNCHRONIZED)的状态。同步提交模式能够保证给定的辅助数据库与主数据库上的数据保持完全的同步。但是代价是主数据库上的事务提交会有滞后时间。可以说,同步提交模式相对于性能而言更强调高可用性。
辅助副本的同步工作原理:
在同步提交模式下,在辅助副本联接可用性组并与主副本建立会话之后,辅助副本会将传入日志记录写入到磁盘(“固化日志”)并向主副本发送确认消息。 一旦辅助数据库上已经硬化的日志赶上主数据库的日志末尾,辅助数据库的状态就会设置为 SYNCHRONIZED。 同步所需的时间实质上取决于会话开始时辅助数据库滞后于主数据库的程度(按最初从主副本收到的日志记录数计量)、主数据库的工作负荷和承载辅助副本的服务器实例的计算机的速度。 在同步给定辅助副本上的每个辅助数据库之后,辅助副本的同步运行状态总体上将为 HEALTHY。
同步操作按下列方式维护:
1. 一旦从客户端收到事务时,主副本会将事务的日志写入事务日志,同时将该日志记录发送到辅助副本。
2. 一旦将日志记录写入主数据库的事务日志,只有此时故障转移到未收到该日志的辅助副本,才能撤销该事务。 主副本将等待来自同步提交辅助副本的确认。
3. 辅助副本将硬化日志,并将确认消息返回给主副本。
4. 收到来自辅助副本的确认后,主副本将完成提交处理并向客户端发送一条确认消息。
如果同步提交辅助副本未能确认其已固化日志,即超时,则主副本会将该辅助副本标记为失败。 辅助副本的连接状态更改为 DISCONNECTED,主副本停止等待辅助副本的确认。 此行为确保失败的同步提交辅助副本不会阻止在主副本上固化事务日志。
可用性副本之间的“DISCONNECTED”连接状态:
AlwaysOn 可用性组有一个会话超时机制。所有的主副本和辅助副本之间,会按固定间隔互相发送ping。在会话超时期限内,如果收到ping命令,就说明副本之间的连接正常。收到ping 后,副本将重置此连接上的超时计数器。主副本和辅助副本之间就通过ping来判断彼此是否依旧处于活动状态。
一旦某个副本因为网络故障、操作系统、SQLServer宕机等原因失去响应,它将不能按时把ping命令发给它的伙伴。如果主副本和某个辅助副本间的会话发生超时(没有收到辅助副本的ping),主副本和这个辅助副本之间的连接就会进入DISCONNECTED状态。进入DISCONNECTED状态后,即使可用性副本处于同步提交模式,事务也不需要等待该副本的响应就可以在主副本上提交。
会话超时限制是一个可用性组级别的设置,你可以通过在SQLServer Management Studio中打开可用组的属性来修改它的值,默认值为10 秒,允许的最小值为5秒。通常建议你将超时期限设置为10 秒或更长。因为如果低于10 秒,可能会使那些非常繁忙的系统错误地进入DISCONNECTED状态。
辅助数据库的“NOT SYNCHRONIZING”状态:
无论使用什么可用性模式,如果一个事务在辅助数据库上重做失败,就会导致辅助数据库进入“NOTSYNCHRONIZING”状态。和DISCONNECTED状态类似,此时即使可用性副本设置为同步提交模式,事务也可以在主副本上之间直接提交而无需等待辅助副本响应。
如果你想中断某个数据库的数据同步,而不想影响可用性
组中的其它数据库,可以通过在SSMS中选择Suspenddata movement来手动挂起挂起之后,该数据库在各个可用性副本(无论是什么可用性模式)上的状态都会变成“NOTSYNCHRONIZING”。
异步提交模式
在“异步提交模式”下,辅助副本永远不会与主副本同步。 虽然给定的辅助数据库可能会与对应的主数据库保持一致,但任何辅助数据库在任何时点都会落后。 对于主副本和辅助副本相隔很远而且您不希望小错误影响主副本的灾难恢复方案的情况,或性能比同步数据保护更重要的情况,异步提交模式将会很有用。 而且,由于主副本不会等待来自辅助副本的确认,因而辅助副本上的问题从不会影响主副本。
异步提交辅助副本会尝试与接收自主副本的日志记录保持一致。 但异步提交辅助数据库往往会保持未同步状态,并且可能稍微滞后于相应的主数据库。 通常,异步提交辅助数据库和相应的主数据库之间的这个时间差会很小。 但是,如果承载辅助副本的服务器的工作负荷过高或网络速度很慢,则这个时间差会变得较大。
对于主副本和辅助副本相隔很远而不希望小错误影响主副本性能的灾难恢复方案,则可以考虑使用异步提交模式。而且,由于主副本不会等待来自辅助副本的确认,因而辅助副本上的问题从不会影响主副本。
AlwaysOn故障转移
部署 AlwaysOn 可用性组需要一个 Windows Server 故障转移群集 (WSFC) 。 若要启用 AlwaysOn 可用性组,一个 SQL Server 实例必须驻留在某一 WSFC 节点上,并且该 WSFC 群集和节点必须处于联机状态。 此外,给定可用性组的每个可用性副本必须位于相同 WSFC 群集的不同节点上。和SQLServer群集类似的,AlwaysOn可用性组也需要一个群集resourceDLL来连接Windows群集和SQLServer实例。由于可用性组是一个群集资源,Windows群集需要使用AlwaysOn的resourceDLL来控制资源的上线/离线,检查资源是否失败,更改资源的状态和属性,以及发生各种命令给可用性副本实例。用户可以通过过故障转移群集管理器查看可用性组资源的各种属性。
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由于异常而崩溃,整个群集的其他资源也不会受到影响。
Always使用sp_server_diagnostics来检查可用性组的健康状况。Hadrres.dll会建立并保持一个连接到SQLServer,并通过这个连接运行sp_server_diagnostics,然后不断的获得诊断信息。sp_server_diagnostics的评估结果会被用来和AlwaysOn可用组的FailureConditionLevel设置向比较,来约定是够符合发生故障转移的条件。一旦条件满足,则可用性组就被切换到新的可用性副本上。
有几点需要注意的是:
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是无法发现问题的。就算你为当前的可用性副本配置了自动故障转移,这种情况下也是不会触发故障转移的。
AlwaysOn发现故障之后,是否会立刻触发故障转移呢?这取决于可用性副本的可用性模式和故障转移模式。根据副本间数据同步的模式,可用性模式有两种:同步提交和异步提交。根据故障转移的方式,可用性副本也有两种故障转移模式:自动故障转移和手动故障转移。自动故障转移模式只有当副本的可用性模式为“同步提交”时才可以选择。可用性模式和故障转移模式的组合形成了可用组的三种故障转移形式:自动故障转移、计划的手动故障转移(通称为“手动故障转移)、强制手动故障转移(通称为“强制故障转移”)。
如果发生故障,是否会立刻触发故障转移需要取决于可用性副本的可用性模式和故障转移模式。如前所述,副本间数据同步模式有同步提交和异步提交两种。而可用性副本之间的转移模式分为自动故障转移和手动故障转移两种。当副本的可用性模式为同步提交时才可以使用自动故障转移模式。也就是说主副本和故障转移目标共同决定了故障转移模式,即如果二者都配置为同步提交模式和自动故障转移模式则能发生自动故障转移;若两者中的一个配置了手动故障转移,则只支持计划的手动故障转移;二者中的一个配置了异步提交模式,则只能发生强制故障转移。其中只有强制故障转移可能会丢失数据。自动和手动故障转移会保证数据的安全。
下图显示的是具有五个可用性副本的可用性组。 主副本和一个辅助副本配置为使用同步提交模式以及自动故障转移。 另一个辅助副本配置为使用同步提交模式且仅限计划的手动故障转移,两个辅助副本配置为使用异步提交模式,其仅支持强制手动故障转移(一般称为“强制故障转移”)。
两个可用性副本之间的同步和故障转移行为取决于这两个副本的可用性模式。 例如,对于要发生的同步提交,涉及的当前主副本和辅助副本必须配置为同步提交。 同样,对于要发生的自动故障转移,需要将这两个副本配置为自动故障转移。 因此,上述部署方案的行为可用下表概括,它揭示了每个潜在主副本的行为:
通常,节点 04 在灾难恢复站点中作为异步提交副本部署。 事实上,由于两个节点之间的高网络延迟,在故障转移到节点 04 后节点 01、02 和 03 仍处于异步提交模式,这帮助防止潜在的性能下降。
自动故障转移
在主副本变得不可用之后,自动故障转移将导致合格的辅助副本自动转换为主角色。 当承载主副本的 WSFC 节点对于承载辅助副本的节点而言为本地节点时,自动故障转移最适合。 这是因为数据同步最适合于计算机之间的低消息延迟时间情况以及因为客户端连接可以保持为本地。
仅在以下条件下才发生自动故障转移:
? 存在自动故障转移集。 此自动故障转移集由主副本和辅助副本(“自动故障转移目标”)构成,主副本和辅助副本都配置为同步提交模式并且设置为自动故障转移。 如果主副本设置为手动故障转移,则自动故障切换将无法发生,即使某一辅助副本设置为自动故障转移时也是如此。
? 自动故障转移目标具有正常运行的同步状态(这指示故障转移目标上的每个辅助数据库都与其相应的主数据库同步)。
? Windows Server 故障转移群集 (WSFC) 群集具有仲裁。
? 主副本已变得不可用,并且由灵活的故障转移策略定义的故障转移条件级别已得到满足。
自动故障转移的原理,自动故障转移将启动以下操作序列:
1. 如果承载当前主副本的服务器实例仍在运行,则它会将主数据库的状态更改为“已断开连接”并断开所有客户端的连接。
2. 如果在目标辅助副本上有任何日志记录正在恢复队列中处于等待状态,则辅助副本会应用剩下的日志记录,以完成对辅助数据库的前滚操作。
3. 先前的辅助副本转换到主角色。 其数据库成为主数据库。 新的主副本将尽快回滚任何未提交的事务(恢复的撤消阶段)。 锁定会分离这些未提交的事务,允许当客户端使用数据库时在后台进行回滚。 此过程不会回滚任何已提交的事务。
直到连接给定的辅助数据库后,才将其简要标记为 NOT_SYNCHRONIZED。 在回滚恢复开始前,辅助数据库可以连接到新的主数据库并快速转换为同步状态。 最佳事例是通常用于第三个同步提交的副本,该副本在故障转移之后仍然为辅助角色。
4. 然后,当承载先前主副本的服务器实例重新启动时,它将识别出其他可用性副本现在拥有主角色。 以前的主副本将转换为辅助角色,并且其数据库将成为辅助数据库。 新的辅助副本连接到当前主副本,并尽快将其数据库更新为当前主数据库。 只要新的辅助副本重新同步了其数据库,就可以再次执行故障转移,但按反向执行。
计划的手动故障转移(无数据丢失)
在数据库管理员针对承载目标辅助副本的服务器实例发出手动故障转移命令后,手动故障转移将导致已同步的辅助副本转换为主角色。 为了支持手动故障转移,辅助副本和当前主副本必须同时配置为同步提交模式(如果有)。 可用性副本上的每个辅助数据库都必须加入到可用性组中,并与其对应的主数据库同步(也即,必须同步辅助副本)。 这可确保对先前主数据库提交的每个事务也对新的主数据库提交。 因此,新的主数据库与旧的主数据库完全相同。
下图说明计划的故障转移的各个阶段:
1. 在故障转移之前,主副本位于 Node01 的服务器实例上。
2. 数据库管理员启动计划的故障转移。 故障转移目标为位于 Node02 的服务器实例上的可用性副本。
3. 故障转移目标(位于 Node02 上)将成为新的主副本。 因为这是计划的故障转移,以前的主副本在故障转移期间切换为辅助角色,并且使其数据库立即联机作为辅助数据库。
手动故障转移所需条件
为了支持手动故障转移,当前主副本必须设置为同步提交模式,而辅助副本必须:
配置为同步提交模式。
当前已与主副本同步。
若要手动对可用性组执行故障转移,您必须连接到将成为新的主副本的辅助副本。
计划的手动故障转移的工作方式
计划的手动故障转移(必须在目标辅助副本上启动)将启动以下操作序列:
为了确保在原始主数据库上不发生任何新的用户事务,WSFC 群集向主副本发送要求脱机的请求。
如果任何辅助数据库的恢复队列中有任何日志处于等待状态,则辅助副本将完成对辅助数据库进行前滚的操作。 所需时间取决于系统速度、最新工作负荷以及恢复队列中的日志量。 若要了解恢复队列的当前大小,请使用数据库镜像性能对象中的 Recovery Queue 性能计数器。
注意
可通过限制恢复队列的大小调整故障转移时间。 不过,这会导致主副本的速度下降,以允许辅助副本与其同步。
辅助副本成为新的主副本,先前的主副本成为新的辅助副本。
新的主副本回滚所有未提交的事务,并使其数据库作为主数据库联机。 所有辅助数据库都被简要地标记为 NOT SYNCHRONIZED,直至它们连接到新的主数据库并重新进行同步为止。 此过程不会回滚任何已提交的事务。
当以前的主副本重新联机后,它将承担辅助角色,而以前的主数据库将成为辅助数据库。 新的辅助副本快速将新的辅助数据库与对应的主数据库重新同步。
注意
只要新的辅助副本重新同步了数据库,就可以再次执行故障转移,但按反向执行。
强制故障转移(可能丢失数据)
对可用性组强制进行故障转移(可能丢失数据)是一种灾难恢复方法,使您能够将辅助副本用作温备用服务器。 因为强制故障转移存在数据丢失的风险,所以应该谨慎使用。 建议仅当您必须立即将服务还原到可用性数据库并愿意承担数据丢失的风险时,才执行强制故障转移。
强制故障转移的原理:
强制故障转移会启动一个将主角色转换为角色处于辅助或正在解析状态的目标副本的过程。 故障转移目标成为新的主副本,并立即将其数据库副本提供给客户端。 当以前的主副本变得可用时,它将转换为辅助角色,并且其数据库将成为辅助数据库。
所有辅助数据库(包括现在变得可用的以前的主数据库)将挂起。 根据挂起的辅助数据库以前的数据同步状态,它可能适合于补救该主数据库的未能提交的数据。 在配置为只读访问的辅助副本上,您可以查询辅助数据库以手动发现丢失的数据。 然后,您可以对新的主数据库发出 Transact-SQL 语句来进行必要的更改。
强制故障转移的风险:
一定要注意,强制故障转移可能会造成数据丢失。 这是因为目标副本无法与主副本进行通信,从而不能保证两个数据库同步。 强制故障转移启动新的恢复分叉。 因为原始主数据库和辅助数据库位于不同的恢复分叉上,所以每个数据库现在包含另一个数据库不包含的数据:每个原始主数据库包含任何尚未从其发送队列发送到以前的辅助数据库的更改(未发送的日志);以前的辅助数据库包含任何强制故障转移之后发生的更改。
如果因为主副本出现故障而强制进行故障转移,则潜在的数据丢失取决于是否在出现故障之前已将所有事务日志发送到辅助副本。 在异步提交模式下,可能会始终存在累积的未发送日志。 在同步提交模式下,可能仅在辅助数据库同步之前会出现这种情况。