理论介绍:
我们通常说的双机热备是指两台机器都在运行,但并不是两台机器都同时在提供服务。当提供服务的一台出现故障的时候,另外一台会马上自动接管并且提供服务,而且切换的时间非常短。MySQL双主复制,即互为Master-Slave(只有一个Master提供写操作),可以实现数据库服务器的热备,但是一个Master宕机后不能实现动态切换。使用Keepalived,可以通过虚拟IP,实现双主对外的统一接口以及自动检查、失败切换机制,从而实现MySQL数据库的高可用方案。环境说明:
版本 version 5.6.25-log 主1库ip: 10.219.24.25主2库ip:10.219.24.22vip: 10.219.24.30os 版本: centos 6.7已安装热备软件:xtrabackup 防火墙已关补充:
主从复制原理: http://blog.csdn.NET/zhang123456456/article/details/72972701MySQL 5.6安装 :http://blog.csdn.net/zhang123456456/article/details/53608554xtrabackup 安装: http://blog.csdn.Net/zhang123456456/article/details/72836184全程:先搭建一主一从,然后反过来搭建,就是双主复制,最后配置 Mysql+Keepalived 故障转移的高可用环境
一、 先一主一从搭建 ,再反向搭建,配置双主复制
1、 主库参数调整
-- 停止主库mysql[root@mysql02 ~]# service mysql stop[root@mysql02 ~]# netstat -nltp|grep mysql|grep 3606-- 主库创建relay log目录[root@mysql02 full]# mkdir -p /data/mysql/relaylog/[root@mysql02 full]# chown -R mysql:mysql /data/mysql/relaylog-- 调整 my.cnf 参数[root@mysql02 ~]# cat /etc/my.cnf[client]password = Oracleport = 3306socket = /data/mysql/mysql.sock[mysqld]server-id=25port = 3306socket = /data/mysql/mysql.sockcharacter_set_server = utf8character_set_client = utf8collation-server=utf8_general_cilower_case_table_names = 1max_connections = 1000datadir = /data/mysqllog_bin = /data/mysql/binarylog/binlog log_bin_index = /data/mysql/binarylog/binlogrelay-log = /data/mysql/relaylog/relayrelay-log-index = /data/mysql/relaylog/relayrelay_log_purge = onbinlog_format = mixedinnodb_data_file_path = ibdata1:12M:autoextend auto_increment_increment = 10 auto_increment_offset = 1 [mysql]default-character-set = utf8说明:
a、主库必须配置的参数server-id (主从的server-id必须不同)、log_bin、binlog_format、relay-log、relay-log-index、relay_log_purgeauto-increment-offset、auto-increment-incrementb、log-slave-updates 意思是,中继日志执行之后,这些变化是否需要计入自己的binarylog。 当你的B服务器需要作为另外一个服务器的主服务器的时候需要打开。 就是双主互相备份,或者多主循环备份。 我们这里需要, 所以打开。
c、auto-increment-offset、auto-increment-increment 两个参数用于在 双主(多主循环)互相备份。 因为每台数据库服务器都可能在同一个表中插入数据,如果表有一个自动增长的主键,那么就会在多服务器上出现主键冲突。 解决这个问题的办法就是让每个数据库的自增主键不连续。 上图说是, 我假设需要将来可能需要10台服务器做备份, 所以auto-increment-increment 设为10. 而 auto-increment-offset=1 表示这台服务器的序号。 从1开始, 不超过auto-increment-increment。这样做之后, 我在这台服务器上插入的第一个id就是 1, 第二行的id就是 11了, 而不是2.(同理,在第二台服务器上插入的第一个id就是2, 第二行就是12, 这个后面再介绍) 这样就不会出现主键冲突了。 后面我们会演示这个id的效果。
-- 启动主库
[root@mysql02 ~]# mysqld_safe --defaults-file=/etc/my.cnf &2、 从库参数调整-- 停止从库mysql[root@mysql01 ~]# service mysql stop[root@mysql01 ~]# netstat -nltp|grep mysql|grep 3606-- 调整 my.cnf 参数[root@mysql01 ~]# cat /etc/my.cnf[client]password = oracleport = 3306socket = /data/mysql/mysql.sock[mysqld]server-id=22port = 3306socket = /data/mysql/mysql.sockcharacter_set_server = utf8character_set_client = utf8collation-server=utf8_general_cilower_case_table_names = 1max_connections = 1000datadir = /data/mysqllog_bin = /data/mysql/binarylog/binlog log_bin_index = /data/mysql/binarylog/binlogrelay-log = /data/mysql/relaylog/relayrelay-log-index = /data/mysql/relaylog/relayrelay_log_purge = onauto_increment_increment = 10 auto_increment_offset = 2[mysql]default-character-set = utf8说明:从库必须配置的参数server-id、log_bin、relay-log、relay_log_purge、auto-increment-offset、auto-increment-increment、3、 主库备份
-- 主库备份目录[root@mysql02 full]# pwd/xtrabackup/full-- 主库 innobackupex 备份[root@mysql02 ~]# innobackupex --user=root --password=oracle --port=3606 /xtrabackup/full/170610 17:50:23 Backup created in directory '/xtrabackup/full/2017-06-10_17-50-19/'MySQL binlog position: filename 'binlog.000010', position '120'....170610 17:50:23 completed OK!-- 查看备份 binlog编号 与 截止 position[root@mysql02 2017-06-10_17-50-19]# cat xtrabackup_binlog_info binlog.000010 1204、 从库创建与主库相同的备份目录
[root@mysql01 ~]# mkdir -p /xtrabackup/full[root@mysql01 ~]# chown -R mysql:mysql /xtrabackup/full/5、 主库将备份 scp 到从库
[root@mysql02 full]# pwd/xtrabackup/full[root@mysql02 full]# scp -r 2017-06-10_17-50-19 10.219.24.22:/xtrabackup/full6、 从库查看scp过来的备份[root@mysql01 ~]# cd /xtrabackup/full/2017-06-10_17-50-19/[root@mysql01 2017-06-10_17-50-19]# lltotal 12320-rw-r-----. 1 root root 419 Jun 10 18:01 backup-my.cnf-rw-r-----. 1 root root 12582912 Jun 10 18:01 ibdata1drwxr-x---. 2 root root 4096 Jun 10 18:01 mysqldrwxr-x---. 2 root root 4096 Jun 10 18:01 performance_schemadrwxr-x---. 2 root root 4096 Jun 10 18:01 test-rw-r-----. 1 root root 18 Jun 10 18:01 xtrabackup_binlog_info-rw-r-----. 1 root root 113 Jun 10 18:01 xtrabackup_checkpoints-rw-r-----. 1 root root 482 Jun 10 18:01 xtrabackup_info-rw-r-----. 1 root root 2560 Jun 10 18:01 xtrabackup_logfile7、 主库创建同步用户
mysql> GRANT replication slave ON *.* TO 'slave25'@'%' IDENTIFIED BY 'oracle'; Query OK, 0 rows affected (0.05 sec)8、 从库恢复主库数据
-- 从库将原有datadir文件夹重命名到新位置,并创建原文件夹 [root@mysql01 ~]# mv /data/mysql /data/mysqlbak[root@mysql01 ~]# mkdir -p /data/mysql-- innobackupex apply-log[root@mysql01 ~]# innobackupex --apply-log --user=oracle \--password=oracle --port=3606 /xtrabackup/full/2017-06-10_17-50-19/-- innobackupex copy 恢复的文件到原来的数据位置[root@mysql01 mysql]# innobackupex --defaults-file=/etc/my.cnf --user=root \--copy-back /xtrabackup/full/2017-06-10_17-50-19/170610 18:25:11 completed OK!
-- 创建binlog目录与 relaylog 目录并赋权[root@mysql01 ~]# mkdir -p /data/mysql/binarylog[root@mysql01 ~]# mkdir -p /data/mysql/relaylog/[root@mysql01 mysql]# chown -R mysql:mysql /data/mysql9、 从库配置与检测
-- 从库启动[root@mysql01 mysql]# mysqld_safe --defaults-file=/etc/my.cnf &-- 从库指定与主库同步的基本信息mysql>change master tomaster_host='10.219.24.25',master_port=3306,master_user='slave25',master_password='oracle', master_log_file='binlog.000010',master_log_pos=120; Query OK, 0 rows affected, 2 warnings (0.04 sec)参数解释:
MASTER_HOST : 设置要连接的主服务器的ip地址MASTER_USER : 设置要连接的主服务器的用户名MASTER_PASSWORD : 设置要连接的主服务器的密码MASTER_LOG_FILE : 设置要连接的主服务器的bin日志的日志名称MASTER_LOG_POS : 设置要连接的主服务器的bin日志的记录位置-- 启动slave 状态(开始监听msater的变化)mysql> start slave;Query OK, 0 rows affected, 1 warning (0.00 sec)-- 查看slave的状态.mysql> show slave status \G;*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 10.219.24.25 #主库 IPMaster_User: slave25 # 主库复制的用户Master_Port: 3306 # 主库 mysqld Connect_Retry: 60Master_Log_File: binlog.000010 #io_thread 读取主库 master_log_fileRead_Master_Log_Pos: 717 # io_thread 读取主库 master_log_posRelay_Log_File: relay.000002Relay_Log_Pos: 877Relay_Master_Log_File: binlog.000010 #sql_thread 执行主库的 master_log_fileSlave_IO_Running: Yes # 关键的,io_thread 是否 running Slave_SQL_Running: Yes # 关键的,sql_thread 是否 runningReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 717 #sql_thread 执行主库的 master_log_posRelay_Log_Space: 1040Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 # 从库 的延迟Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 25Master_UUID: 29d68531-4cf9-11e7-8e1f-000c297c4100Master_Info_File: /data/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 01 row in set (0.00 sec)ERROR:
No query specified10、 主从同步检查
-- 主库mysql> create database repl;Query OK, 1 row affected (0.00 sec)mysql> use replDatabase changedmysql> create table repl (id int);Query OK, 0 rows affected (0.02 sec)mysql> insert into repl values(1);Query OK, 1 row affected (0.00 sec)-- 从库
mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || binarylog || mysql || performance_schema || relaylog || repl || test |+--------------------+7 rows in set (0.00 sec)mysql> use replReading table information for completion of table and column namesYou can turn off this feature to get a quicker startup with -ADatabase changedmysql> select * from repl;+------+| id |+------+| 1 |+------+1 row in set (0.00 sec) >一主一从同步成功!##################################################
#至此A到B的复制已经配置完成,下面配置从B到A的复制。###################################################声明> 下面操作中 新主库即为原从库(10.219.24.22) 新从库为原主库(10.219.24.25)
11、 新主库创建同步用户
mysql> GRANT replication slave ON *.* TO 'slave22'@'%' IDENTIFIED BY 'oracle';Query OK, 0 rows affected (0.00 sec)12、 新主库查看 binlog 文件号与 position 点
mysql> show master status;+---------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+---------------+----------+--------------+------------------+-------------------+| binlog.000004 | 313 | | | |+---------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)13、 新从库指定与主库同步的基本信息
mysql>change master tomaster_host='10.219.24.22',master_port=3306,master_user='slave22',master_password='oracle', master_log_file='binlog.000004',master_log_pos=313; Query OK, 0 rows affected, 2 warnings (0.04 sec)14、新从库打开 slave 复制功能
mysql> start slave;Query OK, 0 rows affected (0.00 sec)15、 新从库检测同步复制状态mysql> show slave status \G;*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 10.219.24.22Master_User: slave22Master_Port: 3306Connect_Retry: 60Master_Log_File: binlog.000004Read_Master_Log_Pos: 313Relay_Log_File: relay.000002Relay_Log_Pos: 280Relay_Master_Log_File: binlog.000004Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 313Relay_Log_Space: 443Until_Condition: NoneUntil_Log_File: Until_Log_Pos: 0Master_SSL_Allowed: NoMaster_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0Master_SSL_Verify_Server_Cert: NoLast_IO_Errno: 0Last_IO_Error: Last_SQL_Errno: 0Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 22Master_UUID: 70023652-4dc7-11e7-9360-000c2944297aMaster_Info_File: /data/mysql/master.infoSQL_Delay: 0SQL_Remaining_Delay: NULLSlave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update itMaster_Retry_Count: 86400Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 01 row in set (0.00 sec)ERROR:
No query specified-- 新从库测试数据同步状态
mysql> create database mm_repl;Query OK, 1 row affected (0.00 sec)mysql> use mm_repl;Database changedmysql> create table mm_repl(id int auto_increment,name varchar(10), primary key(id));Query OK, 0 rows affected (0.01 sec)mysql> insert into mm_repl(name) values("andy"),("taoYe");Query OK, 1 row affected (0.00 sec)mysql> select * from mm_repl;+----+-------+| id | name |+----+-------+| 1 | andy || 11 | taoYe |+----+-------+2 rows in set (0.00 sec)-- 新主库测试数据同步状态mysql> select * from mm_repl;+----+-------+| id | name |+----+-------+| 1 | andy || 11 | taoYe |+----+-------+2 rows in set (0.00 sec)mysql> insert into mm_repl(name) values("andy"),("taoYe");Query OK, 2 rows affected (0.00 sec)Records: 2 Duplicates: 0 Warnings: 0mysql> select * from mm_repl;+----+-------+| id | name |+----+-------+| 1 | andy || 11 | taoYe || 12 | andy || 22 | taoYe |+----+-------+4 rows in set (0.00 sec)-- 新从库检查同步复制mysql> select * from mm_repl;+----+-------+| id | name |+----+-------+| 1 | andy || 11 | taoYe || 12 | andy || 22 | taoYe |+----+-------+4 rows in set (0.00 sec) >主主同步测试成功二、 配置Mysql+Keepalived故障转移的高可用环境
安装keepalived ( master1 和 master2 两台机器上都安装)
二、1.1 安装 LVS
前提:已经提前配置好本地 Yum 源 配置过程可参考> http://blog.csdn.NET/zhang123456456/article/details/56690945
1、 检查一下系统内核安装之前,首先检查一下系统内核是否支持LVS的IPVS模块;自Linux 2.6开始,系统内核完全内置了LVS的各个模块。[root@mysql02 ~]# modprobe -l|grep ipvskernel/net/netfilter/ipvs/ip_vs.kokernel/net/netfilter/ipvs/ip_vs_rr.kokernel/net/netfilter/ipvs/ip_vs_wrr.kokernel/net/netfilter/ipvs/ip_vs_lc.ko....kernel/net/netfilter/ipvs/ip_vs_pe_sip.ko看到如上输出信息,则表明系统内核默认支持IPVS模块。2、安装依赖包
由于是源码包安装,所以编译时需要打上如下依赖包。# yum -y install kernel-headers glibc-headers glibc-devel libgomp gcc libstdc++-devel gcc-c++3、 yum安装 ipvsadm-1.26-4
[root@mysql02 ~]# yum -y install kernel-devel ipvsadm===================================================================================Package Arch Version Repository Size===================================================================================Installing:ipvsadm x86_64 1.26-4.el6 c6-media 42 kTransaction Summary
===================================================================================Install 1 Package(s)Total download size: 42 k
Installed size: 78 kDownloading Packages:Running rpm_check_debugRunning Transaction TestTransaction Test SucceededRunning TransactionInstalling : ipvsadm-1.26-4.el6.x86_64 1/1 Verifying : ipvsadm-1.26-4.el6.x86_64 1/1Installed:
ipvsadm.x86_64 0:1.26-4.el6Complete!
4、 做个 ln[root@mysql02 ~]# ln -sv /usr/src/kernels/2.6.32-573.el6.x86_64/ /usr/src/linux <--请自行修改 kernels 版本号5、 查看 ipvsadm 版本信息
[root@mysql02 ~]# ipvsadm -versionipvsadm v1.26 2008/5/15 (compiled with popt and IPVS v1.2.1) #> 能看到帮助信息,则说明IPVS安装成功。二、1.2 安装 keepalived-1.2.24
1、官网下载地址:
[root@mysql02 ~]# wget http://www.keepalived.org/software/keepalived-1.2.24.tar.gz2、解压安装包:[root@mysql02 ~]# ll keepalived-1.2.24.tar.gz -rw-r--r--. 1 root root 601873 Jun 16 23:49 keepalived-1.2.24.tar.gz[root@mysql02 ~]# tar -zxvf keepalived-1.2.24.tar.gz3、进入安装目录:[root@mysql02 ~]# cd keepalived-1.2.244、安装keepalived:
[root@mysql03 keepalived-1.2.24]# ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-573.el6.x86_64/说明:--with-kernel-dri :指定使用内核源码中的头文件,即include目录,该参数很重要,只有使用LVS时才用此参数。
[root@mysql03 keepalived-1.2.24]# make && make install
5、复制脚本和文件:
5.1 拷贝执行文件
[root@mysql02 keepalived-1.2.24]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/5.2 将init.d文件拷贝到etc下,加入开机启动项[root@mysql02 keepalived-1.2.24]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/5.3 将keepalived文件拷贝到etc下,加入网卡配置[root@mysql02 keepalived-1.2.24]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/5.4 创建keepalived文件夹[root@mysql02 keepalived-1.2.24]#mkdir /etc/keepalived5.5 将keepalived配置文件拷贝到etc下[root@mysql02 keepalived-1.2.24]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/5.6 复制启动脚本[root@mysql02 keepalived-1.2.24]# cp /usr/local/keepalived/sbin/keepalived /etc/keepalived/6、加入开机启动项
[root@mysql02 keepalived-1.2.24]# chkconfig --add keepalived #添加时必须保证/etc/init.d/keepalived存在7、 启动[root@mysql02 keepalived-1.2.24]# chmod 755 /etc/init.d/keepalived[root@mysql03 keepalived-1.2.24]# service keepalived startStarting keepalived: [ OK ]8、 关闭[root@mysql02 keepalived-1.2.24]# service keepalived stopStopping keepalived: [ OK ] > OK,成功!_________________________________________________________________________________________________________
9、 绑定虚拟IP(VIP),只在master1机器上绑定。## 说明,这一步随便做不做,不影响正常使用,作为了解。说明:绑定虚拟IP(VIP),这个只在master1机器上绑定即可。如下配置好keepalived后,当master1机器出现故障时,VIP资源就会被master2机器自动接管!(这一步其实可以不用这么直接在外部使用ifconfig绑定,VIP就直接在 Keepalived 的配置文件里配置就好,使用命令 ip addr 就能看出 vip;只有LVS+Keepalived 四层负载均衡的高可用环境中, vip是要在外面单独设置的(即ifconfig eth0:0 ....的方式创建vip),通过 ifconfig 可以查看出来 vip。)[root@mysql02 keepalived-1.2.24]# ifconfigeth0 Link encap:Ethernet HWaddr 00:0C:29:7C:41:00 inet addr:10.219.24.25 Bcast:10.255.255.255 Mask:255.0.0.0 inet6 addr: fe80::20c:29ff:fe7c:4100/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12156 errors:0 dropped:0 overruns:0 frame:0 TX packets:2700 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1389340 (1.3 MiB) TX bytes:901117 (879.9 KiB)[root@mysql02 keepalived-1.2.24]# ifconfig eth0:0 10.219.24.30 broadcast 10.255.255.255 netmask 255.0.0.0 up[root@mysql02 keepalived-1.2.24]# route add -host 10.219.24.30 dev eth0:0 [root@mysql02 keepalived-1.2.24]# ifconfigeth0 Link encap:Ethernet HWaddr 00:0C:29:7C:41:00 inet addr:10.219.24.25 Bcast:10.255.255.255 Mask:255.0.0.0 inet6 addr: fe80::20c:29ff:fe7c:4100/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12397 errors:0 dropped:0 overruns:0 frame:0 TX packets:2748 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1405326 (1.3 MiB) TX bytes:906805 (885.5 KiB)eth0:0 Link encap:Ethernet HWaddr 00:0C:29:7C:41:00
inet addr:10.219.24.30 Bcast:10.255.255.255 Mask:255.0.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1补充:删除虚拟ip命令:ip addr del 10.219.24.30 dev eth0 以及 route del -host 10.219.24.30 dev eth0:0 _____________________________________________________________________________________________________________________9、 master1 机器上的keepalived.conf配置。(下面配置中没有使用lvs的负载均衡功能,所以不需要配置虚拟服务器virtual server)[root@mysql02 keepalived-1.2.24]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak-- 清空默认内容[root@mysql02 keepalived-1.2.24]# > /etc/keepalived/keepalived.conf-- 采用如下配置[root@mysql02 keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf! Configuration File for keepalivedglobal_defs {
router_id MYSQL-MASTER-HA}vrrp_script chk_mysql_port {
script "/data/chk_mysql.sh" # mysql 健康检查脚本interval 2 #脚本执行间隔,每2s检测一次}vrrp_instance VI_2 {
state BACKUPinterface eth0 #指定虚拟ip的网卡接口virtual_router_id 54 #路由器标识,MASTER和BACKUP必须是一致的priority 100advert_int 1nopreemptauthentication { auth_type PASSauth_pass 1111}virtual_ipaddress { 10.219.24.30 # vip}track_script { chk_mysql_port }}10、 master2机器上的keepalived配置。master2机器上的keepalived.conf文件只修改priority为90、nopreempt不设置、real_server设置本地IP。[root@mysql01 keepalived-1.2.24]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak[root@mysql01 keepalived-1.2.24]# >/etc/keepalived/keepalived.conf[root@mysql01 keepalived-1.2.24]# vim /etc/keepalived/keepalived.conf[root@mysql01 keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf! Configuration File for keepalivedglobal_defs {
router_id MYSQL-MASTER-HA}vrrp_script chk_mysql_port {
script "/data/chk_mysql.sh"interval 2}vrrp_instance VI_2 {
state BACKUPinterface eth0virtual_router_id 54priority 90advert_int 1nopreemptauthentication { auth_type PASSauth_pass 1111}virtual_ipaddress { 10.219.24.30}track_script { chk_mysql_port }}11、 编写切换脚本。 (master1 与 master2 都操作)
KeepAlived做心跳检测,如果Master的MySQL服务挂了(3306端口挂了),那么它就会选择自杀。Slave的KeepAlived通过心跳检测发现这个情况,就会将VIP的请求接管。-- 检查nc能否正常使用
[root@mysql02 keepalived-1.2.24]# nc-bash: nc: command not found-- 未安装nc包 ,yum安装[root@mysql02 keepalived-1.2.24]# yum -y install nc[root@mysql02 keepalived-1.2.24]# vim /data/chk_mysql.sh
[root@mysql02 ~]# cat /data/chk_mysql.sh#!/bin/bash# check mysql server status# mysql端口PORTS="3306"function check_ports {
for port in $PORTS;donc -z 127.0.0.1 $port | grep -q succeeded[ "${PIPESTATUS[1]}" -eq 0 ] && mark=${mark}1done# 如果mark值为空说明端口都不通。# 如果mark等于1,说明有端口是通的。echo $mark}ret1=$(check_ports)
# 如果mysql端口不通,会尝试重启一次mysqlif [ "$ret1" != 1 ];thenservice mysql stopmysqld_safe --defaults-file=/etc/my.cnf &q! #无用命令,只是为了跳出上面的命令sleep 1ret2=$(check_ports)# 如果还是有端口不通,表示mysql服务不正常,则停掉keepalived,使VIP发生切换[ "$ret2" != 1 ] && /etc/init.d/keepalived stopfi12、 脚本赋权
[root@mysql02 keepalived-1.2.24]# chmod 755 /data/chk_mysql.sh13、 master1 与 master2 开启 keepalived 进程
-- master1[root@mysql02 keepalived-1.2.24]# service keepalived start-- master2[root@mysql01 keepalived-1.2.24]# service keepalived start14、 测试
14.1 查看 vip 情况 ,发现 vip 只在 master1 上, tcpdump 抓包,发现只有 master1 10.219.24.25 多播包 这也符合 VRRP 工作机制-- master1 [root@mysql02 keepalived-1.2.24]# ip a l 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:7c:41:00 brd ff:ff:ff:ff:ff:ff inet 10.219.24.25/8 brd 10.255.255.255 scope global eth0 inet 10.219.24.30/32 scope global eth0 inet6 fe80::20c:29ff:fe7c:4100/64 scope link valid_lft forever preferred_lft forever[root@mysql02 keepalived-1.2.24]# tcpdump -n 'host 224.0.0.18'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes00:58:35.883861 IP 10.219.24.25 > 224.0.0.18: VRRPv2, Advertisement, vrid 54, prio 100, authtype simple, intvl 1s, length 2000:58:36.885543 IP 10.219.24.25 > 224.0.0.18: VRRPv2, Advertisement, vrid 54, prio 100, authtype simple, intvl 1s, length 20-- master2
[root@mysql01 keepalived-1.2.24]# ip a l1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:44:29:7a brd ff:ff:ff:ff:ff:ff inet 10.219.24.22/8 brd 10.255.255.255 scope global eth0 inet6 fe80::20c:29ff:fe44:297a/64 scope link valid_lft forever preferred_lft forever14.2 master1 中 keepalived 关闭 , 发现 vip 漂到了 master2 上
-- master1[root@mysql02 keepalived-1.2.24]# service keepalived stopStopping keepalived: [ OK ]-- master2[root@mysql01 keepalived-1.2.24]# ip a l 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:44:29:7a brd ff:ff:ff:ff:ff:ff inet 10.219.24.22/8 brd 10.255.255.255 scope global eth0 inet 10.219.24.30/32 scope global eth0 inet6 fe80::20c:29ff:fe44:297a/64 scope link valid_lft forever preferred_lft forever14.3 再将之前关闭的 keepalived 开启,发现 vip 未漂回来, 正好符合主备为 非抢占式。
[root@mysql02 keepalived-1.2.24]# service keepalived startStarting keepalived: [ OK ][root@mysql02 keepalived-1.2.24]# ip a l1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:7c:41:00 brd ff:ff:ff:ff:ff:ff inet 10.219.24.25/8 brd 10.255.255.255 scope global eth0 inet6 fe80::20c:29ff:fe7c:4100/64 scope link valid_lft forever preferred_lft forever14.4 将 master1 上的 mysql 关闭, 发现 master1 上的 keepalived 进程也被脚本 kill 了, 顺利的完成了 vip 漂回 master2 上 -- master1[root@mysql02 keepalived-1.2.24]# ip a l1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:7c:41:00 brd ff:ff:ff:ff:ff:ff inet 10.219.24.25/8 brd 10.255.255.255 scope global eth0 inet6 fe80::20c:29ff:fe7c:4100/64 scope link valid_lft forever preferred_lft forever-- master2
[root@mysql01 keepalived-1.2.24]# ip a l1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:44:29:7a brd ff:ff:ff:ff:ff:ff inet 10.219.24.22/8 brd 10.255.255.255 scope global eth0 inet 10.219.24.30/32 scope global eth0 inet6 fe80::20c:29ff:fe44:297a/64 scope link valid_lft forever preferred_lft forever