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

MySQL高可用解决方案MMM

237次阅读
没有评论

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

一、MMM 简介:

MMM 即 Multi-Master Replication Manager for MySQL:mysql 多主复制管理器,基于 perl 实现,关于 mysql 主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入),MMM 也能对从服务器进行读负载均衡,所以可以用它来在一组用于复制的服务器启动虚拟 ip,除此之外,它还有实现数据备份、节点之间重新同步功能的脚本。MySQL 本身没有提供 replication failover 的解决方案,通过 MMM 方案能实现服务器的故障转移,从而实现 mysql 的高可用。MMM 不仅能提供浮动 IP 的功能,如果当前的主服务器挂掉后,会将你后端的从服务器自动转向新的主服务器进行同步复制,不用手工更改同步配置。这个方案是目前比较成熟的解决方案。详情请看官网:http://mysql-mmm.org

MySQL 高可用解决方案 MMM

优点:高可用性,扩展性好,出现故障自动切换,对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性。当主服务器挂掉以后,另一个主立即接管,其他的从服务器能自动切换,不用人工干预。

缺点:monitor 节点是单点,不过这个你也可以结合 keepalived 或者 haertbeat 做成高可用; 至少三个节点,对主机的数量有要求,需要实现读写分离, 还需要在前端编写读写分离程序。在读写非常繁忙的业务系统下表现不是很稳定,可能会出现复制延时、切换失效等问题。MMM 方案并不太适应于对数据安全性要求很高,并且读、写繁忙的环境中。

适用场景:

MMM 的适用场景为数据库访问量大,并且能实现读写分离的场景。

Mmm 主要功能由下面三个脚本提供:

mmm_mond  负责所有的监控工作的监控守护进程,决定节点的移除 (mmm_mond 进程定时心跳检测,失败则将 write ip 浮动到另外一台 master) 等等

mmm_agentd  运行在 mysql 服务器上的代理守护进程,通过简单远程服务集提供给监控节点

mmm_control  通过命令行管理 mmm_mond 进程

在整个监管过程中,需要在 mysql 中添加相关授权用户,授权的用户包括一个 mmm_monitor 用户和一个 mmm_agent 用户,如果想使用 mmm 的备份工具则还要添加一个 mmm_tools 用户。

二、部署实施

1、环境介绍

OS:CentOS7.2(64 位)数据库系统:mysql5.7.13

关闭 selinux

配置 ntp,同步时间

 

角色

IP

hostname

Server-id

Write vip

Read vip

Master1

192.168.31.83

master1

1

192.168.31.2

 

Master2(backup)

192.168.31.141

master2

2

 

192.168.31.3

Slave1

192.168.31.250

slave1

3

 

192.168.31.4

Slave2

192.168.31.225

slave2

4

 

192.168.31.5

monitor

192.168.31.106

monitor1

  

 

2、在所有主机上配置 /etc/hosts 文件,添加如下内容:

192.168.31.83 master1

192.168.31.141 master2

192.168.31.250 slave1

192.168.31.225 slave2

192.168.31.106 monitor1

在所有主机上安装 perl、perl-develperl-CPAN libart_lgpl.x86_64 rrdtool.x86_64  rrdtool-perl.x86_64 包

#yum -y install perl-*  libart_lgpl.x86_64  rrdtool.x86_64  rrdtool-perl.x86_64

注:使用 centos7 在线 yum 源安装

安装 perl 的相关库

#cpan -i Algorithm::Diff Class::Singleton DBI DBD::mysql Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Time::HiRes Params::Validate Net::ARP

3、在 master1、master2、slave1、slave2 主机上安装 mysql5.7 和配置复制

master1 和 master2 互为主从,slave1、slave2 为 master1 的从

在每个 mysql 的配置文件 /etc/my.cnf 中加入以下内容,注意 server_id 不能重复。

master1 主机:

log-bin = mysql-bin

binlog_format = mixed

server-id = 1

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

log-slave-updates = 1

auto-increment-increment = 2

auto-increment-offset = 1

master2 主机:

log-bin = mysql-bin

binlog_format = mixed

server-id = 2

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

log-slave-updates = 1

auto-increment-increment = 2

auto-increment-offset = 2

slave1 主机:

server-id = 3

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

read_only   = 1

slave2 主机:

server-id = 4

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

read_only   = 1

在完成了对 my.cnf 的修改后,通过 systemctl restart mysqld 重新启动 mysql 服务

4 台数据库主机若要开启防火墙,要么关闭防火墙或者创建访问规则:

firewall-cmd –permanent –add-port=3306/tcp

firewall-cmd –reload

主从配置(master1 和 master2 配置成主主,slave1 和 slave2 配置成 master1 的从):

在 master1 上授权:

mysql> grant replication slave on *.* to rep@’192.168.31.%’ identified by ‘123456’;

