在线开启gtid功能方法

发布时间 2023-06-14 17:06:49作者: 阿rua

 

MySQL 在线开启/关闭GTID

文档

目录

一 前言 1

二 在线开启GTID 1

2.1 在主从复制结构中所有的实例中执行 1

2.2 在主从复制结构中所有实例中执行: 2

2.3 在主从复制结构中所有实例中执行: 2

2.4 在主从复制结构中所有的实例中执行: 2

2.5 确保第四步之前的binlog全部为应用。 2

2.5 在主从复制结构中所有的实例中执行: 2

2.6 在从库上执行: 2

三 在线关闭GTID 3

3.1 关闭slave 复制中的 MASTERAUTOPOSITION 3

3.2 在所有的实例上执行: 3

3.3 在所有的实例上执行: 3

3.4 等待 @@GLOBAL.GTID_OWNED 的值是一个空字符串为止。 3

3.5 检查master上的binlog中的日志都已经被slave应用完毕 3

3.6 在所有实例上设置GTID_MODE 为off 3

3.7 在所有实例上执行: 3

3.8 删除或者注释my.cnf中的GTID相关参数。 3

四 参考文章 3

一 MySQL各个版本对GTID的变化

MySQL 5.6版本

• 简化复制和降低主从复制维护的难度

• 提高复制的可运维性,不再依赖binlog文件名和文件中的位置

MySQL 5.7版本

• 不需要重启MySQL服务器.

• 配置过程在线,整个复制集群仍然对外提供读和写的服务.

• 不需要改变复制拓扑结构.

• 可以在任何结构的复制集群中在线启用GTID功能.

MySQL 8.0版本

MySQL 8.0 对 GTID 的限制解除

• CREATE TABLE ... SELECT statements.

• Temporary tables.

在线修改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.

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 after)

模拟生产环境:

# 准备工作

# db内创建环境

mysql -uroot -pmysql -h172.72.0.100 -P3306 -S/tmp/mysql.sock

CREATE DATABASE sbtest;

# 检查各项参数,最大用户连接、最大连接、会话最大prepared语句数

select @@max_user_connections,@@max_connections,@@max_prepared_stmt_count;

show global status like 'com_stmt%';

# 设置最大连接数、会话语句最大准备数

set GLOBAL max_connections=1000;

set global max_prepared_stmt_count=65536;

# 用远程连接MySQL使用oltp方式进行16个线程在sbtest库下创建10张10000行的表

sysbench /usr/share/sysbench/oltp_common.lua --time=100 --mysql-host=172.72.0.100 --mysql-port=3306 --mysql-user=root --mysql-password=mysql --mysql-db=sbtest --table-size=10000 --tables=10 --threads=16 --events=999999999 prepare

# 使用500个连接压测十分钟读写操作(无事务限制),结束自动关闭连接

sysbench /usr/share/sysbench/oltp_read_write.lua --time=600 --mysql-host=172.72.0.100 --mysql-port=3306 --mysql-user=root --mysql-password=mysql --mysql-db=sbtest --table-size=10000 --tables=10 --threads=500 --events=999999999 --report-interval=10 --db-ps-mode=disable --forced-shutdown=1 run > 500.txt

# 清理压测数据操作

sysbench /usr/share/sysbench/oltp_read_write.lua --time=60 --mysql-host=172.72.0.100 --mysql-port=3306 --mysql-user=root --mysql-password=mysql --mysql-db=sbtest --table-size=10000 --tables=10 --threads=400 --events=999999999 --report-interval=10 --db-ps-mode=disable --forced-shutdown=1 cleanup

2.1 在主从复制结构中所有的实例中执行

set global ENFORCE_GTID_CONSISTENCY = 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\G 检查应用位点的情况。

2.6 在主从复制结构中所有的实例中执行:

set global GTID_MODE = ON;

让系统产生GTID ,Slave只能接受带GTID的事务。

2.7 在从库上执行:

设置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;

2.8 修改my.cnf 添加

gtid_mode = on

enforce_gtid_consistency = on

 

三 在线关闭GTID

关闭GTID的步骤和开启的步骤相反:

3.1 关闭slave 复制中的 MASTERAUTOPOSITION (需指明当前主库的binlog和pos)

[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应用完毕

主:SHOW MASTER;

从:SHOW SLAVE STATUS\G

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