一、故障切换的过程
当master_manager监控到主库mysqld服务停止后,首先对主库进行SSH登录检查(save_binary_logs -command=test),然后对mysqld服务进行健康检查(PING(SELECT)每个3秒检查一次,持续3次),最后作出Master is down!的判断,master failover开始。
Phase 1: Configuration Check Phase..
确认主从主机状态,从库中最新的主机有哪些。
Phase 2: Dead Master Shutdown Phase..
前提是你需要指定相关的脚本,比如:master_ip_failover_script、shutdown_script,在安装包的samples/scriptes目录下。
Phase 3: Master Recovery Phase..
Phase 3.1: Getting Latest Slaves Phase..
根据从库同步主库的binlog的位置,分出latest slaves和oldest slaves。
Phase 3.2: Saving Dead Master’s Binlog Phase..
在主库上执行以下命令获得lastest slave与master间的binlog差异:
save_binary_logs -command=save -start_file=mysql-bin.000010 -start_pos=3716 -binlog_dir=/data/mha_48 -output_file=/var/log/masterha/saved_master_binlog_from_10.0.1.48_3306_20120326174946.binlog -handle_raw_binlog=1 -disable_log_bin=0 -manager_version=0.53
然后,通过scp将生成的差异binlog文件拷贝到monitor server上。
Phase 3.3: Determining New Master Phase..
执行如下命令,找出latest slave,并确认relay log是否全部应用,最后根据候选规则,选出新的主库(会检查是否有设置candidate_master=1和no_master=1):
apply_diff_relay_logs -command=find -latest_mlf=mysql-bin.000019 -latest_rmlp=238437084 -target_mlf=mysql-bin.000019 -target_rmlp=116056791 -server_id=1 -workdir=/var/log/masterha -timestamp=20120330124742 -manager_version=0.53 -relay_log_info=/data/mha_38/relay-log.info -relay_dir=/data/mha_38/
Phase 3.4: New Master Diff Log Generation Phase..
新主库需要判断自己的relay log是否与latest slave有差异,产生差异relay log;之后Monitor server会通过scp将主库差异binlog拷贝到新主库上。
Phase 3.5: Master Log Apply Phase..
在新主库上应用relay log差异和主库binlog差异;最后,获得新主库的binlog文件及位置信息,并设置read_only=0。
Phase 4: Slaves Recovery Phase..
Phase 4.1: Starting Parallel Slave Diff Log Generation Phase..
判断从库与lastest slave是否存在relay log差异,在latest slave上执行如下命令,生成差异relay log文件,并通过scp拷贝到对应的从库上:
apply_diff_relay_logs -command=generate_and_send -scp_user=root -scp_host=10.0.1.37 -latest_mlf=mysql-bin.000019 -latest_rmlp=238437084 -target_mlf=mysql-bin.000019 -target_rmlp=116056791 -server_id=1 -diff_file_readtolatest=/var/log/masterha/relay_from_read_to_latest_10.0.1.37_3306_20120330124742.binlog -workdir=/var/log/masterha -timestamp=20120330124742 -handle_raw_binlog=1 -disable_log_bin=0 -manager_version=0.53 -relay_log_info=/data/mha_38/relay-log.info -relay_dir=/data/mha_38/
Phase 4.2: Starting Parallel Slave Log Apply Phase..
首先,将monitor server上生成的binlog差异拷贝到个从库上;
然后,判断从库执行relay log位置(Exec_Master_Log_Pos)是否与已读到的relay log位置(Read_Master_Log_Pos)一致,执行以下命令获得差异文件:
save_binary_logs -command=save -start_file=relay-bin.000003 -start_pos=33701765 -output_file=/var/log/masterha/relay_from_exec_to_read_10.0.1.37_3306_20120330124742.binlog -handle_raw_binlog=1 -disable_log_bin=0 -manager_version=0.53 -relay_log_info=/data/mha_37/relay-log.info -binlog_dir=/data/mha_37/
接下来,应用所有差异日志,同时差异日志文件合并到一个文件(total_binlog_for_10.0.1.37_3306.20120330124742.binlog)中,执行的语句及结果会被输出一个标有err的日志文件(relay_log_apply_for_10.0.1.37_3306_20120330124742_err.log)中:
apply_diff_relay_logs -command=apply -slave_user=root -slave_host=10.0.1.37 -slave_ip=10.0.1.37 -slave_port=3306
-apply_files=/var/log/masterha/relay_from_exec_to_read_10.0.1.37_3306_20120330124742.binlog, \
/var/log/masterha/relay_from_read_to_latest_10.0.1.37_3306_20120330124742.binlog, \
/var/log/masterha/saved_master_binlog_from_10.0.1.48_3306_20120330124742.binlog \
-workdir=/var/log/masterha -target_version=5.1.57-log -timestamp=20120330124742 -handle_raw_binlog=1 -disable_log_bin=0 -manager_version=0.53 -slave_pass=xxx
最后,执行reset slave,并重新CHANG MASTER。
Phase 5: New master cleanup phease..
执行reset slave操作清除之前slave信息。
以上每个阶段的分析,是根据master_manager监控脚本的输出日志分析得来,它的日志非常详细。看着日志不停的感叹,如此严谨细致的方案;从故障的反复确认,到binlog/relay日志的层层比对,多重差异日志的应用,到最后复制位置的准确选择做得每一步都是十分仔细,如果中途有意外发生会终止failover操作,并产生mha_manager.failover.error的文件,下一次必须要删除该文件才能正常failover,再或是当从库的差异日志太大落后太多(100M),默认情况会终止failover随后报错退出,除非设置check_repl_relay=0,因为它要保证快速切换,downtime不能过长。
二、在线手动切换过程
第1步:配置检测:根据配置文件检测主从关系以及确定有哪些存活的服务器,然后在master上执行FLUSH NO_WRITE_TO_BINLOG TABLES命令关闭打开的表。再检查从库到主库的复制是否正常。并根据配置决定新的主库。
第2步:执行FLUSH TABLES WITH READ LOCK锁住所有的表阻塞主库的写操作。等待其他从库复制追赶上主库。这里建议部署master_ip_online_change_script 脚本,该脚本会自动阻塞以及kill原master session,置原master为只读,停掉VIP(获取旧主库的binlog位置,使用master_log_wait()函数追赶主库)。同步完成之后,获取新主库的binlog位置,生成change master语句准备用于其他从库切换到新主库。
第3步:所有其他从库并行切换主库到新主库。使用第二步骤获取的旧主库的binlog位置,所有其他从库使用master_log_wait()函数追赶主库。然后使用change master切换到新的主库上。
第4步:旧主库unlock tables,并change master到新的主库上。
第5步:新的主库reset slave,绑定VIP在新的主库上。
转自博文:
http://blog.youkuaiyun.com/zengxuewen2045/article/details/51605613