在 master2 上授权:

mysql> grant replication slave on *.* to rep@’192.168.31.%’ identified by ‘123456’;

把 master2、slave1 和 slave2 配置成 master1 的从库:

在 master1 上执行 show master status; 获取 binlog 文件和 Position 点

mysql> show master status;

+——————+———-+————–+——————+————————————————–+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+——————+———-+————–+——————+—————————————————+

| mysql-bin.000001 |      452 |              |          |                   |

+——————+———-+————–+——————+—————————————————–+

在 master2、slave1 和 slave2 执行

mysql> change master to master_host=’192.168.31.83′,master_port=3306,master_user=’rep’,master_password=’123456′,master_log_file=’mysql-bin.000001′,master_log_pos=452;

mysql>slave start;

验证主从复制:

master2 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

slave1 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

slave2 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果 Slave_IO_Running 和 Slave_SQL_Running 都为 yes,那么主从就已经配置 OK 了

把 master1 配置成 master2 的从库:

在 master2 上执行 show master status ; 获取 binlog 文件和 Position 点

mysql> show master status;

+——————+———-+————–+——————+————————————————–+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+——————+———-+————–+——————+—————————————————+

| mysql-bin.000001 |      452 |              |           |                   |

+——————+———-+————–+——————+—————————————————-+

在 master1 上执行:

mysql> change master to master_host=’192.168.31.141′,master_port=3306,master_user=’rep’,master_password=’123456′,master_log_file=’mysql-bin.000001′,master_log_pos=452;

mysql> start slave;

验证主从复制:

master1 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.141

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果 Slave_IO_Running 和 Slave_SQL_Running 都为 yes,那么主从就已经配置 OK 了

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-04/142613p2.htm

4、MySQL-mmm 配置:

在 4 台 mysql 节点上创建用户

创建代理账号:

mysql> grant super,replicationclient,process on *.* to ‘mmm_agent’@’192.168.31.%’ identified by ‘123456’;

创建监控账号:

mysql> grant replication client on *.* to ‘mmm_monitor’@’192.168.31.%’ identified by ‘123456’;

注 1:因为之前的主从复制,以及主从已经是 ok 的,所以我在 master1 服务器执行就 ok 了。

检查 master2 和 slave1、slave2 三台 db 上是否都存在监控和代理账号

mysql> select user,host from mysql.user where user in (‘mmm_monitor’,’mmm_agent’);

+————-+—————————-+

| user        | host         |

+————-+—————————-+

| mmm_agent   | 192.168.31.% |

| mmm_monitor | 192.168.31.% |

+————-+——————————+

mysql> show grants for ‘mmm_agent’@’192.168.31.%’;

+—————————————————————————————————————————–+

| Grants for mmm_agent@192.168.31.%                                             |

+—————————————————————————————————————————–+

| GRANT PROCESS, SUPER, REPLICATION CLIENT ON *.* TO ‘mmm_agent’@’192.168.31.%’ |

+—————————————————————————————————————————–+

mysql> show grants for ‘mmm_monitor’@’192.168.31.%’;

+—————————————————————————————————————————–+

| Grants for mmm_monitor@192.168.31.%                             |

+—————————————————————————————————————————–+

| GRANT REPLICATION CLIENT ON *.* TO ‘mmm_monitor’@’192.168.31.%’ |

注 2:

mmm_monitor 用户:mmm 监控用于对 mysql 服务器进程健康检查

mmm_agent 用户:mmm 代理用来更改只读模式,复制的主服务器等

5、mysql-mmm 安装

在 monitor 主机(192.168.31.106) 上安装监控程序

cd /tmp

wget http://pkgs.Fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz

tar -zxf mysql-mmm-2.2.1.tar.gz

cd mysql-mmm-2.2.1

make install

在数据库服务器 (master1、master2、slave1、slave2) 上安装代理

cd /tmp

wget http://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz

tar -zxf mysql-mmm-2.2.1.tar.gz

cd mysql-mmm-2.2.1

make install

6、配置 mmm

编写配置文件,五台主机必须一致:

完成安装后,所有的配置文件都放到了 /etc/mysql-mmm/ 下面。管理服务器和数据库服务器上都要包含一个共同的文件 mmm_common.conf,内容如下:

active_master_rolewriter# 积极的 master 角色的标示,所有的 db 服务器要开启 read_only 参数,对于 writer 服务器监控代理会自动将 read_only 属性关闭。

<host default>

cluster_interfaceeno16777736# 群集的网络接口

pid_path       /var/run/mmm_agentd.pid#pid 路径

bin_path       /usr/lib/mysql-mmm/# 可执行文件路径

replication_user        rep# 复制用户

replication_password    123456# 复制用户密码

agent_usermmm_agent# 代理用户

