接下来,将在mysql 5.7.33 和mysql 8.0.37 一步一步进行主从复制搭建,并对一些细节问题展开详细说明。补充一下,5.7.35及以上版本在进行mysqldump时发现gtid_executed bug,故5.7版本采用33,8.0.37是目前使用未发现bug的8.0版本。
1、搭建複製必須知道的一些表和參數:master_info_repository 决定是file 还是table
启动复制从库会记录以下两张表
mysql.slave_master_info 对应io线程 更新次数由sync_master_info决定 一般10000个事务更新一次
mysql.slave_relay_log_info 对应slave 线程 实时更新(性能问题)
2、msyql 8.0 以上版本吗默认开启binlog (要关闭必须显示的设置 skip_log_bin或者disable_log_bin)
3、最简洁的主从
主:
server-id=1
log-bin=mysql-bin
从:
server-id=2
4、搭建最简单复制步骤
主库建立复制用户并授权(replication slave)
主库全库备份并还原至从库(mysqldump)(此处备份还原是一个研究点备份的并行和还原的并行,效率问题很重要)
备库change master to 4+2 (主机、端口、用户、密码+logfile 、pos)
'2'来源于备份文件 grep -m 1 "CHANGE MASTER TO" FULL_BACKUP.SQL
以上,搭建完毕!
检查:
主库:Binlog Dump 线程 (表示dump线程推送数据)
备库:Waiting for source to send event线程(表示io线程申请数据)
Replica has read all relay log; waiting for more updates (sql线程在等待重放数据)
5、gtid复制
普通的复制同一操作在不同机器上pos是不同的,MHA出现的背景即是如此,它能计算出搭建复制所需要的位置点。因此GTID的出现大大解决这一问题。gtid比普通复制更加高效的复制,在改变复制的拓扑结构时非常方便。
gtid=source_id:transaction_id (source_id 同 server_uuid 、transaction_id 只不过是事务的顺序提交记录而已);
说白了GTID就是server_uuid+事务提交顺序记录号 一台机器上面产生的事务一定全局唯一的。有了gtid,不需要再关心binlog的具体位置信息。
另外,补充一点,orchestrator是一个支持复杂的,基于binlog位置点的复制拓扑管理工具(其实就是GTID),具体细节后面讨论。
6、搭建GTID复制
主要与传统复制区别在以下两个方面:
1、参数配置方面(主节点)
gtid_mode=on (不是1 该参数是枚举值 不是布尔值)
enforce_gtid_consistency=1
在5.6中,还要增加:
log-bin=mysql-bin
log-slave-updates=1 ( log-slave-updates参数是一个布尔类型的参数,它决定了在从服务器(Slave)上是否将复制事件写入二进制日志文件(Binary Log))
其实这就意味着,在5.6中,从库也需要开启binlog
2、change master to 命令方面
4+1:master_host master_port master_user master_password + master_auto_position
7、GTID在在表示时由GTID_SET构成,对于一堆连续的GTID,会表示为UUID:1-11的样式
8、当事务提交时,系统会分配GTID(最小未使用的),然后记录事务操作,最后commit,这些操作都是原子性质的 。在binlog里面可以看到刚gtid事件(也可以看到事务提交的XID事件),事件的类型很多,我们后面在慢慢看。
9、从库应用事务,首先就要应用GTID事件,所以我们可以GTID事件来修复从库的复制报错。这一点是gtid主从恢复的核心,理解这一点很重要。
10、背诵GTID复制的9个参数
select @@global.gtid_mode (5.7.6之前是静态参数,修改需要重启,之后则为动态,可动态修改)
5.7.6之前事务分为gtid事务与非GTID事务
5.7.6之后分为匿名事务和gtid事务 同时新增两个选项:on_permissive、off_permissive
select @@gtid_next (session级)
有三个非常重要的结论:(两为两不为)
当gtid_next为automatic时,开启binlog,gtid_mode 只有设置为on_permisive和on时,新事务才为gtid形式,否则都为匿名事务,不计入MySQL.executed_gtids;关闭binlog,gtid_mode无论设置为什么,都是匿名事务。
当gtid_next为anonymous时,无论是否开启binlog,新增的事务都是匿名事务。
当gtid_next不为off时,无论gtid_mode设置为什么 都可以显示的设置gtid事务
select @@global.gtid_owned (只读参数,仅供内部使用)
select @@global.gtid_purged 有三个来源,分别是:在未开启binlog时与gtid_executed一致;来源于purge 操作;手动设置;
select @@global.gtid_executed 内存值,实时更新,关闭实例清空,开启实例重新初始化,初始化参数与binlog_gtid_simple_recovery有关。
reset master 会清空gtid_executed
MySQL8.0之前,要设置gtid_purged只能先清空executed_gtids,而清空gtid_executed只能reset master,8.0后取消了这个限制,但是还是有两点需要注意。
1.gtid_purged不能是gtid_executed中还未清除的,即二者不能有交集。
2、gtid_purged必须是gtid_executed的超集。( S1是S2的超集)
select @@global.gtid_executed_compression_period 从mysql 5.7开始引入,目的是为了不开启binlog却能使用gtid.(不开启GTID既能节省空间又能提高效率)
select @@global.binlog_gtid_simple_recovery 从5.7开始默认就是true executed 读取最新的binlog,gtid_executed 读取最旧的binlog。
select @@global.enforce_gtid_consistency (5.7.6之前是静态参数,修改需要重启,之后则为动态,可动态修改)为了保障主从一致,要求执行顺序一致
8.0.21之前版本不支持create table as select .......之后版本将该操作按照原子性处理,可以支持。
不允许在函数,存储过程,触发器等使用临时表,8.0.13之后版本在格式设置为row/mixed可支持
不允许非innodb与innodb表在一个事务内至执行(可用来检测是否违反该限制)
若gtid_mode为on,该参数也要为on。
11、关于GTID相关的一些函数
gtid_subset(集合1,集合2)判断集合1是否属于集合2
gtid_subtract(集合1,集合2)判断属于集合1但不属于集合2的gtid集合
wait_for_executed_gtid_set(集合,时间)
12、在线修改复制模式指的是在线开启和关闭gtid。
(主从)在线修改之前需要先设置enforce_gtid_consistency=warn,然后打开错误日志,观察有无违反GTID的sql,比如innodb和myisam的表放到一个一个事务中执行
(主从)然后逐步修改gtid_mode模式,off->off_permissive->on_permissive,到这一步时,检查:
show status like 'onconfig_anonymous_transaction_count';
(主从)必须为0,才能继续需改为on;
(主)修改完成后,检车主库的gtid:
show master status;
(从)在从库执行:select master_pos_wait('主库binlog file',主库position)
等待执行完毕!
在线关闭gtid的思路是:从库停止主从复制,将GTID复制转换为基于file和position的复制,然后主从逐步关闭gtid_mode(逆序开启的步骤,到off_permissive时 需要检查select @@global.gtid_owned 为空才可以继续关闭),最后在主库显示设置两个参数:
gtid_mode=off enforce_gtid_consitency=off