场景
DDL(Data Definition Language)数据定义语言。
DML(Data Manipulation Language)数据操纵语言。
假设有用户表t_user
,其存储姓名的字段name
最初设置为varchar(4)
,在后来的存入的数据发现该字段长度够能满足需求,需要更改该字段的长度。
那么可以在线上直接修改吗?
修改失败的场景
在线上运行的时候,如果有一个正在执行的查询操作,同时一个人执行修改字段长度的命令,则该修改操作会被阻塞。
- session1 - 执行查询操作
为实验方便,使用sleep(20)增加查询操作的耗时。
执行耗时查询select sleep(30) from t_user where id = 1;
-
session2 执行修改name字段设置的操作
DDL操作阻塞
此时发现操作被阻塞。
查询mysql进程状态。
等待元数据锁show processlist;
发现修改操作在等待表元数据锁。
- 原因
在执行DML操作的时候,会为表加上表元数据锁(table metadata lock),目的是防止在查询的过程中,表结构发生改变,导致查询结果错误。
解决方式
- 尽量避免在线上直接修改表结构。
- 使用pt-online-schema-change工具
pt-online-schema-change使用参考
https://blog.csdn.net/lovelichao12/article/details/73549939
MySQL DDL/DML并发参考表
MySQL提供了DDL Online机制,使得部分DDL操作可以和DML操作并发,其对照表如下。
https://dev.mysql.com/doc/refman/5.7/en/innodb-create-index-overview.html
网友评论