server1:mornitor和master
server7:candicate slave
server8:slave
global log_slave_updates参数打开和关闭的作用
server7:
set global log_slave_updates=0;
server1:
mysql> use westos;
Database changed
mysql> create table usertb (uasername varchar(20) not null,pssword varchar(20) not null);
Query OK, 0 rows affected (0.81 sec)
[root@server1 mysql]# mysqlbinlog -vv binlog.00008
server1的二进制日志中有记录行为
server7;
[root@server7 mysql]# mysqlbinlog -vv server7-relay-bin.000008
server7的二进制日志中有记录操作的行为。
[root@server7 mysql]# mysqlbinlog -vv binlog.000014 #server7的binlog里面没有记录
server8将master指向server7时会报错。
所以说如果global log_slave_updates参数设置为打开,则slvae主机在同步master的binlog到中继日志的同时,也会同步在slave的二进制日志中。如果此参数是关闭的,则只会同步到中继日志中不会同步到二进制日志中。这样对于候选master是错误的,因为它无法正确的接管master。
恢复:
[root@server7 mysql]# vim /etc/my.cnf
[root@server7 mysql]# /etc/init.d/mysqld restart
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show slave status\G; #恢复正常
relay_log_purge和relay_log_recovery两个参数打开和关闭的作用:
如果希望将relay log 多保留一段时间,比如用于高可用切换后的数据补齐,于是就会设置 relay_log_purge=0,禁止 SQL 线程在执行完一个 relay log 后自动将其删除。这样旧的 relay log 则会被保留。虽然这并不会影响从库复制本身,但还是会有地雷:
由于崩溃或停止 MySQL 时,SQL 线程可能没有执行完全部的 relay log,最后一个 relay log 中的一部分数据会被重新下载到新的文件中。也就是说,这部分数据重复了两次。
设置 relay_log_recovery=1,这个选项的作用是,在 MySQL 崩溃或人工重启后,由于 IO 线程无法保证记录的从主库读取的 binlog 位置的正确性,因此,就不管 master_info 中记录的位置,而是根据 relay_log_info 中记录的已执行的 binlog 位置从主库下载,并让 SQL 线程也从这个位置开始执行。
测试:现在master是server1,candicate server是server7,同时也是slave,server8是slave;
server7上:
mysql> show variables like '%relay%';
+---------------------------+----------------------------------------+
| Variable_name | Value |
+---------------------------+----------------------------------------+
| max_relay_log_size | 0 |
| relay_log | |
| relay_log_basename | /var/lib/mysql/server7-relay-bin |
| relay_log_index | /var/lib/mysql/server7-relay-bin.index |
| relay_log_info_file | relay-log.info |
| relay_log_info_repository | FILE |
| relay_log_purge | ON |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
| sync_relay_log | 10000 |
| sync_relay_log_info | 10000 |
+---------------------------+----------------------------------------+
11 rows in set (0.01 sec)
mysql> set global relay_log_purge=0;
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%relay%';
+---------------------------+----------------------------------------+
| Variable_name | Value |
+---------------------------+----------------------------------------+
| max_relay_log_size | 0 |
| relay_log | |
| relay_log_basename | /var/lib/mysql/server7-relay-bin |
| relay_log_index | /var/lib/mysql/server7-relay-bin.index |
| relay_log_info_file | relay-log.info |
| relay_log_info_repository | FILE |
| relay_log_purge | OFF |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
| sync_relay_log | 10000 |
| sync_relay_log_info | 10000 |
+---------------------------+----------------------------------------+
11 rows in set (0.00 sec)
mysql> show variables like '%relay%';
+---------------------------+----------------------------------------+
| Variable_name | Value |
+---------------------------+----------------------------------------+
| max_relay_log_size | 0 |
| relay_log | |
| relay_log_basename | /var/lib/mysql/server7-relay-bin |
| relay_log_index | /var/lib/mysql/server7-relay-bin.index |
| relay_log_info_file | relay-log.info |
| relay_log_info_repository | FILE |
| relay_log_purge | OFF |
| relay_log_recovery | OFF |
| relay_log_space_limit | 0 |
| sync_relay_log | 10000 |
| sync_relay_log_info | 10000 |
+---------------------------+----------------------------------------+
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.45 sec)
sever8上:
mysql> set global relay_log_purge=0;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G; #此时master为server1
server1上:创建数据
mysql> create database test;
mysql> use test;
Database changed
mysql> create table usertb (username varchar(20) not null, password varchar(20) not null);
mysql> insert usertb values('user1','111');
Query OK, 1 row affected (0.73 sec)
mysql> insert usertb values('user1','111');
Query OK, 1 row affected (0.13 sec)
mysql> insert usertb values('user1','111');
Query OK, 1 row affected (0.12 sec)
#此时创建的数据在server8上可以看见,但是在server7上看不到,因为server7的io线程挂了。
[root@server1 masterha]# ls
app1.cnf master_ip_failover send_report
app1.failover.complete master_ip_online_change
manager.log nohup.out
[root@server1 masterha]# rm -fr app1.failover.complete manager.log nohup.out #切记要删除此处的不必要文件
[root@server1 masterha]# nohup masterha_manager --conf=/usr/local/masterha/app1.cnf &
[root@server1 masterha]# pkill -9 mysqld
[root@server1 masterha]# cat manager.log
Master failover to 172.25.92.7(172.25.92.7:3306) completed successfully.
[1]+ Done nohup masterha_manager --conf=/usr/local/masterha/app1.cnf
server8上:
mysql> show slave status\G; #执向新的master:server7
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.92.7
server7上:
mysql> start slave io_thread;
ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO
mysql> show master status; #可以知道server7成了此时的master,并且可以查看到插入的数据
mysql> select * from usertb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 111 |
| user1 | 111 |
| user1 | 111 |
| user1 | 111 |
+----------+----------+
#解释,server7和server8设置relay_log_purge=0,就是禁止 SQL 线程在执行完一个 relay log 后自动将其删除。现在关闭掉server7的io线程,则server7不会向master同步数据,但是当master(server1)宕掉之后,会自动将master角色给server7。但是在app1.cnf配置文件中明确指明了server7为候选master,但是它此时的数据是落后的,所以在server1宕掉之后,MHA管理器会先让server7去同步server8上的数据,因为serever8一直都是正常的,而且server8的此中继日志没有被删除。当server7从server8上同步数据完成后,重新指定server7为新的master,完成整个切换
手动切换master:手动failover,这种场景意味着在业务上没有启用MHA自动切换功能,当主服务器故障时,人工手动调用MHA来进行故障切换操作
server1现在是master,server7为候选master,毁坏serer1的master
server1上:
[root@server1 masterha]# nohup masterha_manager --conf=/usr/local/masterha/app1.cnf &
[root@server1 masterha]# pkill -9 mysqld
[root@server1 masterha]# masterha_master_switch --master_state=dead --conf=/usr/local/masterha/app1.cnf --dead_master_host=172.25.92.1 --dead_master_port=3306 --new_master_host=172.25.92.7 --new_master_port=3306 --ignore_last_failover
Master failover to 172.25.92.7(172.25.92.7:3306) completed successfully #切换成功。
server7上:
mysql> show slave status\G;
Empty set (0.00 sec)
mysql> show master status; #成功变为master
server8上:
mysql> show slave status\G; #指定master为server7
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.25.92.7
Master_User: repl
server1上的mysql开机后自动变为slave,并指向新的master
在线切换:在许多情况下, 需要将现有的主服务器迁移到另外一台服务器上。
现在master是server7,目标在线切换master为server1:
[root@server1 masterha]# masterha_stop --conf=/usr/local/masterha/app1.cnf
[root@server1 masterha]# masterha_master_switch --conf=/usr/local/masterha/app1.cnf --master_state=alive --new_master_host=172.25.92.1 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
可以看到server7和server8都变为slave
使用脚本来自动切换并添加vip以及设置警报:
vim //usr/local/masterha/app1.cnf
添加:
master_ip_failover_script=/usr/local/masterha/master_ip_failover
master_ip_online_change_script=/usr/local/masterha/master_ip_online_change
report_script=/usr/local/masterha/send_report
将三个脚放在/usr/lcal/masterha目录下 ,脚本内容件看后文
master_ip_failover(切换脚本) master_ip_online_change(在线更改vip脚本) send_report(发送邮件报警脚本)
添加三个脚本的可执行权限:chmod +x
保证mha主机和外网是相通的。
[root@server1 masterha]# masterha_master_switch --conf=/usr/local/masterha/app1.cnf --master_state=alive --new_master_host=172.25.92.7 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
可以看见完成切换,并发送了邮件报警。