阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

使用Keepalived实现MySQL双主高可用

228次阅读
没有评论

共计 10965 个字符,预计需要花费 28 分钟才能阅读完成。

MySQL 双主配置

环境准备:

OS:CentOS7
master:192.168.1.10
backup:192.168.1.20
  VIP:192.168.1.30

一、安装 MySQL 数据库.

在 master 和 backup 上安装 mysql, 安装完后自动启动,mysql root 密码为 123456

二、修改 MySQL 配置文件:

1.master 端配置文件如下:

1.master 端配置文件如下:

# vim /etc/my.cnf                                              #添加
server_id = 1                                                  #backup 上设置为 2
log-bin = /data/mysql/mysql-bin
log-bin-index=/data/mysql/my-bin.index
binlog-ignore-db = mysql,information_schema  #忽略写入 binlog 日志的库
auto-increment-increment = 2                        #字段变化增量值
auto-increment-offset = 1                              #初始字段 ID 为 1
slave-skip-errors = all                                #忽略所有复制产生的错误

# systemctl restart mysqld

2. backup 端配置文件如下:

master 端和 backup 端配置只有 server_id 不一样,别的都一致.

三、创建数据同步用户并查看 log bin 日志和 pos 位置:

1.> master 上创建 mysql 同步账号并查看 log bin 日志和 pos 位置:

# mysql -uroot -p123456

mysql> GRANT  REPLICATION SLAVE ON *.* TO ‘repl’@’192.168.1.%’ IDENTIFIED  BY ‘repl’;

mysql> flush  privileges;

mysql> show master status;
+——————+———-+————–+————————–+——————-+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB        | Executed_Gtid_Set |
+——————+———-+————–+————————–+——————-+
| mysql-bin.000001 |      618 |              | mysql,information_schema |                  |
+——————+———-+————–+————————–+——————-+

master 配置如下:

# mysql -uroot -p123456

mysql> change master to
    -> master_host=’192.168.1.20′,                #这里填 backup 的 IP
    -> master_user=’repl’,
    -> master_password=’repl’,
    -> master_log_file=’mysql-bin.000001′,
    -> master_log_pos=618;

mysql> start slave;

2.> backup 上创建 mysql 同步账号配置如下:

# mysql -uroot -p123456

mysql> GRANT  REPLICATION SLAVE ON *.* TO ‘repl’@’192.168.1.%’ IDENTIFIED  BY ‘repl’;

mysql> flush  privileges;

mysql> change master to
    -> master_host=’192.168.1.10′,                #这里填 master 的 IP
    -> master_user=’repl’,
    -> master_password=’repl’,
    -> master_log_file=’mysql-bin.000001′,
    -> master_log_pos=618;

mysql> start slave;
———————

分别查看同步状态:

master 查看:

mysql> show slave status\G;
*************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.20
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 1082
              Relay_Log_File: test2-relay-bin.000002
                Relay_Log_Pos: 784
        Relay_Master_Log_File: mysql-bin.000001
            Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
———————

backup 查看:

mysql> show slave status\G;
*************************** 1. row ***************************
              Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.10
                  Master_User: replication
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 618
              Relay_Log_File: test3-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000001
            Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
———————

Slave_IO 和 Slave_SQL 是 YES 说明主主同步成功。

 四、MySQL 主主同步测试

master 上插入数据测试:

mysql> create database testdb;

mysql> use testdb;

mysql> create table user (number INT(10),name VARCHAR(255));

mysql> insert into user values(01,’testid’);

mysql> show tables;
+—————-+
| Tables_in_test |
+—————-+
| user          |
+—————-+
———————

backup 上查看:

mysql> show databases;
+——————–+
| Database          |
+——————–+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| testdb              |
+——————–+

mysql> use testdb;

mysql> show tables;
+—————-+
| Tables_in_test |
+—————-+
| user          |
+—————-+

mysql> select number,name from user;
+——–+——+
| number | name |
+——–+——+
|      1 | testid  |
+——–+——+
———————

可以看到已经成功同步过去,同样在 backup 插入到 user 表数据,一样同步过去,双主配置没有问题。

五、配置 keepalived 实现双机热备

1.master 安装 keepalived 并配置:

# yum install -y keepalived

# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
  notification_email {
    admin@test.com
  }
  notification_email_from admin@test.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              #优先级,master 设置为 100
    advert_int 1
    nopreempt                  #不主动抢占资源,只在 master 上设置
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.30
    }
}

