MySQL复制总结
MySQL复制分类
传统复制
GTID原理
半同步复制
并发复制
多源复制
延迟复制
MySQL5.7在复制方面的增强
传统复制
原理:
主库起一个dump_thread,连接从库的io_thread,将主库产生的binlog传输到从库的relay log,利用从库的sql_thread进行利用。
问题:MySQL复制是master把log推给slave,还是slave从master上把日志拉过来的。
个人感觉全量是拉,增量是推。
GTID原理
事物唯一编号,在一个复制的group里,全局唯一
同时和事物记录到binlog,用来标识事物,binlog中多一个:gtid_log_event
gtid的构成
UUID:sequence_Number
sequence_Number是MySQL内部的一个事物编号,一个MySQL不会重复的顺序号
每个MySQL实例都有一个全局唯一的UUID,在$datadir/auto.cnf中存储
gtid复制出现断点,估计是使用master_auto_position=0造成
例如:UUID:1-10:20-N
这种情况11-19的事物丢了考虑做一下数据校验(pt-table-checksum)
master_auto_position=1
MySQL可以记录执行过事物的gtid,可以通过show_master_status-->gtid_executed查看
MySQL5.6依赖于binlog和gtid_purged,MySQL5.7依赖于mysql.gtid_executed
slave 上记录了接受和执行的gtid,可以通过show slave status -->Retrieved_Gtid_Set,Executed_Gtid_Set查看
slave连接master时,会把gtid_exectued中的gtid发给master,master会skip过execute_gtid_set,把没有执行过的gtid事物发给slave。
注意:当dump thread的数量超过slave数量时,可能是由于slave net timeout参数设置过短导致的,系统默认3600秒。
MySQL5.7GTID启动过程
不产生gtid,salve只接受不带gtid的事物 | off |
不产生gtid,slave接受不带也接受带gtid事物 | off_permissive |
产生gtid,slave接受不带gtid事物也接受不带gtid事物 | on_permissive |
产生gtid,slave只接受带gtid的事物 | on |
线上非gtid转为gtid如何操作
set global gtid_mode=off_permissive;在group中每个MySQL上执行
set global gtid_mode=on_permissive;在group中每个MySQL上执行
确认每个group中的binlog非gtid的执行完毕
set global gtid_mode=on,在group中每个MySQL执行
MySQL5.7gtid会存储到gtid_executed表里,支持从库不用开启binlog(log_slave_updates)
有的slave不会切换成master,不用开启slave,可以节省空间,提高性能。MySQL5.6gtid只能存储在binlog中,所以必须开启binlog
如何记录gtid
如果开启binlog,在binlog切换时,将当前的gtid插入到gtid_executed表
insert into mysql.gtid_execcted(uuid,1000,2000);
如何没有开启binlog,每个事物提交前,会执行一个insert操作
begin:
。。。事物操作
insert into mysql.gtid_executed(uuid,1000,1000) #隐式MySQL内部添加
commit;
gtid_executed表压缩
控制压缩频率的参数:set global gtid_executed_compression_period=N;(N 事物个数, 默认是1000)
压缩前
压缩后
off 不检测是否有gtid不支持的语句事物
warn 当发现不支持语句事物,返回告警,并在日志中记录警告信息
on 当发现语句事物不支持gtid时,返回错误
tips
在线上从gtid到非gtid转换时,可以先设置成warn
gtid limit(限制)
不能使用create table...select....
改为:create table tb_1 like tb_2;insert into tb_1 select * from tb_2;
事物中更新非事物表:
begin;update no_trx_table set c1= xxx where xxx;update trx_table set c1 = xxx where xxx; commit;
事物中创建删除临时表:
begin;update trx_table set c1= xxx;create temporary table ...;commit;
sql_slave_skip_counter不支持
gtid跳过事物
stop slave sql_thread;
set gtid_next='uuid:101';
begin;commit;
set gtid_next='automatic';
start slave sql_thread;
删库的过程也是一直享受的过程!