Mysql Replication(主从复制)
职责介绍:
(1)、搭建主从复制 ***
(2)、主从复制原理熟悉 *****
(3)、主从的故障处理 *****
(4)、主从延时 *****
(5)、主从的特殊架构的配置使用 ****
(6)、主从架构的演变 ****
2、主从复制介绍
(1)、主从复制基于binlog来实现的
(2)、主库发生新的操作,都会记录binlog
(3)、从库取得主库的binlog进行回放
(4)、主从复制的过程是异步
3、主从复制的前提(搭建主从复制的过程)
(1)、两个或两个以上的数据库实例
(2)、主库需要开启二进制日志
(3)、server_id要不同,用来区分不同的节点
(4)、主库需要建立专用的复制用户(replication slave 权限)
(5)、从库应该通过备份主库,恢复的方法进行"补课"
(6)、人为告诉从库一些复制信息(ip,port,user,password,二进制日志起点)
(7)、从库应该开启专门的复制线程
4、主从复制搭建过程(一台数据库192.168.189.128主库已有数据的情况下)
4.1、准备1台服务器(192.168.189.131从库),安装mysql 5.7.26
4.2、检查配置文件
主库:二进制日志是否开启,从库可以先不开。
主从节点:server_id不能相同,一般建议,主库的server_id比从库的server_id小
4.3、主库上创建复制用户
mysql -uroot -p -e "grant replication slave on *.* to repl@'192.168.%' identified by 'repl.com';"
4.4、'补课',就是把主库上面的最近一次全备数据恢复到从库上
备份主库的数据:
mysqldump -uroot -p -A --master-data=2 --single-transaction -R -E --triggers >/tmp/master.sql
scp -r /tmp/master.sql root@192.168.189.131:/tmp/
从库:导入主库的备份
登录mysql
set sql_log_bin=0;
source /tmp/master.sql;
set sql_log_bin=1;
4.5、告诉从库信息(主库的信息IP 端口,用户名和密码)
vim /tmp/master.sql
change master to master_host='192.168.189.128',master_user='repl',master_password='repl.com',master_log_file='mysql-bin.000011',master_log_pos=485,master_connect_retry=5;
master_connect_retry=5 ##重新连接的次数,如果主从数据库断开,从库会自动重连,超过10次,表示连接失败。
4.6、从库开启复制线程(从库上有两个线程,IO线程,SQL线程)
start slave;
4.7、检查主从复制的状态
show slave status\G
5、主从复制原理
5.1、主从复制中涉及的文件
主库:binlog
从库:
relaylog:中继日志
master.info:主库信息文件
relaylog.info:relaylog应用的信息
5.2、主从复制中涉及的线程
主库:binlog_dump Thread:简称:DUMP_T
从库:SLAVE_IO_THREAD 简称:IO_T
SALVE_SQL_THREAD 简称:SQL_T
5.3、主从复制工作过程原理
(1)、从库执行change master to 命令(主库的连接信息+复制的起点)
(2)、从库会将以上信息,记录到master.info文件中
(3)、从库执行 start slave 命令,立即开启IO线程和SQL线程
(4)、从库IO线程读取master.info文件中的信息,获取到IP,PORT,User,Password,binlog的位置信息
(5)、从库IO线程请求连接主库,主库专门提供一个DUMP线程,负责和从库的IO线程交互。
(6)、从库IO线程根据binlog的位置信息(mysql-bin.000011,485),请求主库新的binlog
(7)、主库通过DUMP线程,将最新的binlog,通过网络传输给从库的IO线程
(8)、从库的IO线程接收到新的binlog日志,存储到TCP/IP缓存中,立即返回ACK给主库,并更新从库的master.info
(9)、从库的IO线程将TCP/IP缓存中数据,转储到磁盘的relaylog 中。
(10)、从库的SQL线程读取relay-log.info中的信息,获取到上次已经应用过的relaylog的位置信息
(11)、从库的SQL线程会按照上次的位置点,回放最新的relaylog,再次更新relay-log.info信息
(12)、从库会自动purge(清除)应用过relaylog,进行定期清理。
补充说明:
一旦主从复制构建成功,主库中的数据发生了新的变化,都会通过DUMP线程,发送一个信息给从库的IO线程,IO立即请求主库新的binlog,并进行数据同步。增强了主从复制的实时性,不过Mysql主从复制 依然是个异步过程。因为只有等主库上的日志写到磁盘上后,从库IO线程才能请求。
5.4、主从复制监控:
show slave status\G
******* 主库有关的信息(master.info) ********
Master_Host: 192.168.189.128
Master_User: repl
Master_Port: 3306
Connect_Retry: 5
Master_Log_File: mysql-bin.000011
Read_Master_Log_Pos: 955
******* 从库relay 应用信息有关的(relay.info):
Relay_Log_File: dba01-relay-bin.000002 ##默认在,数据目录/data/mysql/data/主机名-relay-bin.000001开始,可自定义
Relay_Log_Pos: 790 ##上次SQL线程已经运行到这个position了
Relay_Master_Log_File: mysql-bin.000011
******* 从库线程运行状态(排错) *****
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
****** 过滤复制有关的信息: *****
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
从库延时主库的时间(秒):
Seconds_Behind_Master: 0
延时从库:就是和主库相差多久时间,才开始同步。
SQL_Delay: 0
SQL_Remaining_Delay: NULL
********* GTID复制有关的状态信息: *******
Retrieved_Gtid_Set: 7cd51543-8d03-11ea-83e7-000c29e6dd30:2-3
Executed_Gtid_Set: 7cd51543-8d03-11ea-83e7-000c29e6dd30:1-3,b3060a95-5e86-11ea-bdb9-000c29e6dd30:1-54
Auto_Position: 0
5.5、主从复制故障 *****
从库:
5.5.1、IO线程故障:
(1)、连接主库:(网络,连接信息错误或者变更了,防火墙,连接数上限。)IO状态为:connecting
排查思路:
用复制用户,手工登录mysql,根据错误信息判断问题所在。
解决:
stop slave;
reset slave all;
change master to ..........
start slave;
(2)、请求主库上的binlog
主库上binlog 没开
主库上的binlog损坏,不存在
主库上执行了,reset master; binlog日志mysql-bin.000001 154
解决:
在从库上操作:
stop slave;
reset slave all;
change master to .........master_log_file='mysql-bin.000001',master_log_pos=154
start slave;
(3)、存储主库上的binlog到从库的relaylog
出现relaylog不能写入,这种情况很少。
处理:
修改权限
重启新启动主从
5.5.2、SQL线程故障:
处理方法:
把握一个原则,一切以主库为准,进行解决。
如果出现问题,尽量进行反操作
最直接稳妥办法,重新构建主从。
暴力的解决方法:
方法一:
stop slave;
set global sql_slave_skip_counter=1;
start slave;
#将同步指针向下移动一个,如果多次不同步,可以重复操作。
方法二:
/etc/my.cnf
slave-skip-errors=1032,1062,1007
重启服务,生效。
常见错误代码:
1007:对象已存在
1032:无法执行DML
1062:主键冲突,或约束冲突。
主库,从库上,找到有问题的主键值的,update从库上的值(一切已主库为准),update之后,再跳过这个错误。
stop slave;
set global sql_slave_skip_count=1;
start slave;
主库上操作:
use test;
create table t1 (id int primary key not null auto_increment,name varchar(10));
insert into t1(name) values('zhangsan'),('lishi'),('wangwu'),('ysj');
commit;
从库上操作:
use test;
select * from t1;
insert into t1(name) values('scl');
++++++++ 这时,再回到主库上的 test库,插入一条记录
insert into t1(name) values('wfz');
++++++ 这时,在从库上,查看slave 状态:
解决方法:
(1)、在从库上,更新test库t1表第5行值,为主库test 库t1表,第5行的值(一切以主库为主)
use test;
update t1 set name='wfz' where id=5;
(2)、stop slave;
set global sql_slave_skip_counter=1;
start slave;
show slave status\G
****** 如果开启了GTID
从库操作:
stop slave;
reset master;
set @@global.gtid_purged='7cd51543-8d03-11ea-83e7-000c29e6dd30:2-8';
7cd51543-8d03-11ea-83e7-000c29e6dd30:2-8 就是,报错的时候,Retrieved_Gtid_Set: 的内容
上面这些命令的用意是,忽略7cd51543-8d03-11ea-83e7-000c29e6dd30:2-8 这个GTID事务,下一次事务接着从 9 这个GTID开始,即可跳过上述错误。
start slave;
show slave status\G
++++++++++++++++++++++
为了很大程度的避免 SQL 线程故障:
(1)、把从库设为只读
用参数来控制的
show variables like '%read_only%';
| read_only | OFF | 针对普通用户
| super_read_only | OFF | 针对root用户
添加到配置文件中,重启。现在一般用得少。
(2)、使用读写分离中间件技术,使用较多。
atlas
mycat
proxySQL
MaxScale
+++++++++++++++
5.6、主从延时监控及原因 ******
5.5.6.1、主库方面原因
(1)、binlog写入不及时
sync_binlog=1 # 1 ,事务提交后,binlog立即写入磁盘
(2)、默认情况下主库的DUMP线程是,串行(一个一个的传)传输binlog 的,在并发事务量大时或者大事务,由于DUMP线程是串型工作的,导致传送日志较慢。
如何解决问题?
必须开启GTID,使用Group commit方式,可以支持DUMP线程 并行操作。
必须开启双1 标准。
(3)、主库及其繁忙
慢语句、、、、、 锁等待 从库的个数多 网络延时
5.6.2、从库方面的原因
(1)、传统复制(classic)中,如果主库并发事务量很大,或者出现大事务,由于是SQL单线程,导致不农牧民传的日志有多少,一次只能执行一个事务
5.6版本有了GTID,可以实现多SQL线程,全是只能基于不同库的事务,进行回放。
5.7版本中,有了增强的GTID,基于事务,增加了seq_no机制,增加了新型的并发SQL线程,叫逻辑时钟(logical_clcok),实现了事务级别的回放,把这种从库多线程SQL,称之为MTS技术。(多线程复制)
(2)、主从硬件差异太大
(3)、主从的参数配置不一样
(4)、从库和主库的索引不一样
(5)、主从的版本不一样
主从延时的监控:
从库延时主库的时间(秒):
Seconds_Behind_Master: 0
主库方面原因的监控:
主库:show master status;
从库:show slave status;
Master_Log_File: mysql-bin.000011
Read_Master_Log_Pos: 2230
从库方面原因监控:
判断是不是SQL原因,首先我们要知道,执行了多少日志,请求了多少日志
show slave status;
拿了多少:
Connect_Retry: 5
Master_Log_File: mysql-bin.000011
Read_Master_Log_Pos: 2230
执行了多少:
Relay_Log_File: dba01-relay-bin.000003
Relay_Log_Pos: 360
++++++++++++++++++++++++++++++
Exec_Master_Log_Pos: 2230 #主库的位置,如果这个值和 Read_Master_Log_Pos 相差大了,就是从库的SQL线程导致慢了。
Relay_Log_Space: 2478 ##这是relaylog的位置