前言

根据元数据锁,我们知道其它事务的dml会阻塞ddl的执行。如果ddl在事务中执行会怎么样呢?

mysql> select * from users;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |    1 |
|  2 | lisi     |    2 |
|  3 | wangwu   |    3 |
|  5 | haha     |    5 |
|  8 | oo       |    8 |
|  9 | wowo     |    9 |
+----+----------+------+

分析

1、开启事务,先执行插入操作,再增加字段,最后回滚事务
开启事务

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

执行插入

mysql> insert into users(id, name, age) values(10, 'hehe', 10);
Query OK, 1 row affected (0.02 sec)

增加字段

mysql> alter table users add column address varchar(255);
Query OK, 0 rows affected (0.12 sec)
Records: 0  Duplicates: 0  Warnings: 0

回滚事务

mysql> rollback;
Query OK, 0 rows affected (0.00 sec)

此时查看数据,事务回滚,但是字段和数据都操作成功了

mysql> select * from users;
+----+----------+------+---------+
| id | name     | age  | address |
+----+----------+------+---------+
|  1 | zhangsan |    1 | NULL    |
|  2 | lisi     |    2 | NULL    |
|  3 | wangwu   |    3 | NULL    |
|  5 | haha     |    5 | NULL    |
|  8 | oo       |    8 | NULL    |
|  9 | wowo     |    9 | NULL    |
| 10 | hehe     |   10 | NULL    |
+----+----------+------+---------+
7 rows in set (0.00 sec)

看下binlog,在alter执行前,如果有待提交的事务,则会进行提交。
image-1671765258813

查看binlog文件命令:show master logs;
查看binlog文件目录:show variables like ‘log_bin%’;
查看binlog命令:mysqlbinlog -v $binlog


2、开启事务,删除字段,再执行插入操作,最后回滚事务
开启事务

删除字段

alter table users drop column address;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

插入数据

insert into users(id, name, age) values(11, 'wuwu', 11);
Query OK, 1 row affected (0.08 sec)

回滚事务

查看数据,字段删除成功,数据插入成功,回滚失效:

mysql> select * from users;
+----+----------+------+
| id | name     | age  |
+----+----------+------+
|  1 | zhangsan |    1 |
|  2 | lisi     |    2 |
|  3 | wangwu   |    3 |
|  5 | haha     |    5 |
|  8 | oo       |    8 |
|  9 | wowo     |    9 |
| 10 | hehe     |   10 |
| 11 | wuwu     |   11 |
+----+----------+------+
8 rows in set (0.01 sec)

查看binlog,alter之前,如果只有begin,则自动失效;后面的插入操作重新自动开启事务并提交:
image-1671765919363


总结

1、在alter执行前,如果有待提交的事务,则会进行提交;
2、在alter执行之前,如果只有begin,则自动失效;后面的插入操作重新自动开启事务并提交。