MMM(Master-Master replication manager for MySQL,MySQL主主复制管理器)是一套支持双主故障切换和双主日常管理的脚本程序。MMM使用Perl语言开发,是Google的开源项目(Perl脚本),主要用来监控和管理MySQL Master-Master===(双主)复制==,虽然叫做双主复制,但是业务上同一时刻只允许对一个主进行写入,另一台备选主上提供部分读服务,以加速在主主切换时刻备选主的预热,可以说MMM这套脚本程序一方面实现了故障切换的功能,另一方面其内部附加的工具脚本也可以实现多个slave的read负载均衡。
原理
MMM高可用架构说明
mmm_mon
监控进程,负责所有的监控工作,决定和处理所有节点角色活动。此脚本需要在监控机上运行
mmm_agent
运行在每个mysql服务器上的代理进程,完成监控的探针工作和执行简单的远程服务设置,此脚本需要在被监管机上运行
mmm_control
一个简单的脚本,提供管理mmm_mond进程的命令
mysql_mmm
的监管端会提供多个虚拟IP(VIP),包括一个可写VIP,多个可读VIP,通过监管的管理,这些IP会绑定在可用mysql之上,当某一台mysql宕机时,监管会将VIP迁移至其他mysql
在整个监管过程中,需要在MySQL中添加相关的授权用户,以便让MySQL可以支持监理机的维护。授权的用户包括一个mmm_monitor
用户和一个mmm_agent
用户,如果想使用MMM的备份工具则还需要添加一个mmm_tools
用户
安装脚本
#!/bin/bash
tar xf /root/mysql-5.7.25-el7-x86_64.tar.gz -C /usr/local/
cd /usr/local
mv mysql-5.7.25-el7-x86_64 mysql
id mysql &>/dev/null
if [ $? -ne 0 ];then
groupadd mysql
useradd -M -s /sbin/nologin mysql -g mysql
fi
chown -R mysql.mysql /usr/local/mysql
config() {
rm -rf /etc/my.cnf
cat > /etc/my.cnf <<-EOF
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
server_id=1
port=3306
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock
prompt=mysql [\\\d]>
EOF
}
config
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile
yum install -y libaio &>/dev/null
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data &>/dev/null
if [ $? -ne 0 ];then
echo '初始化错误,请检查依赖'
exit 2
else
echo '初始化成功!'
fi
sys() {
cat >/etc/systemd/system/mysqld.service <<-EOF
[Unit]
Description=MySQL Server
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000
EOF
}
sys
systemctl daemon-reload
systemctl start mysqld
pgrep mysql &>/dev/null
if [ $? -ne 0 ];then
echo 'mysql启动失败,请检查配置文件或查看日志'
exit 3
fi
mysqladmin -uroot password '123' &>/dev/null
if [ $? -ne 0 ];then
echo '请手动source /etc/profile 之后更改密码和登录mysql'
fi
mysql -uroot -p123
在主节点上搭建时间同步服务器
安装NTP(关闭防火墙/selinux)
yum -y install ntp
配置NTP
vim /etc/ntp.conf
# local clock
server 127.127.1.0 # 本地时间供给源
fudge 127.127.1.0 stratum 8 # 设置时区为+08区
重启服务并设置为开机启动
systemctl enable ntpd --now
在主备选和从节点上进行时间同步
yum -y install ntpdate
ntpdate 192.168.188.71
主MySQL
vim /etc/my.cnf
[mysqld]
server_id = 1 # 每台服务器设置为不同id
log_bin = master-bin # 开启二进制日志
log-slave-updates = true # 宕机后启用备用库
auto_increment_increment = 2 # 两台主MySQL设置相同数
auto_increment_offset = 1 # 两台主MySQL设置为不同数
备选主MySQL
[mysqld]
server_id = 2
log_bin = master-bin
log-slave-updates = true
auto_increment_increment = 2 # 两台主MySQL设置相同数
auto_increment_offset = 2 # 两台主MySQL设置为不同数
systemctl restart mysqld
补充:
mysql中有自增长字段,在做数据库的主主同步时需要设置自增长的两个相关配置:auto_increment_offset
和auto_increment_increment
这样才可以避免两台服务器同时做更新时自增长字段的值之间发生冲突。
从MySQL1
vim /etc/my.cnf
[mysqld]
server_id = 3
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
log-slave-updates = true
从MySQL2
[mysqld]
server_id = 4
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
log-slave-updates = true
systemctl restart mysqld
两台服务器都需要做
mysql -uroot -p123
首先确定二进制日志是否开启
show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
添加授权访问用户
GRANT REPLICATION SLAVE ON *.* TO 'maomao'@'192.168.188.%' IDENTIFIED BY '123';
刷新授权
FLUSH PRIVILEGES;
获取日志名及偏移量
show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 613 | | | |
+-------------------+----------+--------------+------------------+-------------------+
主MySQL
change master to master_host='192.168.188.72',master_user='maomao',master_password='123',master_log_file='master-bin.000001',master_log_pos=613;
start slave;
主备选MySQL
change master to master_host='192.168.188.71',master_user='maomao',master_password='123',master_log_file='master-bin.000001',master_log_pos=613;
start slave;
验证主从状态
show slave status\G;
主备选
查看同步状态Slave_IO和Slave_SQL为YES
,说明猪猪同步成功
分别在两台主服务器上创建不同的库 分别查看
create database zhu;
create database niu;
mysql [(none)]>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| niu |
| performance_schema |
| sys |
| zhu |
+--------------------+
6 rows in set (0.00 sec)
首先在主服务器上查看日志和节点
show master status;
得到master-bin.000001 和 Position是935
在从服务器上配置同步(两台从机一样操作)
change master to master_host='192.168.188.71',master_user='maomao',master_password='123',master_log_file='master-bin.000001',master_log_pos=935;
start slave;
查看主从状态
show slave status\G;
查看同步状态Slave_IO和Slave_SQL为YES
,说明主从同步成功
进入主服务器
show slave hosts;
新建一个测试库school
CREATE DATABASE IF NOT EXISTS `school`;
-- 创建一个school数据库
USE `school`;-- 创建学生表
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`(
`studentno` INT(4) NOT NULL COMMENT '学号',
`loginpwd` VARCHAR(20) DEFAULT NULL,
`studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
`gender` varchar(2) NOT NULL DEFAULT '女' COMMENT '性别',
`gradeid` INT(11) DEFAULT NULL COMMENT '年级编号',
`phone` VARCHAR(50) NOT NULL COMMENT '联系电话,允许为空',
`address` VARCHAR(255) NOT NULL COMMENT '地址,允许为空',
`borndate` DATETIME DEFAULT NULL COMMENT '出生时间',
`email` VARCHAR (50) NOT NULL COMMENT '邮箱账号允许为空',
`identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号',
PRIMARY KEY (`studentno`),
UNIQUE KEY `identitycard`(`identitycard`),
KEY `email` (`email`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`gender`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','唐嘉','女',2,'13800001234','北京朝阳','1980-5-2','[email protected]','123456198001011298'),
(1001,'123456','刘美玲','女',1,'13800002222','广东深圳','1991-6-4','[email protected]','123456199001011191'),
(1002,'123456','潘辰','男',1,'13800002111','四川成都','1992-7-6','[email protected]','123456199001011333'),
(1003,'123456','小田','男',2,'13800002333','四川成都','1993-8-8','[email protected]','123456199001011555'),
(1004,'123456','胡杨','男',3,'13800002555','浙江杭州','1994-9-10','[email protected]','123456199001011777'),
(1005,'123456','猫猫','女',2,'13800002666','日本东京','1995-1-12','[email protected]','123456199001011888'),
(1006,'123456','飞飞','男',2,'13800002666','上海浦东','1997-7-12','[email protected]','123456199001011666');
在从机上查询
mysql [(none)]>select studentname from school.student;
+-------------+
| studentname |
+-------------+
| 唐嘉 |
| 刘美玲 |
| 潘辰 |
| 小田 |
| 胡杨 |
| 猫猫 |
| 飞飞 |
+-------------+
7 rows in set (0.00 sec)
详情可以查看 Atlas读写分离
这时候需用用到192.168.188.75这台服务器
首先在四台MySQL上授权访问用户
添加授权访问用户
grant all on *.* to maomao@'192.168.188.%' identified by '123';
刷新授权
FLUSH PRIVILEGES;
下载Atlas
wget https://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
安装
rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
安装完成后会自动在/usr/local/mysql-proxy下生成四个文件
加密密码
cd /usr/local/mysql-proxy/bin
[root@maomao bin]# ./encrypt 123
3yb5jEku5h4=
配置atlas主配置文件
vim /usr/local/mysql-proxy/conf/test.cnf
[mysql-proxy]
#带#号的为非必需的配置项目
admin-username = atlas
#管理接口的密码
admin-password = 123
#Atlas后端连接的MySQL主库的IP和端口,可设置多项,用逗号分隔
proxy-backend-addresses = 192.168.188.71:3306,192.168.188.72:3306
#Atlas后端连接的MySQL从库的IP和端口,@后面的数字代表权重,用来作负载均衡,若省略则默认为1,可设置多项,用逗号分隔
#proxy-read-only-backend-addresses = 127.0.0.1:3305@1
proxy-read-only-backend-addresses = 192.168.188.73:3306@1,192.168.188.74:3306@1
pwds = maomao:3yb5jEku5h4= # 此账号就是之前授权的账号
#设置Atlas的运行方式,设为true时为守护进程方式,设为false时为前台方式,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
daemon = true
#设置Atlas的运行方式,设为true时Atlas会启动两个进程,一个为monitor,一个为worker,monitor在worker意外退出后会自动将其重启,设为false时只有worker,没有monitor,一般开发调试时设为false,线上运行时设为true,true后面不能有空格。
keepalive = true
#工作线程数,对Atlas的性能有很大影响,可根据情况适当设置
event-threads = 4
#日志级别,分为message、warning、critical、error、debug五个级别
log-level = message
#日志存放的路径
log-path = /usr/local/mysql-proxy/log
#Atlas监听的工作接口IP和端口
proxy-address = 0.0.0.0:1234
#Atlas监听的管理接口IP和端口
admin-address = 0.0.0.0:2345
配置无误后,启动Atlas软件
[root@maomao conf]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
OK: MySQL-Proxy of test is started
在Atlas 代理服务器上
yum -y install mysql
mysql -h127.0.0.1 -P2345 -umaomao -p123 # 这里用户和密码就是配置文件里面写的
select * from help; # 可以查看帮助
select * from backends; # 查看目前的主从复制
通过代理访问Mysql
mysql -h192.168.188.75 -P1234 -umaomao -p123 # 这里用户名和密码就是之前授权的账号
进入数据库后可以查询到主MySQL的所有库和表
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ceshi |
| mysql |
| performance_schema |
| school |
| sys |
+--------------------+
6 rows in set (0.00 sec)
还可以查看日志
tafil /usr/local/mysql-proxy/log/test.log
看到写操作都在Master,读操作都连接到Slave了
需要使用epel源 注意所有的服务器节点都需要下载
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
在五台服务器上下载
yum install -y mysql-mmm*
在四台MySQL服务器上授权monitor访问
grant replication client on *.* to 'mmm_monitor'@'192.168.188.%' identified by'monitor';
grant super,replication client,process on *.* to 'mmm_agent'@'192.168.188.%' identified by'agent';
FLUSH PRIVILEGES;
在所有服务器上修改/etc/mysql-mmm/mmm_common.conf配置文件
vim /etc/mysql-mmm/mmm_common.conf
active_master_role writer
<host default>
cluster_interface eth0 # 更改为自身主机网卡
pid_path /run/mysql-mmm-agent.pid
bin_path /usr/libexec/mysql-mmm/
replication_user maomao # 用于主从,主主复制的用户(之前授权的账号)
replication_password 123
agent_user mmm_agent # 运行在每个mysql 的代理用户
agent_password agent # 之前授权时候填的密码
</host>
<host db1> # 主MYSQL服务器
ip 192.168.188.71
mode master # 主服务器
peer db2 # 邻居为db2
</host>
<host db2> # # 主备选MYSQL服务器
ip 192.168.188.72
mode master # 主服务器
peer db1 # 邻居为db1
</host>
<host db3>
ip 192.168.188.73
mode slave # 从服务器
</host>
<host db4>
ip 192.168.188.74
mode slave
</host>
<role writer> # 可写的服务器
hosts db1, db2 # 第一台,第二台服务器
ips 192.168.188.200 # 规划指定的虚拟地址
mode exclusive # 独占模式
</role>
<role reader> # 只读的服务器
hosts db3, db4 # 第三台,第四台服务器
ips 192.168.188.201,192.168.188.202 # 分别指定的虚拟地址
mode balanced # 平衡模式
</role>
最后将配置文件传给另外四台服务器
scp /etc/mysql-mmm/mmm_common.conf [email protected]:/root
在四台MySQL服务器上修改/etc/mysql-mmm/mmm_agent.conf配置文件,修改为对应db
include mmm_common.conf
# The 'this' variable refers to this server. Proper operation requires
# that 'this' server (db1 by default), as well as all other servers, have the
# proper IP addresses set in mmm_common.conf.
this db1 # 这里地方换成common.conf里面对应的db位置 如分别修改为db1,db2,db3,db4
在代理服务器上修改/etc/mysql-mmm/mmm_mon.conf 文件
<monitor>
ip 127.0.0.1
pid_path /run/mysql-mmm-monitor.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.188.71,192.168.188.72,192.168.188.73,192.168.188.74 # 主1主2从1从2的真实IP地址
auto_set_online 60
# The kill_host_bin does not exist by default, though the monitor will
# throw a warning about it missing. See the section 5.10 "Kill Host
# Functionality" in the PDF documentation.
#
# kill_host_bin /usr/libexec/mysql-mmm/monitor/kill_host
#
</monitor>
<host default>
monitor_user mmm_monitor # mysql数据库授权用mmm_monito和密码
monitor_password monitor
</host>
debug 0
主:systemctl start mysql-mmm-agent
备选主:systemctl start mysql-mmm-agent
从1:systemctl start mysql-mmm-agent
从2:systemctl start mysql-mmm-agent
监控:systemctl start mysql-mmm-monitor
在代理服务器上查看集群:
[root@maomao ~]# mmm_control show
db1(192.168.188.71) master/ONLINE. Roles: writer(192.168.188.200)
db2(192.168.188.72) master/ONLINE. Roles:
db3(192.168.188.73) slave/ONLINE. Roles: reader(192.168.188.202)
db4(192.168.188.74) slave/ONLINE. Roles: reader(192.168.188.201)
用虚拟IP连接数据库
在代理服务器上
[root@maomao ~]# mysql -h192.168.188.200 -umaomao -p123
mysql [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
停止主mysql
systemctl stop mysqld
在监控服务器
[root@maomao ~]# mmm_control show
db1(192.168.188.71) master/HARD_OFFLINE. Roles:
db2(192.168.188.72) master/ONLINE. Roles: writer(192.168.188.200)
db3(192.168.188.73) slave/ONLINE. Roles: reader(192.168.188.202)
db4(192.168.188.74) slave/ONLINE. Roles: reader(192.168.188.201)
mysql [(none)]> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)
主服务器换成主备选MySQL的id 2 了