热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mha高可用masterfailover数据补齐过程–源码级别

1.masterfailovernotgtid传统方式复制masterfailover图具体过程Phase1:ConfigurationCheckPhase1.init_conf

1.master failover not gtid

传统方式复制master failover图

 具体过程

Phase 1: Configuration Check Phase
1.init_config(): # 初始化配置
2.MHA::ServerManager::init_binlog_server: # 初始化binlog server
3.check_settings()
a. check_node_version():
# 查看MHA的版本
b. connect_all_and_read_server_status(): # 检测确认各个Node节点MySQL是否可以连接
c. get_dead_servers(),get_alive_servers(),get_alive_slaves():# 再次检测一次node节点的状态
d. print_dead_servers(): # 是否挂掉的master是否是当前的master
e. MHA::DBHelper::check_connection_fast_util : # 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check
f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): # 检测上次的failover文件
g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数
h. start_sql_threads_if():
# 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread
4.is_gtid_auto_pos_enabled(): # 判断是否是GTID模式
Phase 2: Dead Master Shutdown Phase..
1.force_shutdown($dead_master):
a.stop_io_thread():
# stop所有slave的IO_thread
b.force_shutdown_internal($dead_master):
b_1. master_ip_failover_script:
# 如果有这个脚本,则执行里面的逻辑(比如:切换vip)
b_2. shutdown_script:# 如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器)

Phase 3
: Master Recovery Phase..
Phase
3.1: Getting Latest Slaves Phase..
* check_set_latest_slaves()
a. read_slave_status():
# 获取所有show slave status 信息
b. identify_latest_slaves(): # 找到最新的slave是哪个
c. identify_oldest_slaves(): # 找到最老的slave是哪个

Phase 3.2: Saving Dead Master’s Binlog Phase..
* save_master_binlog($dead_master);
-> 如果dead master可以ssh,那么
b_1_1. save_master_binlog_internal:
# 用node节点save_binary_logs脚本拷贝相应binlog到manager
diff_binary_log # 生产差异binlog日志
b_1_2. file_copy: # 将差异binlog拷贝到manager节点的 manager_workdir目录下
-> 如果dead master不可以ssh
b_1_3.
# 那么差异日志就会丢失

Phase 3.3
: Determining New Master Phase..
b. 如果GTID auto_pos没有打开,调用find_latest_base_slave()
b_1. find_latest_base_slave_internal:
# 寻找拥有所有relay-log的最新slave,如果没有,则failover失败
b_1_1. find_slave_with_all_relay_logs:
b_1_1_1. apply_diff_relay_logs:
# 查看最新的slave是否有其他slave缺失的relay-log

c. select_new_master:
# 选举new master
c_1. MHA::ServerManager::select_new_master:
#If preferred node is specified, one of active preferred nodes will be new master.
#If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there
#Even though preferred master is configured, it does not become a master if it's far behind
get_candidate_masters(): # 获取配置中候选节点
get_bad_candidate_masters(): # 以下条件不能成为候选master
# dead server
# no_master >= 1
# log_bin=0
# oldest_major_version=0
# check_slave_delay: # 检查是否延迟非常厉害(可以通过设置no_check_delay忽略)
{Exec_Master_Log_Pos} + 100000000 # 只要binlog position不超过100000000 就行

选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选
Phase
3.3(3.4): New Master Diff Log Generation Phase..
* recover_master_internal
recover_relay_logs:
# 判断new master是否为最新的slave,如果不是,则生产差异relay logs,并发送给新master
recover_master_internal: # 将之前生产的dead master上的binlog传送给new master

Phase 3.4: Master Log Apply Phase..
* apply_diff:
a. wait_until_relay_log_applied:
# 直到new master完成所有relay log,否则一直等待

