【Keepalived+MySQL】MySQL双主互备+高可用

痴心易碎 提交于 2020-01-01 02:18:37

一、基本信息说明

 

【DB1】

IP: 192.168.102.144

hostname: LVS-Real1

 

【DB2】

IP: 192.168.102.145

hostname: LVS-Real2

【VIP】

IP:  192.168.102.146

 

 

 二、MySQL配置主主互备

 1.配置DB1和DB2的/etc/my.cnf

【DB1】


[root@LVS-Real1 ~]# more /etc/my.cnf
[client]  
port = 3306  
socket = /tmp/mysql.sock  
  
[mysqld]  
user=mysql  
port = 3306  
server_id = 1                        #需保证唯一性
socket=/tmp/mysql.sock  
basedir =/usr/local/mysql  
datadir =/usr/local/mysql/data  
pid-file=/usr/local/mysql/data/mysqld.pid  
log-error=/usr/local/mysql/log/mysql-error.log


log-bin=mysql-bin                     #开启二进制日志
relay-log=mysql-relay-bin

replicate-wild-ignore-table=mysql.%   #忽略复制mysql数据库下的所有对象,以下依次类推
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%

 

【DB2】

 

[root@LVS-Real2 ~]# more /etc/my.cnf
[client]  
port = 3306  
socket = /tmp/mysql.sock  
  
[mysqld]  
user=mysql  
port = 3306  
server_id = 2                       #需保证唯一性
socket=/tmp/mysql.sock  
basedir =/usr/local/mysql  
datadir =/usr/local/mysql/data  
pid-file=/usr/local/mysql/data/mysqld.pid  
log-error=/usr/local/mysql/log/mysql-error.log


log-bin=mysql-bin                  #开启二进制日志
relay-log=mysql-relay-bin
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%

 

 2.手动同步数据库

如果DB1上有数据,在执行主主互备之前,需要将DB1和DB2上两个数据库保持同步,首先在DB1上执行备份,执行如下语句:

mysql>flush tables with read lock;

在关闭上述终端的情况下,新开启一个终端打包数据库。

 

3.创建复制用户并授权

  • 首先在【DB1】上的MySQL库中创建复制用户
mysql>grant replication slave on *.* to 'repl_user'@'192.168.102.145' identified by 'repl_passwd';
  • 在【DB1】上执行如下语句,并记下File和Position的值
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1004 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.02 sec)
  • 然后在【DB2】上将DB1设为自己的主服务器,如下:
change master to \
master_host='192.168.102.144',           #DB1的IP地址
master_user='repl_user',
master_password='repl_passwd',
master_log_file='mysql-bin.000002',      #DB1上查询出的File值
master_log_pos=1004;                     #DB1上查询出的Position值
  • 在【DB2】上启动slave服务,并查询slave的运行状态
mysql>start slave;

查看Slave的运行状态,这里需要关注Slave_IO_Running和Slave_SQL_Running.这两个就是在Slave节点上运行的主从复制线程,正常情况下两个值都应该为Yes.

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.102.144
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000008
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay-bin.000040
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000008
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 527
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_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: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 64e9b20f-2eee-11e8-ab62-000c29889112
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

 

  • 接下来开始配置从DB2到DB1的MySQL主从复制,这个配置过程和上面一样。
  • 首先在【DB2】上的MySQL库中创建复制用户,并查看数据库状态,记下File和Position值。
grant replication slave on *.* to 'repl_user'@'192.168.102.144' identified by 'repl_passwd';
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1004 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.02 sec)
  • 然后在【DB1】上将DB2设为自己的主服务器
change master to \
master_host='192.168.102.145',
master_user='repl_user',
master_password='repl_passwd',
master_log_file='mysql-bin.000002',
master_log_pos=1004;
  • 在【DB1】上启动slave服务
mysql>start slave;

