记录日常工作关于系统运维,虚拟化云计算,数据库,网络安全等各方面问题。

MySQL的高可用方案有很多种,双主、MHA、MMM等等,这里只是写下最简单的双主这种高可用方案。

一、配置MySQL互为主从

1、环境准备

系统IP主机名服务
Centos 7.5192.168.100.2mysql1MySQL+keepalived
Centos 7.5192.168.100.3mysql2MySQL+keepalived

2、开启二进制日志及中继日志

#主机mysql1配置文件如下:
[root@mysql1 ~]# cat /etc/my.cnf 
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
server_id=1          #server_id必须唯一
socket=/usr/local/mysql/mysql.sock
log-error=/usr/local/mysql/data/mysqld.err
log-bin=/usr/local/mysql/data/log_bin            #指定二进制日志文件
relay-log=/usr/local/mysql/data/relay-bin        #指定中继日志
relay-log-index=relay-bin.index
auto_increment_increment=2
auto_increment_offset=1
 
#主机mysql2配置文件如下:
[root@mysql2 ~]# cat /etc/my.cnf 
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
server_id=2 
socket=/usr/local/mysql/mysql.sock
log-error=/usr/local/mysql/data/mysqld.err
log-bin=/usr/local/mysql/data/log_bin
relay-log=/usr/local/mysql/data/relay-bin
relay-log-index=relay-bin.index
auto_increment_increment=2
auto_increment_offset=2
  


  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

注:mysql1和mysql2只有server-id和auto_increment_offset不同

mysql中有自增长字段,在做数据库的主主同步时需要设置自增长的两个相关配置:auto_increment_offset和auto_increment_increment。 auto-increment-increment表示自增长字段每次递增的量,其默认值是1。它的值应设为整个结构中服务器的总数,我这里用到两台服务器,所以值设为2。 auto-increment-offset是用来设定数据库中自动增长的起点(即初始值),因为这两能服务器都设定了一次自动增长值2,所以它们的起点必须得不同,这样才能避免两台服务器数据同步时出现主键冲突。

注:可以在my.cnf文件中添加“binlog_do_db=数据库名”配置项(可以添加多个)来指定要同步的数据库 

  
  • 1
  • 2
  • 3

3、将mysql2设置为mysql1的从服务器

1)mysql1上创建授权用户

[root@mysql1 ~]# mysql -uroot -p123.com
mysql> grant replication slave on *.* to rep@'192.168.20.%' identified by '123.com'; 

  
  • 1
  • 2

2)查看mysql1的当前binlog状态信息

mysql> show master status\G
*************************** 1. row ***************************
             File: log_bin.000001     #这个值会用到
         Position: 609         #这个值会用到
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)



  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3)在mysql2上指定mysql1为master,并开启slave功能

#指定master地址
mysql> change master to master_host='192.168.100.2',
    -> master_user='rep',
    -> master_password='123.com',
    -> master_log_file='log_bin.000001',    #必须和master上查看到的名字一样
    -> master_log_pos=609;      #同上,这个值也是在master上查看到的
#启动slave功能
mysql> start slave;
#确定配置成功
mysql> show slave status\G            #查看slave状态
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.2
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log_bin.000001
          Read_Master_Log_Pos: 609
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 318
        Relay_Master_Log_File: log_bin.000001
             Slave_IO_Running: Yes               # 这个值必须为Yes
            Slave_SQL_Running: Yes             # 这个值也必须为Yes
#只要上面两个值为yes,则表示主从没有问题,
#其中,IO线程是去master上面读取二进制日志到本地的中继日志中;
SQL线程是将本地的中继日志中的内容转换为sql语句并执行。
 

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

4、将mysql1设置为mysql2的从服务器

#主机mysql2上操作如下:
mysql> grant replication slave on *.* to rep@'192.168.100.%' identified by '123.com';
mysql> flush privileges;
mysql> show master status\G          #获取所需的file和Position
*************************** 1. row ***************************
             File: log_bin.000002
         Position: 609
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 
1 row in set (0.00 sec)
 
#主机mysql1上操作如下:
#指定mysql2为master
mysql> change master to master_host='192.168.100.3',
    -> master_user='rep',
    -> master_password='123.com',
    -> master_log_file='log_bin.000002',
    -> master_log_pos=609;
mysql> start slave;       #启动slave
mysql> show slave status\G          #查看slave状态
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.100.3
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: log_bin.000002
          Read_Master_Log_Pos: 609
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 318
        Relay_Master_Log_File: log_bin.000002
                #确保下面两个值为yes
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
 

  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

5、测试主主同步

1)主机mysql1创建测试数据


mysql> create database test;
mysql> use test
mysql> create table test1(id int,name varchar(4));
mysql> insert into t1 values(1,'a'),(2,'b');
#确认mysql1的数据
mysql> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
+------+------+
2 rows in set (0.00 sec)


  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2)确认mysql2已经同步并插入新的数据

#以下操作在主机mysql2上进行
mysql> select * from test1;        #确定数据已同步
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
+------+------+
#插入数据测试
mysql> insert into test1 values(3,'c'),(4,'d');
mysql> select * from test1;        #确定最新数据
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
+------+------+
  


  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3)确定mysql1可以同步mysql2的数据

#在mysql1上查询,是否同步mysql2主机上的数据
mysql> select * from test1;
+------+------+
| id   | name |
+------+------+
|    1 | a    |
|    2 | b    |
|    3 | c    |
|    4 | d    |
+------+------+
4 rows in set (0.00 sec)


  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