b. 判断Exec_Master_Log_Pos
== Read_Master_Log_Pos, # 如果不等,那么生产差异日志:
save_binary_logs --command=save
c. apply_diff_relay_logs
--command=apply:# 对new master进行恢复
c_1. exec_diff:Exec_Master_Log_Pos和Read_Master_Log_Pos的差异日志 # 这是在应用new master自己还未执行的relay log
c_2. read_diff:new master与lastest slave的relay log的差异日志 # 这是应用拥有最多dead master的slave的relay log, 因为new master不一定是拥有dead master最多的数据。
c_3. binlog_diff:lastest slave与daed master之间的binlog差异日志 #
* 如果设置了master_ip_failover_script脚本,那么会执行这里面的脚本(一般用来漂移vip)
* disable_read_only(): 允许new master可写
Phase
4: Slaves Recovery Phase..
# recover_slaves_internal

Phase
4.1: Starting Parallel Slave Diff Log Generation Phase..
recover_all_slaves_relay_logs: # 生成Slave与New Slave之间的差异日志,并将该日志拷贝到各Slave的工作目录下

Phase
4.2: Starting Parallel Slave Log Apply Phase..
* recover_slave: # 对每个slave进行恢复,跟以上Phase 3.4: Master Log Apply Phase中的 apply_diff一样
* change_master_and_start_slave:# 重新指向到new master,并且start slave

Phase 5: New master cleanup phase..
# reset_slave_on_new_master
在new master上执行reset slave all;

 总结:

生成差异binlog:
如果dead master可以ssh:
传统方式复制通过node节点上的save_binary_logs脚本从dead master上保存binlog,通过生成差异binlog日志,将差异binlog拷贝到manager节点的 manager_workdir目录下
如果dead master不可以ssh
那么差异日志就会丢失,也就是会丢失数据。
选主:
以下条件不能成为候选master
# dead server
# no_master >= 1
# log_bin=0
# oldest_major_version=0
# check_slave_delay

生成差异relay log:

判断new master是否为最新的slave,如果不是,则生产差异relay logs,并发送给新master
2.将之前生产的dead master上的binlog传送给new master

 pass

2.master failover gtid

gtid复制方式 mha failover 流程图

具体过程

Phase 1: Configuration Check Phase
1.init_config(): # 初始化配置
2.MHA::ServerManager::init_binlog_server: # 初始化binlog server
3.check_settings()
a. check_node_version():
# 查看MHA的版本
b. connect_all_and_read_server_status(): # 检测确认各个Node节点MySQL是否可以连接
c. get_dead_servers(),get_alive_servers(),get_alive_slaves():# 再次检测一次node节点的状态
d. print_dead_servers(): # 是否挂掉的master是否是当前的master
e. MHA::DBHelper::check_connection_fast_util : # 快速判断dead server,是否真的挂了,如果ping_type=insert,不会double check
f. MHA::NodeUtil::drop_file_if($_failover_error_file|$_failover_complete_file): # 检测上次的failover文件
g. 如果上次failover的时间在8小时以内,那么这次就不会failover,除非配置了额外的参数
h. start_sql_threads_if():
# 查看所有slave的Slave_SQL_Running是否为Yes,若不是则启动SQL thread
4.is_gtid_auto_pos_enabled(): # 判断是否是GTID模式
Phase 2: Dead Master Shutdown Phase..
1.force_shutdown($dead_master):
a.stop_io_thread():
# stop所有slave的IO_thread
b.force_shutdown_internal($dead_master):
b_1. master_ip_failover_script:
# 如果有这个脚本,则执行里面的逻辑(比如:切换vip)
b_2. shutdown_script:# 如果有这个脚本,则执行里面的逻辑(比如:Power off 服务器)

Phase 3
: Master Recovery Phase..
Phase
3.1: Getting Latest Slaves Phase..
* check_set_latest_slaves()
a. read_slave_status():
# 获取所有show slave status 信息
b. identify_latest_slaves(): # 找到最新的slave是哪个
c. identify_oldest_slaves(): # 找到最老的slave是哪个