virtual_server 192.168.1.30 3306 {
    delay_loop 2
    #lb_algo rr
    #lb_kind NAT
    persistence_timeout 50
    protocol TCP

    real_server 192.168.1.10 3306 {#检测本地 mysql
        weight 3
        notify_down /tmp/mysql.sh              #当 mysql 服务 down 时,执行此脚本,杀死 keepalived 实现切换
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

backup 安装 keepalived 并配置:

# yum install -y keepalived

# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
  notification_email {
    admin@test.com
  }
  notification_email_from admin@test.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                #优先级,backup 设置为 90
    advert_int 1
    #nopreempt                #主动抢占资源
    authentication {
        auth_type PASS
        auth_pass 1111
    } 
    virtual_ipaddress {
        192.168.1.30
    } 

virtual_server 192.168.1.30 3306 {
    delay_loop 2
    #lb_algo rr
    #lb_kind NAT
    persistence_timeout 50
    protocol TCP
   
    real_server 192.168.1.20 3306 {#检测本地 mysql
        weight 3
        notify_down /tmp/mysql.sh                #当 mysql 服务 down 时,执行此脚本,杀死 keepalived 实现切换
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        } 
    } 
}

master 和 backup 上编辑 mysql.sh

# vim /tmp/mysql.sh

#!/bin/bash
pkill keepalived

# chmod +x !$
# systemctl start keepalived

两台 mysql 服务器授权允许 root 远程登录:

# mysql -uroot -p123456789

mysql> grant all on *.* to ‘root’@’192.168.1.%’ identified by ‘123456’;

mysql> flush privileges;

测试高可用
通过 mysql 客户端通过 VIP 连接,看是否连接成功。
这里我用同网段的另一台机器,连接测试:

# mysql -h192.168.1.30 -uroot -p123456

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

mysql> select * from test.user;
+——–+——+
| number | name |
+——–+——+
|      1 | testid  |
+——–+——+
1 row in set (0.01 sec)
———————

可以看到,连接成功,且查询数据没有问题,停止 master 上 mysql 服务,是否能正常切换到 backup 上,可以使用 ip addr 命令来查看 VIP 在哪台服务器上。

master 上查看是否有 VIP, 可以看到 VIP 在 master 上

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:cf:ab:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global noprefixroute eth0
      valid_lft forever preferred_lft forever
    inet 192.168.1.30/32 scope global eth0
      valid_lft forever preferred_lft forever
    inet6 fe80::fe8e:3c2f:4d32:e9fd/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
———————

停掉 master 上 mysql 服务:

# systemctl stop mysqld

# ps axu |grep keepalived
root      11074  0.0  0.0 112708  988 pts/1    S+  15:28  0:00 grep –color=autokeepalived

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:cf:ab:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global noprefixroute eth0
      valid_lft forever preferred_lft forever
    inet6 fe80::fe8e:3c2f:4d32:e9fd/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
———————

可以看到,keepalived 在 mysql 服务停掉之后也被停掉,VIP 不在 master 上。

backup 上查看是否有 VIP,可以看到 VIP 在 backup 上。

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:33:80:d5 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.20/24 brd 192.168.1.255 scope global noprefixroute eth0
      valid_lft forever preferred_lft forever
    inet 192.168.1.30/32 scope global eth0
      valid_lft forever preferred_lft forever
    inet6 fe80::4b20:2e16:a957:f9a1/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
———————

查看 /var/log/messages 日志,可以看到主备切换过程:

Apr  8 15:27:16 hosts systemd: Stopping MySQL Server…
Apr  8 15:27:16 hosts Keepalived_healthcheckers[11048]: TCP connection to [192.168.1.10]:3306 failed.
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: TCP connection to [192.168.1.10]:3306 failed.
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Check on service [192.168.1.10]:3306 failed after 1 retry.
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Removing service [192.168.1.10]:3306 from VS [192.168.1.30]:3306
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: IPVS (cmd 1160, errno 2): No such destination
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Executing [/tmp/mysql.sh] for service [192.168.1.10]:3306 in VS [192.168.1.30]:3306
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Lost quorum 1-0=1 > 0 for VS [192.168.1.30]:3306
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Remote SMTP server [127.0.0.1]:25 connected.
Apr  8 15:27:19 hosts Keepalived_vrrp[11049]: VRRP_Instance(VI_1) sent 0 priority
Apr  8 15:27:19 hosts Keepalived_vrrp[11049]: VRRP_Instance(VI_1) removing protocol VIPs.
Apr  8 15:27:19 hosts Keepalived[11047]: Stopping
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: IPVS (cmd 1156, errno 2): No such file or directory
Apr  8 15:27:19 hosts Keepalived_healthcheckers[11048]: Stopped
Apr  8 15:27:20 hosts Keepalived_vrrp[11049]: Stopped
Apr  8 15:27:20 hosts Keepalived[11047]: Stopped Keepalived v1.3.5 (03/19,2017), git commit v1.3.5-6-g6fa32f2
Apr  8 15:27:27 hosts systemd: Stopped MySQL Server.
———————

恢复 master 服务器故障,看是否主动抢占资源,成为活动服务器。

master 上启动 mysql 服务和 keepalived 服务:

# systemctl start mysqld

# systemctl start keepalived

# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
      valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
      valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:cf:ab:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.10/24 brd 192.168.1.255 scope global noprefixroute eth0
      valid_lft forever preferred_lft forever
    inet6 fe80::fe8e:3c2f:4d32:e9fd/64 scope link noprefixroute
      valid_lft forever preferred_lft forever
———————

可以看到,即使 master 故障恢复,也没有抢占资源,VIP 仍然在 backup 上,这是因为之前已经配置了 master 为非抢占模式(nopreempt)。

不过需要注意的是:

nopreempt 这个参数只能用于 state 为 BACKUP 的情况,所以在配置的时候要把 master 和 backup 的 state 都设置成 BACKUP,这样才会实现 keepalived 的非抢占模式!

也就是说:

* 当 state 状态一个为 MASTER,一个为 BACKUP 的时候,加不加 nopreempt 这个参数都是一样的效果。即都是根据 priority 优先级来决定谁抢占 vip 资源的,是抢占模式!

* 当 state 状态都设置成 BACKUP,如果不配置 nopreempt 参数,那么也是看 priority 优先级决定谁抢占 vip 资源,即也是抢占模式。

* 当 state 状态都设置成 BACKUP,如果配置 nopreempt 参数,那么就不会去考虑 priority 优先级了,是非抢占模式!即只有 vip 当前所在机器发生故障,另一台机器才能接管 vip。
 即使优先级高的那一台机器恢复正常后也不会主动抢回 vip,只能等到对方发生故障,才会将 vip 切回来。

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计10965字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中