agent_password      123456# 代理用户密码

</host>

<host master1>#master1 的 host 名

ip     192.168.31.83#master1 的 ip

        mode       master# 角色属性,master 代表是主

        peer    master2# 与 master1 对等的服务器的 host 名,也就是 master2 的服务器 host 名

</host>

<host master2># 和 master 的概念一样

ip       192.168.31.141

mode       master

peer     master1

</host>

<host slave1># 从库的 host 名, 如果存在多个从库可以重复一样的配置

ip      192.168.31.250# 从的 ip

        mode     slave#slave 的角色属性代表当前 host 是从

</host>

<host slave2># 和 slave 的概念一样

ip      192.168.31.225

mode    slave

</host>

<role writer>#writer 角色配置

        hosts      master1,master2# 能进行写操作的服务器的 host 名,如果不想切换写操作这里可以只配置 master, 这样也可以避免因为网络延时而进行 write 的切换,但是一旦 master 出现故障那么当前的 MMM 就没有 writer 了只有对外的 read 操作。

ips    192.168.31.2# 对外提供的写操作的虚拟 IP

        mode   exclusive#exclusive 代表只允许存在一个主,也就是只能提供一个写的 IP

</role>

<role reader>#read 角色配置

        hosts   master2,slave1,slave2# 对外提供读操作的服务器的 host 名, 当然这里也可以把 master 加进来

ips      192.168.31.3, 192.168.31.4, 192.168.31.5# 对外提供读操作的虚拟 ip,这三个 ip 和 host 不是一一对应的, 并且 ips 也 hosts 的数目也可以不相同,如果这样配置的话其中一个 hosts 会分配两个 ip

        mode      balanced#balanced 代表负载均衡

</role>

同时将这个文件拷贝到其它的服务器,配置不变

#for host in master1 master2 slave1 slave2 ; do scp /etc/mysql-mmm/mmm_common.conf $host:/etc/mysql-mmm/ ; done

代理文件配置

编辑 4 台 mysql 节点机上的 /etc/mysql-mmm/mmm_agent.conf 
在数据库服务器上,还有一个 mmm_agent.conf 需要修改,其内容是:

includemmm_common.conf

this master1

注意:这个配置只配置 db 服务器,监控服务器不需要配置,this 后面的 host 名改成当前服务器的 主机名。

启动代理进程 

在 /etc/init.d/mysql-mmm-agent 的脚本文件的 #!/bin/sh 下面,加入如下内容 
source /root/.bash_profile
 

添加成系统服务并设置为自启动

#chkconfig –add mysql-mmm-agent

#chkconfigmysql-mmm-agent on

#/etc/init.d/mysql-mmm-agent start

注:添加 source /root/.bash_profile 目的是为了 mysql-mmm-agent 服务能启机自启。

自动启动和手动启动的唯一区别,就是激活一个 console。那么说明在作为服务启动的时候,可能是由于缺少环境变量

服务启动失败,报错信息如下:

Daemon bin: ‘/usr/sbin/mmm_agentd’

Daemon pid: ‘/var/run/mmm_agentd.pid’

Starting MMM Agent daemon… Can’t locate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/mmm_agentd line 7.

BEGIN failed–compilation aborted at /usr/sbin/mmm_agentd line 7.

failed

解决方法:

# cpanProc::Daemon
# cpan Log::Log4perl

# /etc/init.d/mysql-mmm-agent start

Daemon bin: ‘/usr/sbin/mmm_agentd’

Daemon pid: ‘/var/run/mmm_agentd.pid’

Starting MMM Agent daemon… Ok

# netstat -antp | grep mmm_agentd

tcp  0   0 192.168.31.83:9989    0.0.0.0:*   LISTEN      9693/mmm_agentd

配置防火墙

firewall-cmd –permanent –add-port=9989/tcp

firewall-cmd –reload

编辑 monitor 主机上的 /etc/mysql-mmm/mmm_mon.conf 

includemmm_common.conf

 

<monitor>

ip    127.0.0.1## 为了安全性,设置只在本机监听,mmm_mond 默认监听 9988

pid_path      /var/run/mmm_mond.pid

bin_path      /usr/lib/mysql-mmm/

status_path/var/lib/misc/mmm_mond.status

ping_ips192.168.31.83,192.168.31.141,192.168.31.250,192.168.31.225# 用于测试网络可用性 IP 地址列表,只要其中有一个地址 ping 通,就代表网络正常,这里不要写入本机地址

auto_set_online  0# 设置自动 online 的时间,默认是超过 60s 就将它设置为 online,默认是 60s,这里将其设为 0 就是立即 online

</monitor>

 

<check default>

check_period    5

trap_period     10

timeout         2

    #restart_after     10000

max_backlog     86400

</check>

check_period

