mysql主从复制
主从复制
默认的主从复制就是异步的
1、主从复制介绍(Master-Slave Replication)
两台以上的数据库实例,通过二进制日志实现数据复制关系。
2、主从复制的作用
辅助数据备份备份,比较擅长处理数据库的物理损坏。
架构演变:高可用,读写分离,分布式......将来可以作为架构演变使用
3、主从复制(Classic Replication 搭建过程)
(1)需要两台以上的数据库实例,需要不同的server_id ,与server_uuid保持不同。
(2)主库需要开启二进制日志(binlog)---->专用复制用户(必须要开启)
(3)进行主数据库,恢复到从库。
(4) 从库:change master to , 通知从库,主库:user,password (专用的),ip,port,复制的起点.
(5) 从库:start slave; 开启专用的复制线程
4、环境搭建
4.1 节点准备及各项检查
[root@db01 ~]# systemctl start mysqld3307
[root@db01 ~]# systemctl start mysqld3308
[root@db01 ~]# mysql -S /tmp/mysql3307.sock -e "select@@server_id"
+-------------+
| @@server_id |
+-------------+
| 7 |
+-------------+
[root@db01 ~]# mysql -S /tmp/mysql3308.sock -e "select@@server_id"
+-------------+
| @@server_id |
+-------------+
| 8 |
+-------------+
[root@db01 ~]# mysql -S /tmp/mysql3307.sock -e "select @@log_bin"
[root@db01 ~]# mysql -S /tmp/mysql3307.sock -e "select @@server_uuid"
[root@db01 ~]# mysql -S /tmp/mysql3308.sock -e "select @@server_uuid"
4.2 binlog日志检查及用户准备
[root@db01 mysql]# mkdir -p /data/mysql/binlog_3307
[root@db01 mysql]# chown -R mysql.mysql /data
[root@db01 mysql]# vim /data/mysql/my3307.cnf
[mysqld]
user=mysql
port=3307
basedir=/usr/local/mysql57
datadir=/data/mysql/data_3307
server_id=7
socket=/tmp/mysql3307.sock
#添加以下行:
log_bin=/data/mysql/binlog_3307/mysql-bin
[root@db01 mysql]# systemctl restart mysqld3307
[root@db01 mysql]# mysql -S /tmp/mysql3307.sock -e "select @@log_bin"
+-----------+
| @@log_bin |
+-----------+
| 1 |
+-----------+
[root@db01 mysql]# mysql -S /tmp/mysql3308.sock -e "select @@server_uuid"
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| e1c2f86b-2263-11ea-86f7-000c29502c0d |
+--------------------------------------+
[root@db01 mysql]# mysql -S /tmp/mysql3307.sock -e "select @@server_uuid"
+--------------------------------------+
| @@server_uuid |
+--------------------------------------+
| dc0524a6-2263-11ea-846c-000c29502c0d |
+--------------------------------------+
[root@db01 mysql]# mysql -S /tmp/mysql3307.sock -e "grant replication slave on *.* to repl@'10.0.0.%' identified by '123'"
4.3 备份主库数据,恢复到从库,并记录位置点.
[root@db01 mysql]# mysqldump -S /tmp/mysql3307.sock -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql
[root@db01 mysql]# vim /tmp/full.sql
......
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=734;
......
[root@db01 mysql]# mysql -S /tmp/mysql3308.sock < /tmp/full.sql
4.4 从库执行 change master to
[root@db01 mysql]# mysql -S /tmp/mysql3308.sock
CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=734, ###上面查到的734
MASTER_CONNECT_RETRY=10;
[root@db01 mysql]# mysql -S /tmp/mysql3308.sock -e "show slave status\G"|grep Running:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
出错问题解决:
4.6简单诊断问题思路
故障解决:
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
mysql> reset slave all; (#全部清空)
## 重复执行前面执行的步骤
mysql> change master to
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=734, ###上面查到的734
MASTER_CONNECT_RETRY=10;
mysql> start slave
4.7简述主从复制原理
文件:
主库: binlog
从库: relaylog, master.info,relay-log.info
线程:
主库: binlog dump thread(show processlist;)
从库: IO , SQL (分别用来传输日志和回放日志)
三线程四文件(主库一个文件,从库三个文件。主库一个线程,从库两个线程)
图讲解--->文字解说
1、从库执行change master to 命令:ip port user password binlog起点;
2、信息被转存到master.info文件(专用表中) -- >8.0默认放到专门表中master.info(1、主库方面的连接点信息2、binlog的位置点信息)
3、从库执行:start slave,为了启动IO、SQL线程。
4、IO的作用:io连接请求主库mysql -urepl -p123 -h 10.0.0.51 -p 3307,主库开启专用的dump线程,查看命令进入数据库执行show processlist;IO拿着master.info中的连接信息连接主库,然后主从就建立联系。
5、io线程拿着从库IO线程master.info信息就会询问主库有没有比001文件444号更新的binlog,然后dump告诉IO去确认一下,然后拿着最新的时间binlog给io线程传回去,IO线程拿着日志信息存储到终记日志中并且更新master.info SQl线程将所有的relay.info记录一下。
6、主库dump线程返回新的日志event返回给主库
7、从库io线程接受binlog,并重新更新master.info
8、从库io将接收到的binlog记录到relay.info 中
9、从库SQL线程读取relay.info信息获取到上次执行到的位置点,继续向后回放最新的relay.log位置,并重新将relay.info信息更新
10、小细节:
1、回放完成的relaylog会自动更新处理
2、主库一旦有新日志变化,dump线程会立即通知从库
3、5.6以后master.info和relay.info可以存储到表中。8.0是默认开启的
4、主从复制只要日志没损坏的前提,开关机重启网络重启自动构建即自动回复主从关系。
4.8主从复制监控方式
[root@db01 mysql]# mysql -S /tmp/mysql3308
mysql> show slave status \G
*************************** 1. row ***************************
## (1)主库连接信息
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.51
Master_User: repl
Master_Port: 3307
Connect_Retry: 10
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1024
##(2) 从库中继日志回放位置点
Relay_Log_File: db01-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
##(3)从库复制线程状态。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#说明:必须是yes,但是yes不代表完全没问题。
## (4)过滤复制相关状态
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
##已经执行到的master位置点
Exec_Master_Log_Pos: 1024
Relay_Log_Space: 526
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:
## (5)从库延时与主库多少秒?
SQL_Delay: 0
SQL_Remaining_Delay: NULL
## 说明:作用是用来处理逻辑故障的。
###(6)GTID相关
Retrieved_Gtid_Set:
Executed_Gtid_Set:
4.9主从复制故障分析及处理
(1)线程为什么不工作
IO线程故障三原因:
1、连接主库
网络:ip、端口、port防火墙、user,password,网络不通。
解决方案:保证以上信息正确可用。
2、请求日志
日志位置点指定错误(搭建过程问题)
binlog损坏,误删除等。
例如:reset master;
保险处理办法:重新备份恢复,重新构建主从
3、存储日志 --->故障:同事将二进制日志删了,然后主从不同步。
relaylog 损坏,丢失,不连续。
网络故障案例--->面试案例:
当时客户现场要求去做,两台交换机当时交换机没有做堆叠,然后数据量大的时候主从不同步,当时能够ping通,各方面端口号啥的都是好的,当时怀疑是网络问题,将所有的硬件都换了,然后还是不通,我们尝试将交换机配成了准备模式,将交换机做了堆叠。然后好了
(税务局项目,四十套集群原厂的人干了两天半没解决,我们第三天把所有的换了,然后还是没解决,第四天把交换机做了准备,四十套集群一个大概三个小时,搞定了。)
SQL
1、回放relaylog日志 -->日志里面是SQL语句 --->SQL线程执行SQL语句为什么失败?
(1)创建对象失败,权限问题,删除修改的对象存在、关键字。
从库被写入了,(开发将主从库搞乱了,在从库写入数据)
跳过错误:
解决方案一:
stop slave;
set global sql_slave _skip_counter =1;
#将同步指针向下移动一个,如果多次不同步,可以重复操作。
start slave;
解决方案二--->直接在配置文件加:
/etc/my.cnf
slave-skip-errors = 1032,1062,1007
常见的错误代码:
1007:对象已经存在
1032:无法执行DML
1062:主键冲突,或者约束冲突
终极大招:---->从权限上控制
从库只读 ----->出处:mysql >show variables like '%read_only%';
read_only=on
super_read_only=on
或者配合中间件
(2)版本不一致,SQL_mode不一致,配置不一致
解决方案:尽量统一,如果非不一样,将高版本的SQL_mode降低为低版本配置
(3)DML语句执行失败
异步复制会导致的问题,比如:表不存在。
人工校验的主从数据库不一致的原因,把有问题的操作给补上。
# Perror 1000+ #perror可以查看错误序号包含的错误原因
(4)约束冲突,例如:主键自增列冲突。8.0之前的bug
双主模式下,会导致主键冲突.
主库宕机,8.0以前自增列是没有持久化的.
## 扩展:
pt-checksum
pt-sync
pt-heartbeat
主从复制进阶
1、延时从库企业级应用
1.1场景介绍: 逻辑损坏情景。
很久很久以前有个傻子删掉了一个库。。。。误删除一张2G的表(一共200G),有备份和日志,延时存库。
问----> 如何恢复?
延时从库企业级应用
1.2配置
SQL线程延时:数据已经写入relaylog中了,SQL线程"慢点"运行
一般企业建议3-6小时,具体看公司运维人员对于故障的反应时间
mysql>stop slave;
mysql>CHANGE MASTER TO MASTER_DELAY = 300; ##300s5分钟
mysql>start slave;
mysql> show slave status \G
SQL_Delay: 300
SQL_Remaining_Delay: NULL
1.3 故障模拟
主库:
create database delaydb charset utf8mb4;
use delaydb;
create table t1 (id int);
begin;
insert into t1 values(1);
commit;
begin;
insert into t1 values(2);
commit;
begin;
insert into t1 values(3);
commit;
begin;
insert into t1 values(4);
commit;
begin;
insert into t1 values(5);
commit;
drop database delaydb;
恢复思路(延时从库)
- 监控到故障,第一时间停掉从库SQL线程
- 手工模拟SQL线程回放relaylog,停止在drop之前
起点:读取relay.info信息
终点:drop之前 - 恢复业务
演练:
从库 :
1. 停止SQL线程
mysql> stop slave sql_thread;
2. 截取relaylog日志
起点:
Relay_Log_File: db01-relay-bin.000002
Relay_Log_Pos: 653
终点:
db01-relay-bin.000002 | 2366 | Query | 7 | 4772 | drop database delaydb
2. 过滤复制的企业级应用
2.1 配置普通复制环境
systemctl start mysqld3309
mysqldump -S /tmp/mysql3307.sock -A --master-data=2 --single-transaction -R -E --triggers >/tmp/full.sql
grep "\-\- CHANGE MASTER TO" /tmp/full.sql
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=4772;
mysql -S /tmp/mysql3309.sock < /tmp/full.sql
mysql -S /tmp/mysql3309.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51',MASTER_USER='repl',MASTER_PASSWORD='123',MASTER_PORT=3307,MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=4772,MASTER_CONNECT_RETRY=10;start slave;"
mysql -S /tmp/mysql3309.sock -e "show slave status\G"|grep Running:
2.2 开启过滤复制功能
库级别:
Replicate_Do_DB: world
Replicate_Ignore_DB:
表级别:
Replicate_Do_Table: world.t1
Replicate_Ignore_Table:
模糊过滤:
Replicate_Wild_Do_Table: world.t*
Replicate_Wild_Ignore_Table:
2.3 库级别白名单演示
[root@db01 ~]# vim /data/mysql/my3309.cnf
......
replicate_do_db=oldguo
......
[root@db01 ~]# systemctl restart mysqld3309
3. 半同步复制介绍
ACK
timeout
4. 基于GTID的复制
环境准备(服用前面使用过的10.0.0.51克隆)
三台机器分别运行内存为2G ip地址分别为db01:10.0.0.51 db02:10.0.0.52 db03:10.0.0.53
## GTID复制配置过程:
### 清理环境(三台机器都做)
pkill mysqld
\rm -rf /data/*
mkdir -p /data/mysql/data
mkdir -p /data/binlog
chown -R mysql.mysql /data/*
### 准备配置文件
### 主库db01:
cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql57/
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=51
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db01 [\\d]>
EOF
### 从库
slave1(db02):
cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql57
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=52
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db02 [\\d]>
EOF
slave2(db03):
cat > /etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql57
datadir=/data/mysql/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
autocommit=0
log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\\d]>
EOF
### 初始化数据(三台全部执行下列语句)
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql57 --datadir=/data/mysql/data
### 启动数据库
/etc/init.d/mysqld start
### 构建主从:
### master:51
### slave:52,53
# 51:(在10.0.0.51上面执行) 创建用户
[root@db01 ~]# mysql
db01 [(none)]>grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
db01 [(none)]>
# 52\53:(10.0.0.52和10.0.0.53操作)下列以为10.0.0.52为例,10.0.0.53相同
[root@db02 ~]# mysql
change master to
master_host='10.0.0.51',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
###检查
mysql
db02 [(none)]>start slave;
db02 [(none)]>show slave status \G;
主从复制架构演变
先前的主从复制只是备份,但是无法应用于实际生产环境。引入中间件。
主从复制架构演变读写分离:读多写少的业务类型2:8或者3:7。Atlas, ProxySQL, Maxscale……
高可用:解决业务主库宕机时,还能继续提供原有服务。MHA, PXC, MGR, MIC(8.0)
分布式架构:将逻辑单元拆分到不同的节点中,分担存储压力和业务压力。
Mycat, DBLE, Sharding-jdbcNewSQL架构:合久必分,分久必合TiDB, Polardb(阿里云), TDSQL(腾讯云)
NewSQL:分久必合合久必分。
2. 企业高可用标准评估:全年无故障率
99.9% 0.1% 365*24*60*0.001= 525.6 min
99.99% 0.01% 365*24*60*0.001= 52.56 min
99.999% 0.001% 365*24*60*0.001= 5.256 min
99.9999% 0.0001% 365*24*60*0.001= 0.5256 min
负载均衡: 3个9
主备集群: 4个9
多活集群: 5个9 MYSQL Cluster, MIC, PXC, MGC
3.3 配置关键程序软连接(所有节点)
ln -s /usr/local/mysql57/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /usr/local/mysql57/bin/mysql /usr/bin/mysql
3.4 配置各节点互信(仅供参考)
db01:
rm -rf /root/.ssh
ssh-keygen ##一路回车
cd /root/.ssh
mv id_rsa.pub authorized_keys
scp -r /root/.ssh 10.0.0.52:/root
scp -r /root/.ssh 10.0.0.53:/root
各节点验证
db01:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db02:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db03:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
3.5 安装软件下载mha软件
mha官网:https://code.google.com/archive/p/mysql-master-ha/
github下载地址:https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
## 1、所有节点全部上传MHA包然后解压
[root@db01 ~]# rz MHA-2019-6.28.zip
[root@db01 ~]# unzip MHA-2019-6.28.zip
Archive: MHA-2019-6.28.zip
inflating: Atlas-2.2.1.el6.x86_64.rpm
inflating: email_2019-最新.zip
inflating: master_ip_failover.txt
inflating: mha4mysql-manager-0.56-0.el6.noarch.rpm
inflating: mha4mysql-node-0.56-0.el6.noarch.rpm
## 2、## 所有节点安装Node软件依赖包
yum install perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm
## 在db01主库中创建mha需要的用户
[root@db01 ~]# mysql
db01 [(none)]> grant all privileges on *.* to mha@'10.0.0.%' identified by 'mha';
## Manager软件安装(db03)
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
3.6 配置文件准备(db03)
创建配置文件目录
[root@db03 ~]# mkdir -p /etc/mha
创建日志目录
[root@db03 ~]# mkdir -p /var/log/mha/app1
编辑mha配置文件
cat > /etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager #日志
manager_workdir=/var/log/mha/app1 #根据不同的业务指定目录
master_binlog_dir=/data/binlog #主库的二进制日志
user=mha
password=mha
ping_interval=2 #ping的间隔时间,每2s一次
repl_password=123
repl_user=repl
ssh_user=root
[server1]
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
EOF
3.7 状态检查
### 互信检查
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
......
Fri Jan 3 14:49:36 2020 - [info] All SSH connection tests passed successfully.
### 主从检查
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
......
MySQL Replication Health is OK.
3.8 开启MHA(db03):
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
[1] 8153
3.9 查看MHA状态
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:8153) is running(0:PING_OK), master:10.0.0.51
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.51 -e "select @@server_id"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 51 |
+---------------+-------+
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.52 -e "select @@server_id"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 52 |
+---------------+-------+
[root@db03 ~]# mysql -umha -pmha -h 10.0.0.53 -e "select @@server_id"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id | 53 |
+---------------+-------+
- MHA 软件结构介绍
Manager工具包主要包括以下几个工具:
masterha_manger 启动MHA
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_master_monitor 检测master是否宕机
masterha_check_status 检测当前MHA运行状态
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息
Node工具包主要包括以下几个工具:
这些工具通常由MHA Manager的脚本触发,无需人为操作
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
6. MHA 的工作原理 --->必会知识点(重要)
监控,选主,补偿,切换
1. 通过masterha_manger脚本启动MHA高可用功能---->监控masterha_master_monitor
2. 通过masterha_master_monitor监控主节点的状态,每ping_interval的值秒探测一次主库的心跳,一共检测4次.如过.4次都没通,认为主库宕机
3. 进行选主工作
算法一: 权重candidate_master=1
算法二: 判断日志量
算法三: 按照配置文件的顺序
4. 数据补偿
ssh能连: 各个从库通过(save_binary_logs)立即保存缺失部分binlog到/var/tmp/xxxx,并补偿数据.
ssh不能连:数据较少的从库,会通过apply_diff_relay_logs,计算差异,追平数据.
5. 通过masterha_master_switch 脚本切换.
所有从节点,stop slave; reset slave all;
s2节点,change master to s1 ,start slave
6. 调用masterha_conf_host脚本,从集群中将故障节点剔除.
7. manager 自杀.
有没有不足?还缺啥?
1. binlog server 日志冗余
2. 应用透明 vip漂移(keepalive,vip--自带)
3. 故障提醒 --->邮件提醒
4. 自愈(待开发...),阿里云的RDS,TDSQL都具备自愈能力.
MHA扩展功能应用
MHA的VIP功能
(1) 准备脚本
[root@db03 ~]# cp master_ip_failover.txt /usr/local/bin/master_ip_failover
[root@db03 ~]# cd /usr/local/bin/
[root@db03 bin]# ll
total 4
-rw-r--r-- 1 root root 2248 Jan 3 15:08 master_ip_failover
[root@db03 bin]# chmod +x master_ip_failover
[root@db03 bin]# dos2unix master_ip_failover ##脚本格式有问题,需要进行转换
dos2unix: converting file master_ip_failover to Unix format ...
[root@db03 bin]# vim master_ip_failover
......
my $vip = '10.0.0.55/24'; ##生产环境按照实际需求配置,并且此ip为没被人使用的
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; ## eth0生产中可能有些不一样需要改
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down"; ## eth0生产中可能有些不一样需要改
(2) manager配置文件修改
## 添加参数
vim /etc/mha/app1.cnf
[server default] ###添加下列行到default下
master_ip_failover_script=/usr/local/bin/master_ip_failover
......
(3) 手工生成vip(主节点) #在db01操作
[root@db01 ~]# ifconfig eth0:1 10.0.0.55/24
(4) 重启mha #在db03操作
[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf
Stopped app1 successfully.
[root@db03 bin]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
[root@db03 bin]# masterha_check_status --conf=/etc/mha/app1.cnf ##检查
app1 (pid:9085) is running(0:PING_OK), master:10.0.0.51
binlogserver ##以下全部在db03操作
2.1 参数
[root@db03 bin]# vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog
2.2 创建必要目录
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*
2.3 拉取主库binlog日志
cd /data/mysql/binlog
mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never mysql-bin.000001 &
2.4 重启MHA
masterha_stop --conf=/etc/mha/app1.cnf
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
邮件提醒
3 邮件提醒
3.2 准备邮件脚本
send_report
(1)准备发邮件的脚本(上传 email_2019-最新.zip中的脚本,到/usr/local/bin/中)
(2)将准备好的脚本添加到mha配置文件中,让其调用
[root@db03 ~]# unzip email_2019-最新.zip
[root@db03 ~]# cp email/* /usr/local/bin/
[root@db03 ~]# cd /usr/local/bin/
[root@db03 bin]# cat testpl
#!/bin/bash
/usr/local/bin/sendEmail -o tls=no -f oldguo123@126.com -t 2226823216@qq.com -s smtp.126.com:25 -xu oldguo123 -xp oldguo123 -u "MHA Waring" -m "YOUR MHA MAY BE FAILOVER" &>/tmp/sendmail.log
7.3.3. 修改manager配置文件,调用邮件脚本
vi /etc/mha/app1.cnf
[server default] ##加到default后面
report_script=/usr/local/bin/send
(3)停止MHA
masterha_stop --conf=/etc/mha/app1.cnf
(4)开启MHA
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
[root@db03 bin]# chmod +x *
[root@db03 bin]# ./testpl #执行脚本
模拟环境主库10.0.0.51down了切换到10.0.0.52检查VIP
[root@db01 ~]# pkill mysql
[root@db01 ~]# ip addr
## 切换至52查看
[root@db02 ~]# ip addr
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:3e:4d:79 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.52/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:1
valid_lft forever preferred_lft forever
### 切换到53查看主从
[root@db03 bin]# mysql
db03 [(none)]>start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
db03 [(none)]>show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.52
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# mha是一次性的,不可以切换多次
日志[root@db03 ~]# cat /var/log/mha/app1/manager
故障恢复
# 10.0.0.51操作
1、恢复故障节点
[root@db01 ~]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS!
2. 修复主从
将db01 加入到主从环境中作为从库角色
mysql
change master to
master_host='10.0.0.52',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1;
start slave;
3. 修复binlog_server(db03)
[root@db03 binlog]# cd /data/mysql/binlog/
[root@db03 binlog]# rm -rf *
[root@db03 binlog]# mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never mysql-bin.000001 &
4、检查主库VIP 10.0.0.52
[root@db02 log]# ifconfig -a
5. 检查配置文件节点信息 (db03)
[server1]
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
新环境:备份现在主库数据,重新change master to
6. 状态检查 (db03)
### 互信检查
masterha_check_ssh --conf=/etc/mha/app1.cnf
### 主从检查
masterha_check_repl --conf=/etc/mha/app1.cnf
7. 启动MHA
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
masterha_check_status --conf=/etc/mha/app1.cnf
读写分离Atlas+MHA应用
- 1、介绍
Atlas是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。
它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。
360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。
下载地址
https://github.com/Qihoo360/Atlas/releases
注意:
1、Atlas只能安装运行在64位的系统上
2、Centos 5.X安装 Atlas-XX.el5.x86_64.rpm,Centos 6.X安装Atlas-XX.el6.x86_64.rpm。
3、后端mysql版本应大于5.1,建议使用Mysql 5.6以上
2.安装配置
[root@db03 ~]# yum install -y Atlas*
[root@db03 ~]# cd /usr/local/mysql-proxy/conf
[root@db03 conf]# mv test.cnf test.cnf.bak
[root@db03 conf]# vi test.cnf
[mysql-proxy]
admin-username = user ##2345账号密码
admin-password = pwd
proxy-backend-addresses = 10.0.0.55:3306 ##写的节点是谁
proxy-read-only-backend-addresses = 10.0.0.51:3306,10.0.0.53:3306 ##读的节点是谁
pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098= ##后端数据库的用户名密码(按照需求添加)
daemon = true
keepalive = true
event-threads = 8
log-level = message
log-path = /usr/local/mysql-proxy/log
sql-log=ON
proxy-address = 0.0.0.0:33060
admin-address = 0.0.0.0:2345
charset=utf8
启动atlas
[root@db03 conf]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
OK: MySQL-Proxy of test is started
[root@db03 conf]# netstat -tulntp
0 0 0.0.0.0:33060 0.0.0.0:* LISTEN 12194/mysql-proxy
0 0 0.0.0.0:2345 0.0.0.0:* LISTEN 12194/mysql-proxy
3. Atlas功能测试
测试读操作:
[root@db03 conf]# mysql -umha -pmha -h 10.0.0.53 -P 33060
db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 51 |
+-------------+
1 row in set (0.01 sec)
db03 [(none)]>select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 53 |
+-------------+
1 row in set (0.00 sec)
测试写操作:
mysql> begin;select @@server_id;commit;
4、atlas管理
[root@db03 conf]# mysql -uuser -ppwd -h10.0.0.53 -P2345
db03 [(none)]> select * from help; ##依次执行测试帮助
+----------------------------+---------------------------------------------------------+
| command | description |
+----------------------------+---------------------------------------------------------+
| SELECT * FROM help | shows this help |
| SELECT * FROM backends | lists the backends and their state |
| SET OFFLINE $backend_id | offline backend server, $backend_id is backend_ndx's id |
| SET ONLINE $backend_id | online backend server, ... |
| ADD MASTER $backend | example: "add master 127.0.0.1:3306", ... |
| ADD SLAVE $backend | example: "add slave 127.0.0.1:3306", ... |
| REMOVE BACKEND $backend_id | example: "remove backend 1", ... |
| SELECT * FROM clients | lists the clients |
| ADD CLIENT $client | example: "add client 192.168.1.2", ... |
| REMOVE CLIENT $client | example: "remove client 192.168.1.2", ... |
| SELECT * FROM pwds | lists the pwds |
| ADD PWD $pwd | example: "add pwd user:raw_password", ... |
| ADD ENPWD $pwd | example: "add enpwd user:encrypted_password", ... |
| REMOVE PWD $pwd | example: "remove pwd user", ... |
| SAVE CONFIG | save the backends to config file |
| SELECT VERSION | display the version of Atlas |
+----------------------------+-----------------------------------
db03 [(none)]>save config; ##修改完成之后记得执行此命令长久保存
自己研究(额外扩展):
ProxySQL
Maxscale
mysqlrouter
consul