Phase 3.2: Saving Dead Master’s Binlog Phase..
* save_master_binlog($dead_master);
-> 如果dead master可以ssh,那么
b_1_1. save_master_binlog_internal:
# 用node节点save_binary_logs脚本拷贝相应binlog到manager
diff_binary_log # 生产差异binlog日志
b_1_2. file_copy: # 将差异binlog拷贝到manager节点的 manager_workdir目录下
-> 如果dead master不可以ssh
b_1_3.
# 那么差异日志就会丢失

Phase 3.3
: Determining New Master Phase..
b. 如果GTID auto_pos没有打开,调用find_latest_base_slave()
b_1. find_latest_base_slave_internal:
# 寻找拥有所有relay-log的最新slave,如果没有,则failover失败
b_1_1. find_slave_with_all_relay_logs:
b_1_1_1. apply_diff_relay_logs:
# 查看最新的slave是否有其他slave缺失的relay-log

c. select_new_master:
# 选举new master
c_1. MHA::ServerManager::select_new_master:
#If preferred node is specified, one of active preferred nodes will be new master.
#If the latest server behinds too much (i.e. stopping sql thread for online backups), we should not use it as a new master, but we should fetch relay log there
#Even though preferred master is configured, it does not become a master if it's far behind
get_candidate_masters(): # 获取配置中候选节点
get_bad_candidate_masters(): # 以下条件不能成为候选master
# dead server
# no_master >= 1
# log_bin=0
# oldest_major_version=0
# check_slave_delay: # 检查是否延迟非常厉害(可以通过设置no_check_delay忽略)
{Exec_Master_Log_Pos} + 100000000 # 只要binlog position不超过100000000 就行

选举流程: 先看candidate_master,然后找 latest slave, 然后再随机挑选
Phase
3.4 New Master Diff Log Generation Phase..
  
* recover_master_gtid_internal:
   wait_until_relay_log_applied:
# 候选master等待所有relay-log都应用完
   # 如果候选master不是最新的slave:
   $latest_slave->wait_until_relay_log_applied($log): # 最新的slave应用完所有的relay-log
  change_master_and_start_slave : # 让候选master同步到latest master,追上latest slave
   # 获取候选master此时此刻的日志信息,以便后面切换
   # 如果候选master是最新的slave:
   # 获取候选master此时此刻的日志信息,以便后面切换

   save_from_binlog_server:
  
# 如果配置了binlog server,那么在binlogsever 能连的情况下,将binlog 拷贝到Manager,并生成差异日志diff_binlog(save_binary_logs --command=save)

   apply_binlog_to_master:
   Applying differential binlog:
# 应用差异的binlog到new master

Phase 4
: Slaves Recovery Phase..
Phase
4.1: Starting Slaves in parallel..
* recover_slaves_gtid_internal:
change_master_and_start_slave:
# 因为master已经恢复,那么slave直接change master auto_pos=1 的模式就可以恢复
gtid_wait:# 用此等待同步全部追上

Phase 5: New master cleanup phase..
# reset_slave_on_new_master
在new master上执行reset slave all;

 

 


pass

 

 

 

pass

 

上帝说要有光,于是便有了光;上帝说要有女人,于是便有了女人!



推荐阅读
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • mysql-cluster集群sql节点高可用keepalived的故障处理过程
    本文描述了mysql-cluster集群sql节点高可用keepalived的故障处理过程,包括故障发生时间、故障描述、故障分析等内容。根据keepalived的日志分析,发现bogus VRRP packet received on eth0 !!!等错误信息,进而导致vip地址失效,使得mysql-cluster的api无法访问。针对这个问题,本文提供了相应的解决方案。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 本文介绍了sqlserver云存储和本地存储的区别,云存储是将数据存储在网络上,方便查看和调用;本地存储是将数据存储在电脑磁盘上,只能在存储的电脑上查看。同时提供了几种启动sqlserver的方法。此外,还介绍了如何导出数据库的步骤和工具。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
author-avatar
我_纯情至上
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有