企业高可用性标准
非计划内故障停机
99.9% ----> 0.001*365*24*60=525.6 min
99.99% ----> 0.0001*365*24*60=52.56 min
99.999% ----> 0.0001*365*24*60=5.256 min 金融级别
企业级高可用方案
负载均衡: 有一定的高可用性
- LVS
- Nginx
主备系统: 有高可用性,但是需要切换,是单活的架构
- KeepAlive
- MMM
- MHA 主流
真正高可用: 多活系统
- NDB Cluster (MySQL集群版)
- Oracle RAC (金融)
- Sysbase cluster
- **PXC**
- **MGC**
- <font color=red>**InnoDB Cluster (MGR 5.7.17)**</font>
主从复制简介
1) 基于二进制日志复制的
2) 主库的修改操作会记录二进制日志
3) 从库会请求新的二进制日志并回放,最终达到主从数据同步
4) 主从复制核心功能:
- 辅助备份,处理物理损坏
- 扩展新型的架构:高可用,高性能,分布式架构等
主从复制的前提
1)多节点,至少2个数据库实例
2)server_id 必须且唯一,uuid 唯一,主库要开启binlog
3)主库需要一个专门用作复制的用户 (replication slave)
4) 通过备份将源库数据补偿到从库
5)告知从库:复制使用的 用户,密码,IP,port,复制的文件和起点
6)需要专门的复制线程 (start slave)
主从复制部署
环境说明
使用了一台虚拟机,做了多实例.
mysql3307 端口 3307
mysql3308 端口 3308
准备多实例环境
systemctl start mysqld3307.service
systemctl start mysqld3308.service
mysql -S /data/3307/mysql.sock
mysql -S /data/3307/mysql.sock
检查主库binlog,server_id
-- 3307实例操作
mysql[(none)]>select @@log_bin;
mysql[(none)]>select @@server_id;
主库创建复制用户
# 3307实例操作
mysql[(none)]>grant replication slave on *.* to repl@'10.0.0.%' identifieed by '123456';
# 查看用户是否创建成功
mysql[(none)]>select user,host from mysql.user where user='repl';
通过备份将源库数据补偿到从库
# 主库备份
mysqldump -S /data/3307/mysql.sock -A -R -E --triggers --master-data=2 --single-transaction --max-allowed-packet=128M >/tmp/full.sql
# 从库恢复
mysql -S /data/3308/mysql.sock </tmp/full.sql
告知从库,用户名,密码,IP ,port,自动复制的起点
# 登录从库
mysql -S /data/3308/mysql.sock
# 告知从库关键复制信息(登录从库执行)、3308
CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000009',
MASTER_LOG_POS=444,
MASTER_CONNECT_RETRY=10;
帮助与参数说明
获取主/从数据库通讯命令: help change master to
命令参数说明:
CHANGE MASTER TO
MASTER_HOST='10.0.0.51', --> 主库的IP
MASTER_USER='repl', --> 主库复制用户
MASTER_PASSWORD='123456', --> 主库复制用户密码
MASTER_PORT=3307, --> 连接主库的端口
MASTER_LOG_FILE='mysql-bin.000006', --> 需要复制的二进制日志名
MASTER_LOG_POS=444, --> 需要复制的二进制日志起始位置
MASTER_CONNECT_RETRY=10;
启动线程
# 开启从库线程、3308实例操作
mysql[(none)]>start slave;
检查主从状态
mysql -S /data/3308/mysql.sock -e "show slave status\G"|grep 'Yes'
--- 显示一下代表成功
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
简单排错过程
mysql -S /data/3308/mysql.sock -e "show slave status \G;"|grep "Last"
主从复制原理
主从复制过程中涉及到的文件
主库:
- binlog -- 记录主库的数据变化
从库:
- relaylog -- 中继日志,临时存储日志信息的文件
- master.info -- 信息文件,保存master的相关信息
- relay-log.info -- 信息文件,记录上次SQL线程执行过的relaylog的位置点
主从复制中涉及到的线程
Master 与 Slave 之间实现整个主从复制的过程是由三个线程参与完成的。
主库(Master) :
Binlog_dump_Thread
从库(Slave) :
Slave_IO_Thread
Slave_SQL_Thread
主从复制原理
主从复制的监控
从库:
线程状态
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Running:"
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
线程报错具体信息
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Last"
Last_Errno: 0
Last_Error:
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
查看主库连接信息有关
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Master"
Master_Host: 10.0.0.51
Master_User: repl
Master_Port: 3307
Master_Log_File: mysql-bin.000012
Read_Master_Log_Pos: 154
Relay_Master_Log_File: mysql-bin.000012
Exec_Master_Log_Pos: 154
从库和主库延时的时间
[root@db01 ~] mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Seconds_Behind_Master"
过滤复制相关状态
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep " Replicate_"
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Replicate_Ignore_Server_Ids:
Replicate_Rewrite_DB:
延时从库的状态信息
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Delay:"
SQL_Delay: 0
SQL_Remaining_Delay: NULL
监控Gtid复制状态信息
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Gtid"
Retrieved_Gtid_Set:
Executed_Gtid_Set:
中继日志监控
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show slave status \G"|grep "Relay"
Relay_Log_File: db01-relay-bin.000005
Relay_Log_Pos: 367
Relay_Master_Log_File: mysql-bin.000012
Relay_Log_Space: 739
主从复制故障
IO线程
(1)读取master.info
损坏
信息错误: change master to 信息错误
(2)连接主库
网络
防火墙
主机/主库没启动
连接数上限
(3)请求日志
master.info 复制起点
主库:损坏,误删除等
(4)接收日志
relaylog 损坏
(5)更新master.info
解决方法:
通过复制用户,手工连接主库,查看报错信息
> stop slave
> reset slave all;
> change master to
> start slave
SQL线程故障 *****
relay.info
回访 relaylog 中的日志 *
SQL语句无法解析
- 语法,SQL_Mode。版本差异,sql_mode不一致
DDL DCL DML 为什么会失败
从库被提前写入
处理方法(以从库为核心的处理方案):
方法一:
stop slave;
set global sql_slave_skip_counter = 1;
#将同步指针向下移动一个,如果多次不同步,可以重复操作。
start slave;
方法二:
/etc/my.cnf
slave-skip-errors = 1032,1062,1007
常见错误代码:
1007:对象已存在
1032:无法执行DML
1062:主键冲突,或约束冲突
防止从库写入(以从库为核心的方案)
主从延时
主从延时简介
主库做的事,从库很久才执行
主从延时的现象
最直观:主库做变更,从库看数据状态
Seconds_Behind_Master: 0 (只能证明,有或者没有)
计算日志的差异 ※
主从延时的原因
外部原因
- 网络,硬件
- 主库繁忙
- 版本差异
- 参数差异
内部因素
主库:
(1) 二进制日志方面
二进制日志落地不及时
解决方案:
- sync_binlog=1
可以将binlog 单独存放高性能存储中
(2) dump_T(线程) - 默认串行工作模式
主库的事务量大
主库发生大事务
解决方案:
1. GTID 模式
2. 双1的保证
如何监控:
主库: show master status;
从库:show slave status\G
从库:
(1) IO 线程方面
relaylog写入
解决方案:
可以将relaylog单独存放高性能存储中
| relay_log_basename | /data/3308/data/db01-relay-bin |
| relay_log_index | /data/3308/data/db01-relay-bin.index |
(2) SQL线程方面(只有一个,串行回放)
默认SQL线程,只能逐条的回放SQL
事务并发高
大事务
5.6 版本 加入了多SQL复制
按照库(database)级别,进行并发回放SQL
slave_parallel_workers=16
slave_parallel_type=DATABASE
5.7 版本 进行了多SQL复制加强(MTS)
真正按照事务级别,实现了多SQL线程回放
slave_parallel_workers=16
slave_parallel_type=logical_clock
注意:必须依赖于 GTID复制
如何监控 :
(1) 监控取了多少日志
show slave status \G
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1084
(2) 回放了多少日志
[root@db01 /data/3308/data]# cat relay-log.info
7
./db01-relay-bin.000003
920
mysql-bin.000001
1084