描述:检查周期默认为5s

默认值:5s

trap_period

描述:一个节点被检测不成功的时间持续 trap_period 秒,就慎重的认为这个节点失败了。

默认值:10s

timeout

描述:检查超时的时间

默认值:2s

restart_after

描述:在完成 restart_after 次检查后,重启 checker 进程

默认值:10000

max_backlog

描述:记录检查 rep_backlog 日志的最大次数

默认值:60

 

<host default>

monitor_usermmm_monitor# 监控 db 服务器的用户

monitor_password  123456# 监控 db 服务器的密码

</host>

debug 0#debug 0 正常模式,1 为 debug 模式

启动监控进程:

在 /etc/init.d/mysql-mmm-agent 的脚本文件的 #!/bin/sh 下面,加入如下内容 
source /root/.bash_profile
 

添加成系统服务并设置为自启动

#chkconfig –add mysql-mmm-monitor

#chkconfigmysql-mmm-monitor on

#/etc/init.d/mysql-mmm-monitor start

启动报错:

Starting MMM Monitor daemon: Can not locate Proc/Daemon.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/sbin/mmm_mond line 11.
BEGIN failed–compilation aborted at /usr/sbin/mmm_mond line 11.

failed

解决方法:安装下列 perl 的库

#cpanProc::Daemon

#cpan Log::Log4perl

[root@monitor1 ~]# /etc/init.d/mysql-mmm-monitor start

Daemon bin: ‘/usr/sbin/mmm_mond’

Daemon pid: ‘/var/run/mmm_mond.pid’

Starting MMM Monitor daemon: Ok

[root@monitor1 ~]# netstat -anpt | grep 9988

tcp  0  0 127.0.0.1:9988   0.0.0.0:*      LISTEN      8546/mmm_mond

注 1:无论是在 db 端还是在监控端如果有对配置文件进行修改操作都需要重启代理进程和监控进程。

注 2:MMM 启动顺序:先启动 monitor,再启动 agent

检查集群状态:

[root@monitor1 ~]# mmm_control show

master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2)

master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5)

slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4)

slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3)

如果服务器状态不是 ONLINE,可以用如下命令将服务器上线,例如:

#mmm_controlset_online 主机名

例如:[root@monitor1 ~]#mmm_controlset_onlinemaster1

从上面的显示可以看到,写请求的 VIP 在 master1 上,所有从节点也都把 master1 当做主节点。

查看是否启用 vip

[root@master1 ~]# ipaddr show dev eno16777736

eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdiscpfifo_fast state UP qlen 1000

link/ether 00:0c:29:6d:2f:82 brdff:ff:ff:ff:ff:ff

inet 192.168.31.83/24 brd 192.168.31.255 scope global eno16777736

valid_lft forever preferred_lft forever

inet 192.168.31.2/32 scope global eno16777736

valid_lft forever preferred_lft forever

    inet6 fe80::20c:29ff:fe6d:2f82/64 scope link

valid_lft forever preferred_lft forever

[root@master2 ~]# ipaddr show dev eno16777736

eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdiscpfifo_fast state UP qlen 1000

link/ether 00:0c:29:75:1a:9c brdff:ff:ff:ff:ff:ff

inet 192.168.31.141/24 brd 192.168.31.255 scope global dynamic eno16777736

valid_lft 35850sec preferred_lft 35850sec

inet 192.168.31.5/32 scope global eno16777736

valid_lft forever preferred_lft forever

    inet6 fe80::20c:29ff:fe75:1a9c/64 scope link

valid_lft forever preferred_lft forever

[root@slave1 ~]# ipaddr show dev eno16777736

eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdiscpfifo_fast state UP qlen 1000

link/ether 00:0c:29:02:21:19 brdff:ff:ff:ff:ff:ff

inet 192.168.31.250/24 brd 192.168.31.255 scope global dynamic eno16777736

valid_lft 35719sec preferred_lft 35719sec

inet 192.168.31.4/32 scope global eno16777736

valid_lft forever preferred_lft forever

    inet6 fe80::20c:29ff:fe02:2119/64 scope link

valid_lft forever preferred_lft forever

[root@slave2 ~]# ipaddr show dev eno16777736

eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdiscpfifo_fast state UP qlen 1000

link/ether 00:0c:29:e2:c7:fa brdff:ff:ff:ff:ff:ff

inet 192.168.31.225/24 brd 192.168.31.255 scope global dynamic eno16777736

valid_lft 35930sec preferred_lft 35930sec

inet 192.168.31.3/32 scope global eno16777736

valid_lft forever preferred_lft forever

    inet6 fe80::20c:29ff:fee2:c7fa/64 scope link

valid_lft forever preferred_lft forever

在 master2,slave1,slave2 主机上查看主 mysql 的指向

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

