MySQL8.0对GTID的限制解除-创建临时表的语句放入事务未生成GTID

1.MySQL gtid;

在MySQL5.6以及MySQL5.7 上使用 GTID,一直以来都有几个硬性限制。
CREATE TABLE ....SELECT; 
CREATE TEMPORARY TABLE ...;
针对这两条SQL,如果想在GTID模式下使用,为了不破坏事务一致性,是被严格显示不允许的。
为了满足需求,一般会通过其他途径绕过这些限制。这个硬性限制随着MySQL8.0的新特性的发布,
连带着被间接取消掉。比如MySQL8.0的DDL原子性。

MySQL5.7环境下:
create table ...select ;这条语句 语义上分别属于两个隐式事务(一条DDL语句,一条DML语句)。
但在GTID开启后,单个语句只能给它分配一个GTID事务,如果强制使用,会直接报违反GTID一致性。
create table t1(id int primary key,log_date date);
insert t1 values(1,'2022-01-02');
create table t2 as select * from t2; 
Error 1786(HY000):Statement violates GTID consistency:CREATE TABLE .. SELECT; 

#替换方案 
create table t2 like t1; #Like语句不插入数据。也不创建索引。
insert into t2 select * from t1; 
对应的binlog 数据,将被拆分为2个事务。

对于显式临时表的床与删除,这样的DDL在GTID模式下也是禁止放在事务块里执行的。
(begin;commit;或者存储过程,存储函数,触发器等大事务块)。
begin;
create temporary table temp(id int);
ERROR:1787 :Statement violates GTID consistency:CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE;
把这类DDL语句放在事务块外面或者使用基于磁盘表的DDL语句来替代。
create temporary table temp2(id int,log_date date);
begin; 
insert into temp2 values(100,'2025-05-20');
insert into temp1 select * from temp2;
commit; 

#MySQL5.7不允许在事务块创建临时表。MySQL8.0允许在事务块里创建临时表。

2.MySQL8.0原生DDL原子性

所以解除了这两个GTID的限制。
对于create table ...as select * from ..; 语句。在MYSQL8.0版本中只会生成一个GTID事务号。
show binlog events in 'binlog.000001'\G;
对于事务块里有临时表的DDL语句,可以正常执行。
#开启GTID;
[mysqld]
gtid_mode=ON
enforce_gtid_consistency=ON
log_bin=mysql-bin

reset master; 


mysql> drop table t;
Query OK, 0 rows affected (1.49 sec)

mysql> show master status\G
*************************** 1. row ***************************
             File: binlog.000001
         Position: 360
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: fa68231f-8d1b-11ef-a4d3-fa163e2f8777:1
1 row in set (0.00 sec)

#没有生成事务ID;
begin; 
create temporary table tmp(a int ,b date);
insert into tmp values(10,'2025-05-20');
commit;

mysql> show binlog events in 'binlog.000001';
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         126 | Server ver: 8.0.28, Binlog ver: 4                                  |
| binlog.000001 | 126 | Previous_gtids |         1 |         157 |                                                                    |
| binlog.000001 | 157 | Gtid           |         1 |         234 | SET @@SESSION.GTID_NEXT= 'fa68231f-8d1b-11ef-a4d3-fa163e2f8777:1'  |
| binlog.000001 | 234 | Query          |         1 |         360 | use `test`; DROP TABLE `t` /* generated by server */ /* xid=318 */ |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
4 rows in set (0.01 sec)

#DROP TABLE 产生一个GTID;创建临时表的事务并没有生成GTID;
mysql> create table t2(id int);
Query OK, 0 rows affected (2.67 sec)

mysql> show binlog events in 'binlog.000001';
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         126 | Server ver: 8.0.28, Binlog ver: 4                                  |
| binlog.000001 | 126 | Previous_gtids |         1 |         157 |                                                                    |
| binlog.000001 | 157 | Gtid           |         1 |         234 | SET @@SESSION.GTID_NEXT= 'fa68231f-8d1b-11ef-a4d3-fa163e2f8777:1'  |
| binlog.000001 | 234 | Query          |         1 |         360 | use `test`; DROP TABLE `t` /* generated by server */ /* xid=318 */ |
| binlog.000001 | 360 | Gtid           |         1 |         437 | SET @@SESSION.GTID_NEXT= 'fa68231f-8d1b-11ef-a4d3-fa163e2f8777:2'  |
| binlog.000001 | 437 | Query          |         1 |         548 | use `test`; create table t2(id int) /* xid=567 */                  |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
6 rows in set (0.00 sec)

创建临时表的事务没有生成GTID;#create temporary table temp1 也不会生成GTID;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值