在【DB1】查看Slave的运行状态,这里需要关注Slave_IO_Running和Slave_SQL_Running.这两个就是在Slave节点上运行的主从复制线程,正常情况下两个值都应该为Yes.

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.102.145
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000016
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay-bin.000040
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000016
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 740
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_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: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 2
                  Master_UUID: a35a032d-2ef8-11e8-bd3c-000c2910f959
             Master_Info_File: /usr/local/mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)
  • 至此,主主复制配置完毕; 

 

三、Keepalived的安装与配置

 

1.下载Keepalived

http://www.keepalived.org/download.html

 

2.安装Keepalived

#1.安装依赖包
yum -y install gcc openssl-devel  libnfnetlink libnfnetlink-devel

#2.开始安装
tar -xvf keepalived-1.2.18.tar.gz
cd keepalived-1.2.18
./configure --prefix=/usr/local/keepalivedmakemake install

 

3.复制文件到相应目录

cp /usr/local/keepalived/sbin/keepalived               /usr/sbin/ 

cp /usr/local/keepalived/etc/rc.d/init.d/keepalived   /etc/init.d/  

cp /usr/local/keepalived/etc/sysconfig/keepalived     /etc/sysconfig/  
mkdir -p /etc/keepalived
cp -r /usr/local/keepalived/etc/keepalived/keepalived.conf  /etc/keepalived

 

4.配置keepalived.conf

 【DB1】

[root@LVS-Real1 keepalived]# more /etc/keepalived/keepalived.conf
global_defs {    
     notification_email {    
         guanyy0911@163.com  
     }    
     notification_email_from guanyy0911@163.com    
     smtp_server 127.0.0.1    
     smtp_connect_timeout 30    
     router_id MySQL-ha    
}    
   
vrrp_instance VI_1 {    
     state BACKUP   
     interface eth0    
     virtual_router_id 51    
     priority 100       #设置优先级
     advert_int 1
     nopreempt          #设置不抢占,当因为故障切换到DB2后,如果DB1恢复,则不再切回DB1,直到DB2出现故障才切换回DB1
     authentication {    
         auth_type PASS    
         auth_pass 1111    
     }    
     virtual_ipaddress {    
         192.168.102.146    #设置虚拟IP,即VIP
     }    
}    
   
virtual_server 192.168.102.146 3306 {    
     delay_loop 2     
     lb_algo wrr   
     lb_kind DR    
     persistence_timeout 60   
     protocol TCP    
     real_server 192.168.102.144 3306 {    
         weight 3    
         notify_down /etc/keepalived/mysql.sh 
         TCP_CHECK {    
             connect_timeout 10     
             nb_get_retry 3       
             delay_before_retry 3  
             connect_port 3306   
         }  
     }    
}  

mysql.sh脚本的内容如下:

[root@LVS-Real1 keepalived]# more /etc/keepalived/mysql.sh 
#!/bin/bash
pkill keepalived

  说明:该脚本主要用来当MySQL服务关闭时杀掉keepalived进程,进而达到切换的目的。

 

【DB2】

[root@LVS-Real2 keepalived]# more /etc/keepalived/keepalived.conf
global_defs {    
     notification_email {    
         guanyy0911@163.com  
     }    
     notification_email_from guanyy0911@163.com    
     smtp_server 127.0.0.1    
     smtp_connect_timeout 30    
     router_id MySQL-ha    
}    
   
vrrp_instance VI_1 {    
     state BACKUP   
     interface eth0    
     virtual_router_id 51    
     priority 90        #设置优先级,要比DB1低
     advert_int 1       
     authentication {    
         auth_type PASS    
         auth_pass 1111    
     }    
     virtual_ipaddress {    
         192.168.102.146    #设置虚拟IP,即VIP
     }    
}    
   
virtual_server 192.168.102.146 3306 {    
     delay_loop 2     
     lb_algo wrr   
     lb_kind DR    
     persistence_timeout 60   
     protocol TCP    
     real_server 192.168.102.145 3306 {    
         weight 3    
         notify_down /etc/keepalived/mysql.sh 
         TCP_CHECK {    
             connect_timeout 10     
             nb_get_retry 3       
             delay_before_retry 3  
             connect_port 3306   
         }  
     }    
}   