MMM 高可用性测试:

服务器读写采有 VIP 地址进行读写,出现故障时 VIP 会漂移到其它节点,由其它节点提供服务。

首先查看整个集群的状态,可以看到整个集群状态正常

[root@monitor1 ~]# mmm_control show

master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2)

master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5)

slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4)

slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3)

模拟 master1 宕机,手动停止 mysql 服务,观察 monitor 日志,master1 的日志如下:

[root@monitor1 ~]# tail -f /var/log/mysql-mmm/mmm_mond.log

2017/01/09 22:02:55  WARN Check ‘rep_threads’ on ‘master1’ is in unknown state! Message: UNKNOWN: Connect error (host = 192.168.31.83:3306, user = mmm_monitor)! Can’t connect to MySQL server on ‘192.168.31.83’ (111)

2017/01/09 22:02:55  WARN Check ‘rep_backlog’ on ‘master1’ is in unknown state! Message: UNKNOWN: Connect error (host = 192.168.31.83:3306, user = mmm_monitor)! Can’t connect to MySQL server on ‘192.168.31.83’ (111)

2017/01/09 22:03:05 ERROR Check ‘mysql’ on ‘master1’ has failed for 10 seconds! Message: ERROR: Connect error (host = 192.168.31.83:3306, user = mmm_monitor)! Can’t connect to MySQL server on ‘192.168.31.83’ (111)

2017/01/09 22:03:07 FATAL State of host ‘master1’ changed from ONLINE to HARD_OFFLINE (ping: OK, mysql: not OK)

2017/01/09 22:03:07  INFO Removing all roles from host ‘master1’:

2017/01/09 22:03:07  INFO     Removed role ‘writer(192.168.31.2)’ from host ‘master1’

2017/01/09 22:03:07  INFO Orphaned role ‘writer(192.168.31.2)’ has been assigned to ‘master2’

查看群集的最新状态

[root@monitor1 ~]# mmm_control show

master1(192.168.31.83) master/HARD_OFFLINE. Roles:

master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5), writer(192.168.31.2)

slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4)

slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3)

从显示结果可以看出 master1 的状态有 ONLINE 转换为 HARD_OFFLINE,写 VIP 转移到了 master2 主机上。

检查所有的 db 服务器群集状态

[root@monitor1 ~]# mmm_control checks all

master1  ping         [last change: 2017/01/09 21:31:47]  OK

master1  mysql        [last change: 2017/01/09 22:03:07]  ERROR: Connect error (host = 192.168.31.83:3306, user = mmm_monitor)! Can’t connect to MySQL server on ‘192.168.31.83’ (111)

master1  rep_threads  [last change: 2017/01/09 21:31:47]  OK

master1  rep_backlog  [last change: 2017/01/09 21:31:47]  OK: Backlog is null

slave1   ping         [last change: 2017/01/09 21:31:47]  OK

slave1mysql        [last change: 2017/01/09 21:31:47]  OK

slave1   rep_threads  [last change: 2017/01/09 21:31:47]  OK

slave1   rep_backlog  [last change: 2017/01/09 21:31:47]  OK: Backlog is null

master2  ping         [last change: 2017/01/09 21:31:47]  OK

master2  mysql        [last change: 2017/01/09 21:57:32]  OK

master2  rep_threads  [last change: 2017/01/09 21:31:47]  OK

master2  rep_backlog  [last change: 2017/01/09 21:31:47]  OK: Backlog is null

slave2   ping         [last change: 2017/01/09 21:31:47]  OK

slave2mysql        [last change: 2017/01/09 21:31:47]  OK

slave2   rep_threads  [last change: 2017/01/09 21:31:47]  OK

slave2   rep_backlog  [last change: 2017/01/09 21:31:47]  OK: Backlog is null

从上面可以看到 master1 能 ping 通,说明只是服务死掉了。

查看 master2 主机的 ip 地址:

[root@master2 ~]# ipaddr show dev eno16777736

eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP>mtu 1500 qdiscpfifo_fast state UP qlen 1000

link/ether 00:0c:29:75:1a:9c brdff:ff:ff:ff:ff:ff

inet 192.168.31.141/24 brd 192.168.31.255 scope global dynamic eno16777736

valid_lft 35519sec preferred_lft 35519sec

inet 192.168.31.5/32 scope global eno16777736

valid_lft forever preferred_lft forever

inet 192.168.31.2/32 scope global eno16777736

valid_lft forever preferred_lft forever

    inet6 fe80::20c:29ff:fe75:1a9c/64 scope link

valid_lft forever preferred_lft forever

slave1 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.141

Master_User: rep

Master_Port: 3306

slave2 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.141

Master_User: rep

Master_Port: 3306

启动 master1 主机的 mysql 服务,观察 monitor 日志,master1 的日志如下:

