1. 延时从库 *****
    1.1 介绍及配置

SQL线程延时:数据已经写入relaylog中了,SQL线程"慢点"运行

一般企业建议3-6小时,具体看公司运维人员对于故障的反应时间

mysql>stop slave;

mysql>CHANGE MASTER TO MASTER_DELAY = 300;#单位:秒

mysql>start slave;

mysql> show slave status \G

SQL_Delay: 300

SQL_Remaining_Delay: NULL

1.2 延时从库处理逻辑故障

1.2.1 延时从库的恢复思路

(1) 监控到数据库逻辑故障

(2) 停从库SQL线程,记录已经回放的位置点(截取日志起点)

stop slave sql_thread ;

show slave status \G

Relay_Log_File: localhost-relay-bin.000002

Relay_Log_Pos: 320 #relay-log执行到了哪个位置

(3) 截取relaylog

起点:

show slave status \G

Relay_Log_File ,Relay_Log_Pos

终点: drop之前的位置点

show relaylog events in 'localhost-relay-bin.000002'

进行截取

(4) 模拟SQL线程回访日志

从库 source

(5) 恢复业务

情况一: 就一个库的话

从库替代主库工作

情况二:

从库导出故障库,还原到主库中.

1.2.2 故障演练

主库 :

create database delay charset utf8mb4;

use delay;

create table t1 (id int);

insert into t1 values(1),(2),(3);

commit;

drop database delay;

从库:

1.停止 从库SQL 线程,获取relay的位置点

mysql> stop slave sql_thread;

mysql> show slave status \G

Relay_Log_File: db01-relay-bin.000002

Relay_Log_Pos: 626

2. 找到relay的截取终点

mysql> show relaylog events in 'db01-relay-bin.000002';

| db01-relay-bin.000002 | 1299 | Query | 7 | 1228 | drop database delay

  1. 截取relay

[root@db01 data]# cd /data/3308/data/

[root@db01 data]# mysqlbinlog --start-position=320 --stop-position=993 /data/3308/data/localhost-relay-bin.000002 >/tmp/relay.sql

  1. 恢复relay到从库

[root@db01 data]# mysql -uroot -p -S /data/3308/mysql.sock

mysql> set sql_log_bin=0;

mysql> source /tmp/relay.sql

  1. 过滤复制 *****
    2.0 快速恢复测试环境

从库 :

mysql -S /data/3308/mysql.sock

drop database delay ;

stop slave;

reset slave all;

主库:

mysql -S /data/33078/mysql.sock

reset master;

从库:

[root@db01 ~]# mysql -S /data/3308/mysql.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=154,

MASTER_CONNECT_RETRY=10;

start slave;

2.1 过滤复制应用

主库:

show master status ;

binlog_do_db

binlog_ignore_db

从库:

mysql> show slave status \G

Replicate_Do_DB:

Replicate_Ignore_DB:

Replicate_Do_Table:

Replicate_Ignore_Table:

Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

例子:

vim /etc/my.cnf

replicate_do_db=repl

[root@db01 data]# systemctl restart mysqld3308

3 GTID复制 *****
2.3.1 介绍

GTID(Global Transaction ID)是对于一个已提交事务的唯一编号,并且是一个全局(主从复制)唯一的编号。

它的官方定义如下:

GTID = source_id :transaction_id

7E11FA47-31CA-19E1-9E56-C43AA21293967:29

什么是sever_uuid,和Server-id 区别?

核心特性: 全局唯一,具备幂等性

2.3.2 GTID核心参数

重要参数:

gtid-mode=on

enforce-gtid-consistency=true

log-slave-updates=1

gtid-mode=on --启用gtid类型,否则就是普通的复制架构

enforce-gtid-consistency=true --强制GTID的一致性

log-slave-updates=1 --slave更新是否记入日志

2.3.3 GTID复制配置过程:

(1) 清理环境

pkill mysqld

