通过二进制日志方式,达到2台以上MySQL实例数据“同步”。
创建从库的用户
grant replication slave on *.* to repl@'10.0.0.%' identified by '123';
连接主库
CHANGE MASTER TO
MASTER_HOST='10.0.0.51',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=674,
MASTER_CONNECT_RETRY=10;
#开启从库复制
start slave;
#重新架构从库
stop slave;reset slave all;
工作原理
从库执行change master to 语句: IP、 PORT 、USER、PASSWD、binlog起点,信息记录到master.info
从库执行start slave 。开启IO、SQL复制线程
从库IO开始工作,读取master.info: IP、 PORT 、USER、PASSWD,连接主库。
主库连接层接收到请求,验证通过后,生成 DUMP线程和IO线程交互。
从库IO 通过 master.info : binlog起点,找主库DUMP请求新的binlog
主库DUMP监控着binlog变化,接收到从库IO请求,截取最新的Binlog,TP给IO
从库IO接收到binlog,临时存储再TCP/IP缓存。主库工作到此为止。
从库IO将接收到的日志存储到relay-log中,并更新master.info。IO线程工作结束
从库SQL线程读取relay.info中,获取到上次回放到的relay-log的位置点
从库SQL回放新的relaylog,再次更新relay.info。SQL线程工作结束。
relay_log_purge线程,对relay-log有自动清理的功能。默认relay_log_purge=1
主库dump线程实时监控binlog的变化,自动通知给从库IO。
主库:
binlog
从库:
relay-log :存储请求过来的binlog
master.info : 保存主库信息(IP,PORT,USER,PASSWORD,binlog位置点)
relay-log.info :记录的是从库回放relaylog的位置点信息。
主库:
dump: 日志投递线程
从库:
IO : 连接主库,请求日志
SQL: 回放日志
监控
show slave hosts;
show slave status \G
Master_Host: 10.0.0.51
Master_User: repl
Master_Port: 3307
Connect_Retry: 10 #无法通信后10秒进行重试
主库已发送的log位置点
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 674
从库relaylog回放到的位置点
Relay_Log_File: db01-relay-bin.000004
Relay_Log_Pos: 320
从库的线程状态:log_error
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:
Executed_Gtid_Set:
故障分析
IO connecting 连接问题
可能最大连接数上线
IO NO
主库日志损坏。
日志起点写错。
server_id重复。
SQL NO
从库日志损坏,无法进行回放
cat /data/3308/data/relay-log.info #上次回放的日志点,重构从库
回放失败的原因
- 修改的对象不存在
- 创建的对象已存在
- 约束冲突
- 主从配置不同
- SQL_MODE不兼容
- 主从版本差异
方法1:stop slave;
set sql_slave_skip_counter = 1;
#将同步指针向下移动一个,如果多次不同步,可以重复操作。例如从库比主库优先创建了一个库,可以使用此方法
start slave;
方法2:为了防止用户对从库进行插入,采用read-only=1 super_read_only
延迟
主库方面
提供binlog
binlog日志文件落地不及时。sync_binlog=1
传输binlog
claassic 模式(无GTID),dump线程传输日志是串行的。主库可以并行多个事务。
大事务、并发事务量大。都会导致较高延时。
5.6 版本加入了GTID功能,在传输时就可以并行传输日志了。
5.7 版本即使没开GTID,会自动生成Anonymous_Gtid。
从库方面
SQL回放
单一SQL线程,只能串行回放relaylog。主库可以并发事务,并行传输日志,回放时是串行的。
如果 大事务,并发事务量大。都会导致较高回放延时。
5.6 版本 GTID模式下,可以开启多个SQL线程。但是,5.6多SQL回放时,只能针对不同database并行回放。
5.7 版本中GTID模式下,可以开启多个SQL线程,真正实现了并性回放(MTS)
过滤复制
配置文件
主库 :
binlog_do_db=world
binlog_ignore_db
只会将指定库写入二进制
从库:
库级别:
replicate_do_db=world
replicate_do_db=test
replicate_ignore_db=
表级别:
replicate_do_table=world.city
replicate_ignore_table=
模糊:
replicate_wild_do_table=world.t*
replicate_wild_ignore_table=
在线配置
stop slave sql_thread ;
change replication filter replicate_do_db=(oldguo,oldboy);
start slave sql_thread ;
延迟复制
配置
mysql>stop slave;
mysql>CHANGE MASTER TO MASTER_DELAY = 300; 设置为300秒
mysql>start slave;
应用
- stop slave;
- 查看realy回放到的位置点,查看master故障的位置点,在realy日志中进行截取
- 导入sql语句,从库替换为主库,或者表空间迁移
半同步复制
主库和从库下载插件,利用插件的功能,从库向主库发送syn,主库收到后再commit,可以设置syn的超时时间
gtid复制
优势
(1)每个事务都有唯一逻辑编号,并具备幂等性
(2)截取binlog时更加灵活、方便(include-gtids --exclude-gtids)
(3)主从复制,提高性能:dump传输日志并行,SQL线程并行回放。
(4)主从复制搭建、监控延时、数据一致性保证。
log-slave-updates=1 从库同时为主库时添加的参数,将realy中的sql语句写入binlog
[mysql]
prompt=db01 [\d]> 设置mysql命令提示符
构建主从
change master to
master_host='10.0.0.51',
master_user='repl',
master_password='123' ,
MASTER_AUTO_POSITION=1; #直接填入gtid号
#第一次构建主从时,自动检查最后一个relay的gtid信息,检查没有SET @@GLOBAL.GTID_PURGED='1c35b73a-7321-11ea-8974-000c29248f69:1-10'参数如果都没有信息。就从主库的第一个GTID事件开始全新复制binlog日志。
~~备份主库数据要恢复到从库时,不要加–set-gtid-purged=OFF ~~
Retrieved_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-3
Executed_Gtid_Set: 71bfa52e-4aae-11e9-ab8c-000c293b577e:1-2
stop slave;
set gtid_next='71bfa52e-4aae-11e9-ab8c-000c293b577e:3';
begin;commit;
set gtid_next='AUTOMATIC'; #自动查询
因为3号事务从库执行不了,所以注入空事务