[root@monitor1 ~]# tail -f /var/log/mysql-mmm/mmm_mond.log

2017/01/09 22:16:56  INFO Check ‘mysql’ on ‘master1’ is ok!

2017/01/09 22:16:56  INFO Check ‘rep_backlog’ on ‘master1’ is ok!

2017/01/09 22:16:56  INFO Check ‘rep_threads’ on ‘master1’ is ok!

2017/01/09 22:16:59 FATAL State of host ‘master1’ changed from HARD_OFFLINE to AWAITING_RECOVERY

从上面可以看到 master1 的状态由 hard_offline 改变为 awaiting_recovery 状态

用如下命令将服务器上线:

[root@monitor1 ~]#mmm_controlset_onlinemaster1

查看群集最新状态

[root@monitor1 ~]# mmm_control show

master1(192.168.31.83) master/ONLINE. Roles:

master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5), writer(192.168.31.2)

slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4)

slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3)

可以看到主库启动不会接管主,只到现有的主再次宕机。

总结

(1)master2 备选主节点宕机不影响集群的状态,就是移除了 master2 备选节点的读状态。
(2)master1 主节点宕机,由 master2 备选主节点接管写角色,slave1,slave2 指向新 master2 主库进行复制,slave1,slave2 会自动 change master 到 master2.
(3)如果 master1 主库宕机,master2 复制应用又落后于 master1 时就变成了主可写状态,这时的数据主无法保证一致性。
如果 master2,slave1,slave2 延迟于 master1 主,这个时 master1 宕机,slave1,slave2 将会等待数据追上 db1 后,再重新指向新的主 node2 进行复制操作,这时的数据也无法保证同步的一致性。
(4)如果采用 MMM 高可用架构,主,主备选节点机器配置一样,而且开启半同步进一步提高安全性或采用 MariaDB/mysql5.7 进行多线程从复制,提高复制的性能。

一、MMM 简介:

MMM 即 Multi-Master Replication Manager for MySQL:mysql 多主复制管理器,基于 perl 实现,关于 mysql 主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入),MMM 也能对从服务器进行读负载均衡,所以可以用它来在一组用于复制的服务器启动虚拟 ip,除此之外,它还有实现数据备份、节点之间重新同步功能的脚本。MySQL 本身没有提供 replication failover 的解决方案,通过 MMM 方案能实现服务器的故障转移,从而实现 mysql 的高可用。MMM 不仅能提供浮动 IP 的功能,如果当前的主服务器挂掉后,会将你后端的从服务器自动转向新的主服务器进行同步复制,不用手工更改同步配置。这个方案是目前比较成熟的解决方案。详情请看官网:http://mysql-mmm.org

MySQL 高可用解决方案 MMM

优点:高可用性,扩展性好,出现故障自动切换,对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性。当主服务器挂掉以后,另一个主立即接管,其他的从服务器能自动切换,不用人工干预。

缺点:monitor 节点是单点,不过这个你也可以结合 keepalived 或者 haertbeat 做成高可用; 至少三个节点,对主机的数量有要求,需要实现读写分离, 还需要在前端编写读写分离程序。在读写非常繁忙的业务系统下表现不是很稳定,可能会出现复制延时、切换失效等问题。MMM 方案并不太适应于对数据安全性要求很高,并且读、写繁忙的环境中。

适用场景:

MMM 的适用场景为数据库访问量大,并且能实现读写分离的场景。

Mmm 主要功能由下面三个脚本提供:

mmm_mond  负责所有的监控工作的监控守护进程,决定节点的移除 (mmm_mond 进程定时心跳检测,失败则将 write ip 浮动到另外一台 master) 等等

mmm_agentd  运行在 mysql 服务器上的代理守护进程,通过简单远程服务集提供给监控节点

mmm_control  通过命令行管理 mmm_mond 进程

在整个监管过程中,需要在 mysql 中添加相关授权用户,授权的用户包括一个 mmm_monitor 用户和一个 mmm_agent 用户,如果想使用 mmm 的备份工具则还要添加一个 mmm_tools 用户。

二、部署实施

1、环境介绍

OS:CentOS7.2(64 位)数据库系统:mysql5.7.13

关闭 selinux

配置 ntp,同步时间

 

角色

IP

hostname

Server-id

Write vip

Read vip

Master1

192.168.31.83

master1

1

192.168.31.2

 

Master2(backup)

192.168.31.141

master2

2

 

192.168.31.3

Slave1

192.168.31.250

slave1

3

 

192.168.31.4

Slave2

192.168.31.225

slave2

4

 

192.168.31.5

monitor

192.168.31.106

monitor1

  

 

2、在所有主机上配置 /etc/hosts 文件,添加如下内容:

192.168.31.83 master1

192.168.31.141 master2