mysql.sh脚本的内容如下:

[root@LVS-Real1 keepalived]# more /etc/keepalived/mysql.sh 
#!/bin/bash
pkill keepalived

 说明:该脚本主要用来当MySQL服务关闭时杀掉keepalived进程,进而达到切换的目的。

 

 

5.启动keepalived

service keepalived start

 

5.检查并测试VIP是否可用

 

如果在/var/log/messages文件中有如下信息,说明VIP已经可用。

Mar 24 13:40:49 LVS-Real1 Keepalived[42692]: Stopping Keepalived v1.2.18 (03/24,2018)
Mar 24 13:40:49 LVS-Real1 Keepalived[42829]: Starting Keepalived v1.2.18 (03/24,2018)
Mar 24 13:40:49 LVS-Real1 Keepalived[42830]: Starting Healthcheck child process, pid=42832
Mar 24 13:40:49 LVS-Real1 Keepalived[42830]: Starting VRRP child process, pid=42833
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Netlink reflector reports IP 192.168.102.144 added
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Netlink reflector reports IP fe80::20c:29ff:fe88:9112 added
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Registering Kernel netlink reflector
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Registering Kernel netlink command channel
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Netlink reflector reports IP 192.168.102.144 added
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Registering gratuitous ARP shared channel
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Opening file '/etc/keepalived/keepalived.conf'.
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Netlink reflector reports IP fe80::20c:29ff:fe88:9112 added
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Configuration is using : 69127 Bytes
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Registering Kernel netlink reflector
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Registering Kernel netlink command channel
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Opening file '/etc/keepalived/keepalived.conf'.
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: Using LinkWatch kernel netlink reflector...
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Configuration is using : 11737 Bytes
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: VRRP_Instance(VI_1) Entering BACKUP STATE
Mar 24 13:40:49 LVS-Real1 Keepalived_vrrp[42833]: VRRP sockpool: [ifindex(2), proto(112), unicast(0), fd(10,11)]
Mar 24 13:40:49 LVS-Real1 Keepalived_healthcheckers[42832]: Using LinkWatch kernel netlink reflector...

此时从外部的客户端可以ping通该VIP.

 

C:\Users\Sakura>ping 192.168.102.146

正在 Ping 192.168.102.146 具有 32 字节的数据:
来自 192.168.102.146 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.102.146 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.102.146 的回复: 字节=32 时间<1ms TTL=64
来自 192.168.102.146 的回复: 字节=32 时间<1ms TTL=64

192.168.102.146 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 0ms,最长 = 0ms,平均 = 0ms

 

6. 同时启动DB1和DB2上的mysql和keepalived服务

service mysql.server start
service keepalived start

 

7.从第三方客户端通过VIP来登录数据库。看是否可以登录。

   我们通过navicat进行登录,发现是可以通过VIP登录。之后查询当前使用是哪个数据库。如下图查询到,使用的是DB1.

 

  7.我们停掉DB1数据库,看是否会切换到DB2上。

     通过实验发现,发现已经切换到DB2上了。

 

8. 我们再次启动DB1上的Mysql服务和keepalived服务(已经通过脚本实现MySQL服务关闭的同时,脚本会杀掉keepalived进程)

   通过实验发现,由于我们设置的是不抢占,在DB1启动后,并没有切换回DB2. 达到预期的目的。

 

9.这次我们停掉DB2上的MySQL服务,看是否会切换回DB1.

  通过实验发现,在停掉DB2上的MySQL服务后,已经自动切换回DB1上。达到预期目的。

 

 特别提示:当MySQL被关闭时,其所在的主机的keepalived也同时被关闭。但在重新启动MySQL服务时,keepalived不会自动启动,需要手动启动。

 

10.至此,整个配置过程完毕!

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!