\rm -rf /data/mysql/data/* #清理数据

\rm -rf /data/binlog/* #清理数据二进制日志

rm -rf /data/3309/data/* #我自己的3309实例,数据放在/data/3309/data/下,二进制日志放在/data/3309/下

rm -rf /data/3309/*

(2) 准备配置文件

主库db01:

cat >/data/3309/my.cnf <<EOF

[mysqld]

basedir=/application/mysql/

datadir=/data/3309/data

socket=/data/3309/mysql.sock

log_error=/data/3309/mysql3309.log_error #自己设置的错误日志的名字

server_id=10

port=3309

secure-file-priv=/tmp

autocommit=0

log_bin=/data/3309/mysql-bin

binlog_format=row

gtid-mode=on

enforce-gtid-consistency=true

log-slave-updates=1

EOF

[mysql]

prompt=db01 [\d]>

EOF

slave1(db02):

cat > /etc/my.cnf <<EOF

[mysqld]

basedir=/application/mysql

datadir=/data/mysql/data

socket=/tmp/mysql.sock

server_id=10

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=/application/mysql

datadir=/data/mysql/data

socket=/tmp/mysql.sock

server_id=11

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

(3) 初始化数据

mysqld --initialize-insecure --user=mysql --basedir=/application/mysql --datadir=/data/3309/data

(4) 启动数据库

/etc/init.d/mysqld start

(5) 构建主从:

master:51

slave:52,53

51:

grant replication slave on . to repl@'%' identified by '123';

52\53:

change master to

master_host='192.168.164.130',

master_user='repl',

master_password='123',

master_port=3309,

MASTER_AUTO_POSITION=1;

start slave;

2.3.4 GTID 复制和普通复制的区别

(0)在主从复制环境中,主库发生过的事务,在全局都是由唯一GTID记录的,更方便Failover

(1)额外功能参数(3个)

(2)change master to 的时候不再需要binlog 文件名和position号,MASTER_AUTO_POSITION=1;

(3)在复制过程中,从库不再依赖master.info文件,而是直接读取最后一个relaylog的 GTID号

(4) mysqldump备份时,默认会将备份中包含的事务操作,以以下方式

SET @@GLOBAL.GTID_PURGED='8c49d7ec-7e78-11e8-9638-000c29ca725d:1-11';

告诉从库,我的备份中已经有以上事务,你就不用运行了,直接从下一个GTID开始请求binlog就行。

  1. 半同步(了解) ***

解决主从复制数据一致性问题.

ACK ,从库relay落地,IO线程会返回一个ACK,主库的 ACK_reciver .主库事务才能提交.如果一直ACK没收到,超过10秒钟会切换为异步复制.

  1. MHA高可用 ****
    5.1 搭建体验

(1)配置关键程序软连接

ln -s /application/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog

ln -s /application/mysql/bin/mysql /usr/bin/mysql

(2)配置互信

db01:

rm -rf /root/.ssh

ssh-keygen

cd /root/.ssh

mv id_rsa.pub authorized_keys

scp -r /root/.ssh 192.168.164.129:/root

scp -r /root/.ssh 192.168.164.131:/root

各节点验证

db01:

ssh 192.168.164.130 date

ssh 192.168.164.129 date

ssh 192.168.164.131 date

db02:

ssh 192.168.164.130 date

ssh 192.168.164.129 date

ssh 192.168.164.131 date

db03:

ssh 192.168.164.130 date

ssh 192.168.164.129 date

ssh 192.168.164.131 date

(3)安装软件包

yum install perl-DBD-MySQL -y

rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

mysql8.0要使用MHA的话,需要修改密码加密模式,mysql8.0默认使用sha2,要改为native

使用node0.57以上版本

(4) 在db01主库中创建mha需要的用户

grant all privileges on . to mha@'192.168.164.%' identified by 'mha';

(5) Manager软件安装(db03)

yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

yum install -y perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager

rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

(6) 配置文件准备(db03)

创建配置文件目录

mkdir -p /etc/mha

创建日志目录

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/3309 #主库的二进制日志所在的目录

user=mha

password=mha

ping_interval=2

repl_password=123

repl_user=repl

ssh_user=root

[server1]

hostname=192.168.164.130

port=3309

[server2]

hostname=192.168.164.129

port=3309

[server3]

hostname=192.168.164.131

port=3309

EOF

(7) 状态检查(db03)

互信检查

masterha_check_ssh --conf=/etc/mha/app1.cnf

masterha_check_repl --conf=/etc/mha/app1.cnf

(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 &

(9) 查看MHA状态

[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf

主库宕机处理过程

  1. 监控节点 (通过配置文件获取所有节点信息)
    系统,网络,SSH连接性
    主从状态,重点是主库

  2. 选主
    (1) 如果判断从库(position或者GTID),数据有差异,最接近于Master的slave,成为备选主
    (2) 如果判断从库(position或者GTID),数据一致,按照配置文件顺序,选主.
    (3) 如果设定有权重(candidate_master=1),按照权重强制指定备选主.

    1. 默认情况下如果一个slave落后master 100M的relay logs的话,即使有权重,也会失效.
    2. 如果check_repl_delay=0的化,即使落后很多日志,也强制选择其为备选主
  3. 数据补偿
    (1) 当SSH能连接,从库对比主库GTID 或者position号,立即将二进制日志保存至各个从节点并且应用(save_binary_logs )
    (2) 当SSH不能连接, 对比从库之间的relaylog的差异(apply_diff_relay_logs)

  4. Failover
    将备选主进行身份切换,对外提供服务
    其余从库和新主库确认新的主从关系

  5. 应用透明(VIP)

  6. 故障切换通知(send_reprt)

  7. 二次数据补偿(binlog_server)

  8. MHA 应用透明(vip)
    应用透明是指在应用和数据库之间加入中间件,实现:当发生数据库切换的时候,应用不需要做任何更改,就像没有发生过数据库切换一样

mysql自带的vip只能同机房使用,不能跨机房跨网络使用

db03:

touch /data/3309/master_ip_failover #粘贴事先准备好的脚本到这个路径

vim /data/3309/master_ip_failover

my $vip = '192.168.164.132/24';

my $key = '1';

my $ssh_start_vip = "/sbin/ifconfig ens160:$key $vip";

my $ssh_stop_vip = "/sbin/ifconfig ens160:$key down";

[root@db03 bin]# yum install -y dos2unix

[root@db03 bin]# dos2unix /usr/local/bin/master_ip_failover

[root@db03 bin]# chmod +x /data/3309/master_ip_failover

[root@db03 bin]# vim /etc/mha/app1.cnf

master_ip_failover_script=/data/3309/master_ip_failover

db01:手工添加vip

[root@db01 ~]# ifconfig ens160:1 192.168.164.132/24

db03 : 重启MHA

[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf

[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:14410) is running(0:PING_OK), master:192.168.164.130

[root@db03 bin]#

  1. MHA 故障提醒
    [root@db03 ~]# cp -a /data/email/* /usr/local/bin/

[root@db03 ~]# cd /usr/local/bin/

[root@db03 ]# chmod +x /usr/local/bin/*

[root@db03 bin]# vim /etc/mha/app1.cnf

report_script=/usr/local/bin/send

重启MHA:

[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf

[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 &

/usr/local/bin/sendEmail -o tls=no -f 13172491294@163.com -t 861700361@qq.com -s smtp.163.com:25 -xu 13172491294 -xp MUVXHOFMRBBKPHFK -u "MHA Waring" -m "YOUR MHA MAY BE FAILOVER" &>/tmp/sendmail.log

红色部分为授权码,不是用户密码,/tmp/sendmail.log为邮件日志路径

  1. 额外的数据补偿(binlog_server)
    (1)一般放在SSD上

找一台额外的机器,必须要有5.6以上的版本,支持gtid并开启,我们直接用的第二个slave(db03)

vim /etc/mha/app1.cnf

[binlog1]

no_master=1

hostname=192.168.164.131

master_binlog_dir=/data/binlog_server

(2) 创建必要目录

mkdir -p /data/binlog_server

chown -R mysql.mysql /data/*

(3) 拉取主库binlog日志

cd /data/binlog_server -----》必须进入到自己创建好的目录

mysqlbinlog -R --host=192.168.164.130 --port=3309 --user=mha --password=mha --raw --stop-never mysql-bin.000001 &

ps -ef | grep mysqlbinlog

注意:show master status;

拉取日志的起点,需要按照目前主库正在使用的binlog为起点.

(4) 重启MHA-manager

[root@db03 bin]# masterha_stop --conf=/etc/mha/app1.cnf

[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 &

  1. 故障模拟及故障处理
    8.1 宕掉 db01 数据库

/etc/init.d/mysqld stop

8.2 恢复故障
恢复思路

1看manager进程状态的两条语句

ps -ef | grep manager

masterha_check_status --conf=/etc/mha/app1.cnf

2.如果配置文件中已经剔除了故障节点信息,说明切换过程已经基本成功

如果配置文件中还保留故障节点信息,说明切换过程没有完成

3.看日志 /var/log/mha/app1/manager

(1) 启动故障节点并恢复其数据

[root@db01 ~]# /etc/init.d/mysqld start

systemctl start mysqld3309

(2) 恢复1主2从(db01)

[root@db03 bin]# grep "CHANGE MASTER TO" /var/log/mha/app1/manager

Thu Jul 18 18:31:54 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';

[root@db03 bin]#

db01 [(none)]>CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';

db01 [(none)]>start slave;

(3) 恢复配置文件(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

report_script=/usr/local/bin/send

4MHA状态检查

masterha_check_ssh --conf=/etc/mha/app1.cnf

masterha_check_repl --conf=/etc/mha/app1.cnf

(5)恢复binlogserver

cd /data/binlog_server

rm -rf /data/binlog_server/*

mysqlbinlog -R --host=192.168.164.130 --port=3309 --user=mha --password=mha --raw --stop-never mysql-bin.000003 &

6检查主库vip状态

(7) 启动MHA

[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 &

[1] 16543

[root@db03 bin]# masterha_check_status --conf=/etc/mha/app1.cnf

app1 (pid:16543) is running(0:PING_OK), master:10.0.0.52

  1. MHA配合Atlas实现读写分离

  2. Atlas 介绍

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.安装配置

yum install -y Atlas*

cd /usr/local/mysql-proxy/conf

mv test.cnf test.cnf.bak

vim test.cnf

[mysql-proxy]

admin-username = user

admin-password = pwd

proxy-backend-addresses = 192.168.164.132:3309

proxy-read-only-backend-addresses = 192.168.164.130:3309,192.168.164.131:3309

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=utf8mb4

mysql8.0默认使用33060 端口,如果在8.0上使用Atlas,proxy-address = 0.0.0.0:33060 端口要改成别的

Atlas和MGR不兼容

启动atlas

/usr/local/mysql-proxy/bin/mysql-proxyd test start

ps -ef |grep proxy

  1. Atlas功能测试

测试读操作:

mysql -umha -pmha -h 192.168.164.131 -P 33060

Atlas安装在哪个位置,-h 参数的值就是哪个位置

db03 [(none)]>select @@server_id;

测试写操作:

mysql> begin;select @@server_id;commit;

  1. 生产用户要求

开发人员申请一个应用用户 app( select update insert) 密码123456,要通过10网段登录

4.1 在主库中,创建用户

grant select ,update,insert on . to app@'10.0.0.%' identified by '123456';

4.2. 在atlas中添加生产用户

/usr/local/mysql-proxy/bin/encrypt 123456 ---->制作加密密码

vim /usr/local/mysql-proxy/conf/test.cnf

pwds = repl:3yb5jEku5h4=,mha:O2jBXONX098=,app:/iZxz+0GRoA=

/usr/local/mysql-proxy/bin/mysql-proxyd test restart

[root@db03 conf]# mysql -uapp -p123456 -h 10.0.0.53 -P 33060

  1. Atlas基本管理

连接管理接口

mysql -uuser -ppwd -h127.0.0.1 -P2345

select * from help;

SELECT * FROM backends;

set offline 2;

set online 2;

REMOVE BACKEND 3;

ADD SLAVE 10.0.0.53:3306;

ADD PWD oldguo:123456;