MySql Online DDL操作记录详解

 更新时间:2022年12月20日 17:24:31   作者:Cindy  
这篇文章主要为大家介绍了MySql Online DDL操作记录详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、环境

为支持用户账号删除功能,需要在 user 表上加一个字段 deleted。

数据库:Mysql5.6

被 操作表 user:数量级为100w,外键200多个

操作:alter table user add deleted boolean NOT NULL default false comment '用户注销标识' , algorithm=inplace, lock=none;

二、执行过程分析

在Mysql5.6之后,mysql支持 Online DDL 操作。

Online DDL Support for Column Operations

OperationIn PlaceRebuilds TablePermits Concurrent DMLOnly Modifies Metadata
Adding a columnYesYesYes*No
Dropping a columnYesYesYesNo
Renaming a columnYesNoYes*Yes
Reordering columnsYesYesYesNo
Setting a column default valueYesNoYesYes
Changing the column data typeNoYesNoNo
Dropping the column default valueYesNoYesYes
Changing the auto-increment valueYesNoYesNo*
Making a column NULLYesYes*YesNo
Making a column NOT NULLYes*Yes*YesNo
Modifying the definition of an ENUM or SET columnYesNoYesYes

如图所示,所执行的添加列操作整个过程为:

  • 初始化:为创建临时表的表结构,获取MDL的排他锁
  • 执行:根据参数 algorithm=inplace, lock=none ,MDL锁降级为共享锁进行数据拷贝
  • 提交:由于涉及到增量备份和临时表的重命名,MDL锁需要升级为排他锁

分析后认为,整个过程只有在初始化和提交的极短过程内需要用到MDL排他锁(影响线上),故而就直接在线上进行操作尝试。

三、遇到的问题

在初始化和提交阶段需要用到MDL的排他锁,而如果DDL操作一直没获取MDL锁(默认获取MDL锁超时时间为一年),那么就会造成 Waiting for table metadata lock 状态,也会阻塞后面所有对 user 表的操作(包括select)。后面会看到连接占满,服务502:

在遇到这样的问题后,为不影响线上,于是后面进行了工具的尝试。

四、工具尝试

工具涉及到 pt-online-schema-change、gh-ost和阿里云无锁DDL。三个工具大同小异,均为使用临时表,将原表数据拷贝到临时表,最后将临时表重命名替换掉原表。区别是在增量同步方面,一个用的触发器、一个用的binlog日志。

但是在处理外键方面,pt-online-schema-change用的删除、重建外键,gh-ost和阿里云无锁DDL则是不支持主表外键的变更。eg:阿里云无锁DDL的失败尝试

故使用工具进行 DDL 操作也不适合。

五、Online DDL 尝试

在本地测试30w数据新增列只需440ms后,尝试选择了 online ddl 的操作:

设置 session 级别获取 MDL 锁等待时间时间,避免长时间阻塞其他线程

$ set lock_wait_timeout=10;
# 在10s内获取不到MDL锁,直接退出 alter 操作
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

kill 掉对应的线程以及事务

$ select group_concat(stat separator ' ') from (select concat('kill query ',id,';') as stat from information_schema.processlist  where command != 'Sleep' and Time > 5 order by Time desc) as stats;
+-------------------------------------+
| group_concat(stat separator ' ')    |
+-------------------------------------+
| kill query 42510; kill query 42514; |
+-------------------------------------+
1 row in set (0.00 sec)
$ select group_concat(stat separator ' ') from (select concat('kill ',trx_mysql_thread_id,';')   as stat from information_schema.innodb_trx order by trx_started desc) as stats;
+-------------------------------------------------------------------------+
| group_concat(stat separator ' ')                                        |
+-------------------------------------------------------------------------+
| kill 42436; kill 42435; kill 42521; kill 42511; kill 42510; kill 42483; |
+-------------------------------------------------------------------------+
1 row in set (0.01 sec)

执行 DDL 操作:

$ alter table user add deleted boolean NOT NULL default false comment '用户注销标识' , algorithm=inplace, lock=none;

结果:

以上是在停服后操作的结果,其中 2 操作在停服后,没有需要 kill 的 ID。

参考文献

InnoDB and Online DDL

以上就是MySql Online DDL操作记录详解的详细内容,更多关于MySql Online DDL操作的资料请关注脚本之家其它相关文章!

相关文章

  • 使用MySQL Slow Log来解决MySQL CPU占用高的问题

    使用MySQL Slow Log来解决MySQL CPU占用高的问题

    在Linux VPS系统上有时候会发现MySQL占用CPU高,导致系统的负载比较高。这种情况很可能是某个SQL语句执行的时间太长导致的。优化一下这个SQL语句或者优化一下这个SQL引用的某个表的索引一般能解决问题
    2013-03-03
  • 关于Mysql搭建主从复制功能的步骤实现

    关于Mysql搭建主从复制功能的步骤实现

    这篇文章主要介绍了关于Mysql搭建主从复制功能的步骤实现,在实际的生产中,为了解决Mysql的单点故障已经提高MySQL的整体服务性能,一般都会采用主从复制,需要的朋友可以参考下
    2023-05-05
  • IDEA 链接Mysql数据库并执行查询操作的完整代码

    IDEA 链接Mysql数据库并执行查询操作的完整代码

    这篇文章主要介绍了IDEA 链接Mysql数据库并执行查询操作的完整代码,代码不难,详细大家看完本文肯定有意向不到的收获,感兴趣的朋友跟随小编一起看看吧
    2021-05-05
  • 数据库SQL调优的几种方式汇总

    数据库SQL调优的几种方式汇总

    在项目中,SQL的调优对项目的性能来讲至关重要,所有掌握常见的SQL调优方式是必不可少的,下面这篇文章主要给大家介绍了关于数据库SQL调优的几种方式,需要的朋友可以参考下
    2022-10-10
  • mysql查询锁表方式

    mysql查询锁表方式

    在MySQL中,查询锁表可以通过多个命令实现,如show engine innodb status、show processlist等,用以检测和解决表锁问题,首先通过show engine innodb status查看锁表情况,接着利用show processlist找出长时间占用的SQL语句
    2024-09-09
  • MySQL存储过程和存储函数的用法解读

    MySQL存储过程和存储函数的用法解读

    这篇文章主要介绍了MySQL存储过程和存储函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-09-09
  • Mysql三种常用的删除数据或者表的方式

    Mysql三种常用的删除数据或者表的方式

    本文主要介绍了Mysql三种常用的删除数据或者表的方式,它们分别是 TRUNCATE、DROP 和 DELETE,下面就详细的介绍一下这三种的使用,感兴趣的可以了解一下
    2024-01-01
  • MySQL在不知道列名情况下的注入详解

    MySQL在不知道列名情况下的注入详解

    这篇文章主要给大家介绍了关于MySQL在不知道列名情况下的注入的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • MYSQL表优化方法小结 讲的挺全面

    MYSQL表优化方法小结 讲的挺全面

    一篇MYSQL表优化的文章,说的很好,使用mysql的朋友可以参考下。
    2010-05-05
  • mysql主从同步原理及应用场景示例详解

    mysql主从同步原理及应用场景示例详解

    这篇文章主要为大家介绍了mysql主从同步原理及应用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论