MySQL 在线开启/关闭GTID
一 前言
MySQL DBA大都熟悉 MySQL 5.6版本开始提供基于 GTID模式的主从复制,该特性简化复制和降低主从复制维护的难度,提高复制的可运维性,不再依赖binlog文件名和文件中的位置。 但是它有很多限制,5.7版本MySQL支持对GTID做了如下改进:
a 不需要重启MySQL服务器.
b 配置过程在线,整个复制集群仍然对外提供读和写的服务.
c 不需要改变复制拓扑结构.
d 可以在任何结构的复制集群中在线启用GTID功能.
在线修改GTID时,必须按照如下顺序
OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON
不能跳过其中环节,比如gtid_mode 从off 不能直接变为on,否则MySQL会进行提示。
ERROR 1788 (HY000): The value of @@GLOBAL.GTID_MODE can only be changed one step at a time: OFF <-> OFF_PERMISSIVE <-> ON_PERMISSIVE <-> ON. Also note that this value must be stepped up or down simultaneously on all servers. See the Manual for instructions.
在实践online升级之前,我们需要了解MySQL 5.7版本的GTID_MODE 的含义:
OFF :不产生GTID,Slave只接受不带GTID的事务
OFF_PERMISSIVE :不产生GTID,Slave即接受不带GTID的事务,也接受带GTID的事务
ON_PERMISSIVE :产生GTID,Slave即接受不带GTID的事务,也接受带GTID的事务
ON :产生GTID,Slave只能接受带GTID的事务。
二 在线开启GTID
需要说明的是只有数据库版本是5.7.6以及之后的版本才能支持在线开启GTID. 在测试开启GTID的同时模拟主库的读写压测:
sysbench --test=oltp.lua --oltp-tables-count=1 --oltp-table-size=500000 --mysql-db=sysbench --mysql-user=sysbench --mysql-password=sysbench --mysql-socket=/srv/my3316/run/mysql.sock --max-time=600 --num-threads=1 --oltp-test-mode=complex run
2.1 在主从复制结构中所有的实例中执行
set global ENFORCE_GTID_CONSISTENCY = WARN;
在正常运行的业务系统数据库中,设置ENFORCEGTIDCONSISTENCY为WARN,目的是观察err log是否有不满足要求的sql出现。如果有发现任何warning,需要通知应用进行调整相关sql,直到不出现warning为止。GTID 使用限制如下:
1.不支持非事务引擎。
2.不支持create table ... select 语句(在主库执行时直接报错)。
3.不允许一个SQL同时更新一个事务引擎和非事务引擎的表。
4.不支持create temporary table和drop temporary语句。
如果没有任何warning 出现,则在所有实例上执行:
set global ENFORCE_GTID_CONSISTENCY = ON;
2.2 在主从复制结构中所有实例中执行:
set global GTID_MODE = OFF_PERMISSIVE;
让主库不产生GTID,Slave实例即接受不带GTID的事务,也接受带GTID的事务。确保一定要在所有实例中执行完该命令之后再执行接下来的步骤。
2.3 在主从复制结构中所有实例中执行:
set global GTID_MODE = ON_PERMISSIVE;
主库开始产生GTID,Slave即接受不带GTID的事务,也接受带GTID的事务。
2.4 在主从复制结构中所有的实例中执行:
在各个实例节点上执行如下命令检查匿名事务是否消耗完毕,最好多检查几次,以便确认该参数的值是0.
[RW][TEST:3316]>SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
+-------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------+-------+
| Ongoing_anonymous_transaction_count | 0 |
+-------------------------------------+-------+
1 row in set (0.00 sec)
如果在从库上检查只需要一次满足为0 即可。
2.5 确保第四步之前的binlog全部为应用。
确保操作之前的所有binlog都已经被其他服务器应用了,因为匿名的GTID必须确保已经复制应用成功,才可以进行下一步操作。如何检查呢? 其实最简单的方式是在从库库执行show slave status检查应用位点的情况。如果追上了,则可以继续。否则需要等待从库应用完binlog之后在进行下一步。
2.5 在主从复制结构中所有的实例中执行:
set global GTID_MODE = ON;
该参数的功能是让系统产生GTID ,Slave只能接受带GTID的事务。
2.6 在从库上执行:
设置slave 复制中MASTER_AUTO_POSITION=1。
[RO][TEST:3316]>stop slave;
[RO][TEST:3316]>CHANGE MASTER TO MASTER_AUTO_POSITION = 1;
[RO][TEST:3316]>[RW][TEST:3316]>start slave;
至此,将基于位点的复制关系升级为GTID模式。结束了吗?还没呢,记得修改my.cnf 添加
gtid_mode = on
enforce_gtid_consistency = on
三 在线关闭GTID
关闭GTID的步骤其实和开启的步骤相反:
3.1 关闭slave 复制中的 MASTERAUTOPOSITION
[RO][TEST:3316]>stop slave;
[RO][TEST:3316]>CHANGE MASTER TO MASTER_LOG_FILE = file,
MASTER_LOG_POS = position MASTER_AUTO_POSITION = 0;
[RO][TEST:3316]>[RW][TEST:3316]>start slave;
3.2 在所有的实例上执行:
set global GTID_MODE = ON_PERMISSIVE;
3.3 在所有的实例上执行:
set global GTID_MODE = OFF_PERMISSIVE;
3.4 等待 @@GLOBAL.GTID_OWNED 的值是一个空字符串为止。
SELECT @@GLOBAL.GTID_OWNED;
3.5 检查master上的binlog中的日志都已经被slave应用完毕
3.6 在所有实例上设置GTID_MODE 为off
set global GTID_MODE = OFF;
3.7 在所有实例上执行:
SET global GTID_MODE = OFF; SET global ENFORCE_GTID_CONSISTENCY = OFF;
3.8 删除或者注释my.cnf中的GTID相关参数。
四 参考文章
https://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-enable-gtids.html
https://dev.mysql.com/doc/refman/5.7/en/replication-mode-change-online-disable-gtids.html
- python——时间与时间戳之间的转换
- Maven 核心原理解析(3)
- String中的null,以及String s;等区别详解
- Shell编程——Shell中的数学运算
- 如何利用微信监管你的TF训练?
- python 安装spark_Spark环境搭建 (Python)
- MongoDB触发oom-killer的简单处理(一)(r7笔记第54天)
- int与integer的区别
- java 自动装箱与拆箱
- python读取文件——python读取和保存mat文件
- python 利用递归实现全排列
- java中 == 与 equal 的区别
- python基础知识——字符串
- python 实现数据降维推荐系统(附Python源码)
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 我服务又双叒叕奔溃了,含泪干货分享
- Azure DevOps+Docker+Asp.NET Core 实现CI/CD(一 .简介与创建自己的代理池)
- Android数据库高手秘籍(十二),LitePal的索引功能
- 使用pm2管理go应用进程
- 用Docker搭建Redis主从复制的集群
- IDEA 非常重要的一些设置项 → 一连串的问题差点让我重新用回 Eclipse !
- ArrayList源码分析(基于jdk1.8)(二):subList陷阱补充
- Windows10中安装Docker
- Windows下Docker安装ClickHouse
- ArrayList源码分析(基于jdk1.8)(三):Arrays.asList方法带来的问题
- 对基本类型包装类常量池的补充
- 与IntegerCache有关的一个比较坑的面试题
- C# Foreach循环本质与枚举器
- Java中的时间和日期(一):有关java时间的哪些坑
- Java中的时间和日期(二):java时间存储的基本原理