当前位置: 首页 >数据库 > 关于MySQL 5.6 DDL阻塞DML的问题!

关于MySQL 5.6 DDL阻塞DML的问题!

 事情是这样的:

数据库版本: Percona 5.6.30

现象如图:

关于MySQL 5.6 DDL阻塞DML的问题! _ JavaClub全栈架构师技术笔记

 

线上加字段、加索引的操作理论上不会影响DML 以及select语句,这是为什么?

加字段、加索引时show processlist 语句是在 copy to tmp table;该表的DML在waiting for table metadata lock
首先怀疑阻塞是因为DDL 没有拿到metadata lock 在等这个锁,导致后续的DML更拿不到metadata lock 进而被阻塞。但分析之后不会呀,如果DDL在等元数据锁,状态应该也是waiting for table metadata lock而不应该是后面的状态 copy to tmp table。所以疑点回到了copy to tmp table,关于这个状态手册中的解释为:
copy to tmp table
The thread is processing an ALTER TABLE statement. This state occurs after the table with the new structure has been created but before rows are copied into it.

正常加索引、加字段(由于online DDL)应该是:
altering table
The server is in the process of executing an in-place ALTER TABLE.

copy to tmp table 这个状态,手册上解释得有点晦涩难懂但很准确。典型的copy数据重建表流程:创建新的表结构tmp_table、导入数据、rename为原表。 正在copy 数据...
但为什么会这样呢? 还是不合情理啊,alter index 都要重建表 以后还怎么玩啊?

线下模拟加索引情况如下:
| 77662 | root | localhost | db_wlt_points_acc | Query | 4 | copy to tmp table | alter table db_wlt_points_acc.wlt_point_txn_serial add index(PARTNER_NO)
碍于加索引的时间太久,Ctrl-C掉暂停了,有一个note值得关注:
root@localhost : db_wlt_points_acc 03:32:44> alter table db_wlt_points_acc.wlt_point_txn_serial add index(PARTNER_NO);

^CCtrl-C -- sending "KILL QUERY 77662" to server ...

Ctrl-C -- query aborted.

ERROR 1317 (70100): Query execution was interrupted

Note (Code 1880): TIME/TIMESTAMP/DATETIME columns of old format have been upgraded to the new format.

Error (Code 1317): Query execution was interrupted

有个提示比较诡异:时间、日期等字段格式需要升级!!!

这里交代一下: 我们刚做了数据库版本升级!为了统一数据库版本便于维护,我们将之前使用的MariaDB 10.0.12数据库迁到了Percona server 5.6.30.

数据库升级是怎么做的呢?

MariaDB10.0迁到Percona 5.6,好像一般公司也不会这么玩吧!缺乏类似案例我们只能自己琢磨了。根据MySQL逻辑复制的理论,数据库是可以逻辑搭备库的方式实现切换、迁移升级的。我们也刚刚把一个MariaDB 5.5.32升级到了Percona 5.6.30.但10.0就不是这么回事了,由于MariaDB 10.0中GTID格式跟Percona 5.6不同,导致binlog格式不一致,Percona 5.6无法逻辑复制同步MariaDB。那迁移怎么做呢? 停业务dump逻辑迁,停机时间太长业务难以接受!采用mysqldump+mysqlblog的方式迁移,但是几个小时binlog的量也会很大,恢复的时间不可预知;只能考虑物理热备的方式了。MariaDB 其实底层是Percona XtraDB 5.6.17,跟我们要用的Percona 5.6.30差的版本号不多,物理热备copy应该有戏。在测试环境做了大量的测试: MariaDB 数据库xtrabackup 恢复到Percona 5.6.30是可以的,表的读写DDL操作都“正常”。 于是准备采用物理热备+增量备份恢复的方式实现迁移升级。跟涂老师沟通后,又有了新的idear: 直接搭建MariaDB备库,免去了全量备份+增量备份+recovery的时间! 最终采用的方式如下: 新环境搭建好MariaDB 的备库,切换时shutdown MariaDB ,以Percona 5.6.30 启动DB完成软件的升级,再导入事先准备好的Percona版本的 mysql库创建脚本完成MySQL数据字典的升级。这种方案线下测得也都Ok,线上迁移也都很顺利。

但业务上线执行DDL时就遇到了问题···

看来是mysql版本升级后时间、日期字段不兼容的原因导致DDL需要重建表。
关于mysql 5.6 版本升级 需要注意的问题见:http://dev.mysql.com/doc/refman/5.6/en/checking-table-incompatibilities.html

有个参数很关键:

avoid_temporal_upgrade

Introduced 5.6.24
Default OFF

This variable controls whether ALTER TABLE implicitly upgrades temporal columns found to be in pre-5.6.4 format (TIME, DATETIME, and TIMESTAMP columns without support for fractional seconds precision). Upgrading such columns requires a table rebuild, which prevents any use of fast alterations that might otherwise apply to the operation to be performed.

This variable is disabled by default. Enabling it causes ALTER TABLE not to rebuild temporal columns and thereby be able to take advantage of possible fast alterations.

为了验证下上面的说法:
set global avoid_temporal_upgrade=on;

Query OK, 0 rows affected, 1 waing (0.00 sec)

再尝试加索引:
alter table db_wlt_points_acc.wlt_point_txn_serial add index(PARTNER_NO);

^CCtrl-C -- sending "KILL QUERY 77662" to server ...

Ctrl-C -- query aborted.

就不会重建表了:
| 77662 | root | localhost | db_wlt_points_acc | Query | 2 | altering table | alter table db_wlt_points_acc.wlt_point_txn_serial add index(PARTNER_NO) |

不会重建表也就没有了阻塞DML的情况

如果要彻底解决DDL阻塞DML的问题就要把整个实例所有的InnoDB表(有时间日期字段的表)都重建一下,实现时间字段格式的升级!

至此一切都明了了,DB升级后是否还有其他的问题尚且未知。。。

 

作者:星爷001
来源链接:https://www.cnblogs.com/xingye001/p/6150183.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/database/118599.html

标签:MySQL升级
分享给朋友:

“关于MySQL 5.6 DDL阻塞DML的问题!” 的相关文章

全面解析Redis 2022年05月13日 10:22:02
MySQL数据库(基础) 2022年05月16日 21:54:19
数据库之事务及事务的 ACID 性质 2022年05月21日 11:37:16
Mysql 查询结果赋值到变量 2022年06月07日 12:35:42
Mysql查询某字段值重复的数据 2022年06月11日 19:39:22
mysql中的json查询 2022年06月16日 22:34:46