192.168.31.250 slave1

192.168.31.225 slave2

192.168.31.106 monitor1

在所有主机上安装 perl、perl-develperl-CPAN libart_lgpl.x86_64 rrdtool.x86_64  rrdtool-perl.x86_64 包

#yum -y install perl-*  libart_lgpl.x86_64  rrdtool.x86_64  rrdtool-perl.x86_64

注:使用 centos7 在线 yum 源安装

安装 perl 的相关库

#cpan -i Algorithm::Diff Class::Singleton DBI DBD::mysql Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Time::HiRes Params::Validate Net::ARP

3、在 master1、master2、slave1、slave2 主机上安装 mysql5.7 和配置复制

master1 和 master2 互为主从,slave1、slave2 为 master1 的从

在每个 mysql 的配置文件 /etc/my.cnf 中加入以下内容,注意 server_id 不能重复。

master1 主机:

log-bin = mysql-bin

binlog_format = mixed

server-id = 1

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

log-slave-updates = 1

auto-increment-increment = 2

auto-increment-offset = 1

master2 主机:

log-bin = mysql-bin

binlog_format = mixed

server-id = 2

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

log-slave-updates = 1

auto-increment-increment = 2

auto-increment-offset = 2

slave1 主机:

server-id = 3

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

read_only   = 1

slave2 主机:

server-id = 4

relay-log = relay-bin

relay-log-index = slave-relay-bin.index

read_only   = 1

在完成了对 my.cnf 的修改后,通过 systemctl restart mysqld 重新启动 mysql 服务

4 台数据库主机若要开启防火墙,要么关闭防火墙或者创建访问规则:

firewall-cmd –permanent –add-port=3306/tcp

firewall-cmd –reload

主从配置(master1 和 master2 配置成主主,slave1 和 slave2 配置成 master1 的从):

在 master1 上授权:

mysql> grant replication slave on *.* to rep@’192.168.31.%’ identified by ‘123456’;

在 master2 上授权:

mysql> grant replication slave on *.* to rep@’192.168.31.%’ identified by ‘123456’;

把 master2、slave1 和 slave2 配置成 master1 的从库:

在 master1 上执行 show master status; 获取 binlog 文件和 Position 点

mysql> show master status;

+——————+———-+————–+——————+————————————————–+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+——————+———-+————–+——————+—————————————————+

| mysql-bin.000001 |      452 |              |          |                   |

+——————+———-+————–+——————+—————————————————–+

在 master2、slave1 和 slave2 执行

mysql> change master to master_host=’192.168.31.83′,master_port=3306,master_user=’rep’,master_password=’123456′,master_log_file=’mysql-bin.000001′,master_log_pos=452;

mysql>slave start;

验证主从复制:

master2 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

slave1 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

slave2 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果 Slave_IO_Running 和 Slave_SQL_Running 都为 yes,那么主从就已经配置 OK 了

把 master1 配置成 master2 的从库:

在 master2 上执行 show master status ; 获取 binlog 文件和 Position 点

mysql> show master status;

+——————+———-+————–+——————+————————————————–+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+——————+———-+————–+——————+—————————————————+

| mysql-bin.000001 |      452 |              |           |                   |

+——————+———-+————–+——————+—————————————————-+

在 master1 上执行:

mysql> change master to master_host=’192.168.31.141′,master_port=3306,master_user=’rep’,master_password=’123456′,master_log_file=’mysql-bin.000001′,master_log_pos=452;

mysql> start slave;

验证主从复制:

master1 主机:

mysql> show slave status\G;

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.141

Master_User: rep

Master_Port: 3306

Connect_Retry: 60

Master_Log_File: mysql-bin.000001

Read_Master_Log_Pos: 452

Relay_Log_File: relay-bin.000002

Relay_Log_Pos: 320

Relay_Master_Log_File: mysql-bin.000001

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

如果 Slave_IO_Running 和 Slave_SQL_Running 都为 yes,那么主从就已经配置 OK 了

更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2017-04/142613p2.htm

附:

1、日志文件:

日志文件往往是分析错误的关键,所以要善于利用日志文件进行问题分析。

db 端:/var/log/MySQL-mmm/mmm_agentd.log

监控端:/var/log/mysql-mmm/mmm_mond.log

2、命令文件:

mmm_agentd:db 代理进程的启动文件

mmm_mond:监控进程的启动文件

mmm_backup:备份文件

mmm_restore:还原文件

mmm_control:监控操作命令文件

db 服务器端只有 mmm_agentd 程序,其它的都是在 monitor 服务器端。

3、mmm_control 用法

mmm_control 程序可以用于监控群集状态、切换 writer、设置 online\offline 操作等。

Valid commands are:

help        – show this message #帮助信息

ping        – ping monitor #ping 当前的群集是否正常

