在一个HA的组里面,由于所有对数据库的更改都是在主节点上面,然后由它将所做的更改分发到各个副节点,导致主节点上的负担非常重,所以选择组内计算能力最强的节点做主节点是顺理成章的事情。
那么一旦加入一个新的节点,它的运算能力比现有的主节点能力更强,用户肯定是希望将这个新节点设置为主节点,这就需要一种能够让用户随意的在两个节点之间转换master角色的功能,整个过程如下:
1.指定的副节点要赶上当前的主节点,在这期间主节点可以继续响应写操作,如果副节点的最新数据在这个过程完成之后还落后于主节点上的最新数据,则转换失败
2.当副节点赶上主节点之后,阻止当前主节点上事务的提交或回滚,这样是为了保证副节点上拥有最新的数据
3.副节点再次验证其是否拥有最新的数据,如果没有,则该转换失败
4.调用选举协议广播一个Result信息,该信息的内容就是推选指定的副节点为主节点
5.原来的主节点转换成副节点,但是需要经历一个恢复的过程,也就是说旧主节点会崩溃并重新启动
为什么一定要保证副节点要拥有和主节点一样的数据呢?这是因为如果新推选出的主节点的数据比其它的副节点的数据还要老的话,也就是出现了数据不一致的情况,而且副节点无法通过同步主节点来解决这种不一致的状况,导致副节点必须将那些在主节点上不存在的数据进行回滚,也就是所谓的硬恢复(Hard Recovery)。除了硬恢复之外,还有软恢复,我会在其它的文章里讲述这两者的差别。
一旦出现这种情况,就意味着当前的组除了主节点之外,有可能其它的副节点全部崩溃,该组就无法提供数据服务,因此如果副节点没有赶上主节点,则转换失败,主节点不会被转换。
保证副节点赶上主节点相对比较简单,设置一个countdownlatch,这个latch只有在指定的副节点赶上主节点之后才会释放。检验一个节点是否赶上主节点,只需要检查两个节点上最新的表示当前事务结束的日志是否一致,如果一致则表示副节点赶上了主节点。
在副节点赶上主节点之后,为了保证主节点上不会再有新的数据更新,需要阻止在主节点上事务的提交或回滚(包括用户启动的事务和内部事务)。为什么只需要组织事务的提交和回滚呢?因为只有这两种日志点才会被用来校验主副节点是否一致,其余的数据可以通过软恢复回滚。
以上的措施可以保障主节点在一定的时间内被副节点赶上。
但是在HA中还有另外一个问题需要解决:如何处理一个主节点转换为副节点?这是由于在主节点上还有一些事务没有提交或回滚,这些事务是在主节点转换为副节点之前启动的,所以用于更改数据的权限,如果不处理,会导致主副节点的不一致。处理这个问题的最好办法就是将主节点crash,然后再做恢复,这样就可以让那些数据不一致性消失。
那么一旦加入一个新的节点,它的运算能力比现有的主节点能力更强,用户肯定是希望将这个新节点设置为主节点,这就需要一种能够让用户随意的在两个节点之间转换master角色的功能,整个过程如下:
1.指定的副节点要赶上当前的主节点,在这期间主节点可以继续响应写操作,如果副节点的最新数据在这个过程完成之后还落后于主节点上的最新数据,则转换失败
2.当副节点赶上主节点之后,阻止当前主节点上事务的提交或回滚,这样是为了保证副节点上拥有最新的数据
3.副节点再次验证其是否拥有最新的数据,如果没有,则该转换失败
4.调用选举协议广播一个Result信息,该信息的内容就是推选指定的副节点为主节点
5.原来的主节点转换成副节点,但是需要经历一个恢复的过程,也就是说旧主节点会崩溃并重新启动
为什么一定要保证副节点要拥有和主节点一样的数据呢?这是因为如果新推选出的主节点的数据比其它的副节点的数据还要老的话,也就是出现了数据不一致的情况,而且副节点无法通过同步主节点来解决这种不一致的状况,导致副节点必须将那些在主节点上不存在的数据进行回滚,也就是所谓的硬恢复(Hard Recovery)。除了硬恢复之外,还有软恢复,我会在其它的文章里讲述这两者的差别。
一旦出现这种情况,就意味着当前的组除了主节点之外,有可能其它的副节点全部崩溃,该组就无法提供数据服务,因此如果副节点没有赶上主节点,则转换失败,主节点不会被转换。
保证副节点赶上主节点相对比较简单,设置一个countdownlatch,这个latch只有在指定的副节点赶上主节点之后才会释放。检验一个节点是否赶上主节点,只需要检查两个节点上最新的表示当前事务结束的日志是否一致,如果一致则表示副节点赶上了主节点。
在副节点赶上主节点之后,为了保证主节点上不会再有新的数据更新,需要阻止在主节点上事务的提交或回滚(包括用户启动的事务和内部事务)。为什么只需要组织事务的提交和回滚呢?因为只有这两种日志点才会被用来校验主副节点是否一致,其余的数据可以通过软恢复回滚。
以上的措施可以保障主节点在一定的时间内被副节点赶上。
但是在HA中还有另外一个问题需要解决:如何处理一个主节点转换为副节点?这是由于在主节点上还有一些事务没有提交或回滚,这些事务是在主节点转换为副节点之前启动的,所以用于更改数据的权限,如果不处理,会导致主副节点的不一致。处理这个问题的最好办法就是将主节点crash,然后再做恢复,这样就可以让那些数据不一致性消失。