至此,现在任何一台MySQL上更新数据都会同步到另一台MySQL,MySQL同步完成。

注:若主MySQL服务器已经存在,只是后期业务拓展才搭建从服务器,在配置数据库同步前应先将MySQL服务器的要同步的数据库拷贝到从服务器上(如先在主MySQL上备份数据库,再用备份再从MySQL服务器上恢复)。

二、配置keepalived高可用

1、安装keepalived

两个节点都需要执行以下命令,以便安装keepalived。

[root@mysql1 ~]# yum -y install keepalived


  
  • 1
  • 2

2、修改主机mysql1的keepalived配置文件

[root@mysql1 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
 
global_defs {
   router_id mysql-1      #此处的值必须唯一
}
 
vrrp_instance VI_1 {
    state BACKUP       #指定角色为backup,两台MySQL服务器的角色均为backup,设置backup将根据优先级决定主从
 
    interface ens33      #指定承载虚拟IP的网卡
    virtual_router_id 51         #指定组,同一个集群内的值必须一致。并且不可和局域网中的其他组冲突
    priority 100          #优先级范围为:0~100
    advert_int 1     #发vrrp包的时间间隔,即多久进行一次master选举(可认为是健康检查时间间隔)
    nopreempt             #不抢占,即允许一个priority比较低的节点作为master,     
    authentication {          #认证区域
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {         #VIP区域,指定vip地址
        192.168.100.20
    }
}
 
virtual_server 192.168.100.100 3306 {    #设置虚拟服务器,需要指定虚拟IP地址和服务端口,IP与端口之间用空格隔开
    delay_loop 2         #设置运行情况检查时间,单位是秒
    lb_algo rr      #设置后端调度算法
    lb_kind DR    #设置lvs实现负载均衡的机制,有NATTUNDR三个模式,DR模式效率最高
    persistence_timeout 60     #会话保持时间,单位是秒
    protocol TCP     #指定转发协议类型,有TCPUDP两种
 
    real_server 192.168.100.2 3306 {          #配置服务节点,这里指定的也就是本机的真实IP
        weight 1     #设置权重
    notify_down /etc/keepalived/bin/mysql.sh    #检测到real_server的MySQL服务宕机后执行的脚本。
    TCP_CHECK {
        connect_port 3306    #健康检查端口
        connect_timeout 3       #连接超时时间
        retry 3    #重试次数
        delay_before_retry 3      #重连间隔时间
     }
   }
}
#准备指定的脚本
[root@mysql01 keepalived]# pwd
/etc/keepalived
[root@mysql01 keepalived]# mkdir bin
[root@mysql01 keepalived]# vim bin/mysql.sh
#!/bin/bash
pkill keepalived    #停止keepalived服务
[root@mysql01 keepalived]# chmod +x bin/mysql.sh    #赋予脚本执行权限
[root@mysql01 ~]# systemctl start keepalived        #启动keepalived服务

 



  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

3、确定ens33网卡有虚拟Ip

[root@mysql01 ~]# ip a show ens33 #必须使用ip a命令才可以查看到,ifconfig命令查看不到
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:c0:39:80 brd ff:ff:ff:ff:ff:ff
inet 192.168.20.2/24 brd 192.168.20.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.20.20/32 scope global ens33 #可以看到指定的VIP已经绑定到ens33上
valid_lft forever preferred_lft forever
inet6 fe80::659e:9312:318a:e52b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#将keepalived的配置文件发送到mysql2主机上
[root@mysql01 ~]# scp /etc/keepalived/keepalived.conf root@192.168.100.3:/etc/keepalived/

4、修改主机mysql2的keepalived配置文件

#修改msyql1发送来的配置文件
[root@mysql02 keepalived]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
 
global_defs {
   router_id mysql-2         #更改router_id,此处在热备组中必须要唯一
}
 
vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 90             #更改优先级
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.100.20
    }
}
 
virtual_server 192.168.100.20 3306 {
    delay_loop 2
    lb_algo rr
    lb_kind DR
    persistence_timeout 60
    protocol TCP
 
    real_server 192.168.100.3 3306 {        #更改为本机的IP地址及监听端口
        weight 1
    notify_down /etc/keepalived/bin/mysql.sh
    TCP_CHECK {
        connect_port 3306
        connect_timeout 3
        retry 3
        delay_before_retry 3
     }
   }
}
#准备所需脚本
[root@mysql1 keepalived]# pwd
/etc/keepalived
[root@mysql2 keepalived]# mkdir bin
[root@mysql2 keepalived]# vim bin/mysql.sh
#!/bin/bash
pkill keepalived
[root@mysql2 keepalived]# chmod +x bin/mysql.sh 
#启动keepalived
[root@mysql2 ~]# systemctl start keepalived 


  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

三 最终总结

至此,即可实现MySQL的双主效果(只要VIP所在的节点,MySQL服务端口无法连接,
 那么VIP将切换至另一台节点,即使宕机的mysql服务器恢复,也不会对VIP进行抢占)。
 虽然有两台MySQL数据库,但是其使用keepalived提供的虚拟IP地址来对外提供服务,
 不管这个虚拟Ip地址落在哪台服务器上,
 都可以保证数据的一致性,因为它们互为主从,
 并且keepalived的状态都为backup,
 也设置了不抢占(减少VIP的切换次数),
 这样可以大大的避免keepalived的脑裂问题。


转载请标明出处【MySQL双主-互为主从+Keepalive集群高可用方案部署】。

《www.micoder.cc》 虚拟化云计算,系统运维,安全技术服务.

网站已经关闭评论