show        – show status #群集在线状态检查

checks [<host>|all [<check>|all]] – show checks status# 执行监控检查操作

set_online<host>    – set host <host> online #将 host 设置为 online

set_offline<host>    – set host <host> offline #将 host 设置为 offline

mode        – print current mode. #打印输出当前的 mode

set_active      – switch into active mode.

set_manual      – switch into manual mode.

set_passive      – switch into passive mode.

move_role [–force] <role><host> – move exclusive role <role> to host <host> #移除 writer 服务器为指定的 host 服务器(Only use –force if you know what you are doing!)

set_ip<ip><host>    – set role with ip<ip> to host <host>

检查所有的 db 服务器群集状态:

[root@monitor1 ~]# mmm_control checks all

检查项包括:ping、mysql 是否正常运行、复制线程是否正常等

检查群集环境在线状况:

[root@monitor1 ~]# mmm_control show

对指定的 host 执行 offline 操作:

[root@monitor1 ~]# mmm_controlset_offline slave2

对指定的 host 执行 onine 操作:

[root@monitor1 ~]# mmm_controlset_online slave2

执行 write 切换(手动切换):

查看当前的 slave 对应的 master

[root@slave2 ~]# mysql -uroot -p123456 -e ‘show slave status\G;’

mysql: [Warning] Using a password on the command line interface can be insecure.

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.141

writer 切换,要确保 mmm_common.conf 文件中的 writer 属性有配置对应的 host, 否则无法切换

[root@monitor1 ~]# mmm_controlmove_role writer master1

OK: Role ‘writer’ has been moved from ‘master2’ to ‘master1’. Now you can wait some time and check new roles info!

[root@monitor1 ~]# mmm_control show

master1(192.168.31.83) master/ONLINE. Roles: writer(192.168.31.2)

master2(192.168.31.141) master/ONLINE. Roles: reader(192.168.31.5)

slave1(192.168.31.250) slave/ONLINE. Roles: reader(192.168.31.4)

slave2(192.168.31.225) slave/ONLINE. Roles: reader(192.168.31.3)

save 从库自动切换到了新的 master

[root@slave2 ~]# mysql -uroot -p123456 -e ‘show slave status\G;’

mysql: [Warning] Using a password on the command line interface can be insecure.

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event

Master_Host: 192.168.31.83

4、其它处理问题

如果不想让 writer 从 master 切换到 backup(包括主从的延时也会导致写 VIP 的切换),那么可以在配置 /etc/mysql-mmm/mmm_common.conf 时,去掉 <role write> 中的 backup

<role writer>#writer 角色配置

hosts master1 #这里只配置一个 Hosts

ips  192.168.31.2# 对外提供的写操作的虚拟 IP

mode exclusive #exclusive 代表只允许存在一个主,也就是只能提供一个写的 IP

</role>

这样的话当 master1 出现故障了 writer 写操作不会切换到 master2 服务器,并且 slave 也不会指向新的 master,此时当前的 MMM 之前对外提供写服务。

5、总结

1. 对外提供读写的虚拟 IP 是由 monitor 程序控制。如果 monitor 没有启动那么 db 服务器不会被分配虚拟 ip, 但是如果已经分配好了虚拟 ip,当 monitor 程序关闭了原先分配的虚拟 ip 不会立即关闭外部程序还可以连接访问(只要不重启网络),这样的好处就是对于 monitor 的可靠性要求就会低一些,但是如果这个时候其中的某一个 db 服务器故障了就无法处理切换,也就是原先的虚拟 ip 还是维持不变,挂掉的那台 DB 的虚拟 ip 会变的不可访问。

2.agent 程序受 monitor 程序的控制处理 write 切换,从库切换等操作。如果 monitor 进程关闭了那么 agent 进程就起不到什么作用,它本身不能处理故障。

3.monitor 程序负责监控 db 服务器的状态,包括 Mysql 数据库、服务器是否运行、复制线程是否正常、主从延时等;它还用于控制 agent 程序处理故障。

4.monitor 会每隔几秒钟监控 db 服务器的状态,如果 db 服务器已经从故障变成了正常,那么 monitor 会自动在 60s 之后将其设置为 online 状态(默认是 60s 可以设为其它的值),有监控端的配置文件参数“auto_set_online”决定,群集服务器的状态有三种分别是:HARD_OFFLINE→AWAITING_RECOVERY→online

5. 默认 monitor 会控制 mmm_agent 会将 writer db 服务器 read_only 修改为 OFF,其它的 db 服务器 read_only 修改为 ON, 所以为了严谨可以在所有的服务器的 my.cnf 文件中加入 read_only= 1 由 monitor 控制来控制 writer 和 read,root 用户和复制用户不受 read_only 参数的影响。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-04/142613.htm

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