暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DDL 失败?中间表残留文件怎么清理最合适?

87

作者:孙绪宗,新浪微博 DBA 团队工程师,主要负责 MySQL、PostgreSQL 等关系型数据库运维。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 800 字,预计阅读需要 2 分钟。


一、故障现象

版本:社区版 5.7.21

数据目录存在中间表文件,进程不存在任何 DDL 操作,同时导致相关表无法执行 Online DDL。

[root commercial_push_1]# ls
'#sql-13fd_3.frm'
'#sql-13fd_3.ibd'

二、故障分析

猜测是历史上执行过 DDL 失败了,导致中间表文件没有删除,导致表无法执行 Online DDL。

三、问题处理

参考 官方文档[1] 的正确的处理方式:

查看系统表空间

MySQL> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql%';
+----------+-------------------------------+------+--------+-------+-------------+------------+---------------+------------+
| TABLE_ID | NAME                          | FLAG | N_COLS | SPACE | FILE_FORMAT | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE |
+----------+-------------------------------+------+--------+-------+-------------+------------+---------------+------------+
|      186 | commercial_push_1/#sql-13fd_3 |   33 |      8 |   172 | Barracuda   | Dynamic    |             0 | Single     |
+----------+-------------------------------+------+--------+-------+-------------+------------+---------------+------------+
1 row in set (0.0030 sec)

加上识别符直接 DROP
 就可以了。

localhost 15:11:07 [commercial_push_1]> DROP TABLE `#mysql50##sql-13fd_3`;

其他情况处理方式:

1. 如果是误删了 frm
 文件,需要通过 sys_columns 重新生成一份相同表结构的表,CREATE
 后再删除即可。
2. 如果 frm
 和 ibd
 都删了,那么重启会自动生成 ibd
 的,通过 undrop for innodb 等工具再恢复表结构再删除即可。

此时重启会有报错,不影响业务正常使用。当然也可以检查一下线上的 error log
 是否存在该历史问题。

2025-05-26T06:01:45.627666Z 138 [ERROR] InnoDB: Failed to find tablespace for table `commercial_push_1`.`#sql-13fd_3` in the cache. Attempting to load the tablespace with space id 172
2025-05-26T06:01:45.628057Z 138 [ERROR] InnoDB: In file './commercial_push_1/#sql-13fd_3.ibd', tablespace id and flags are 17396 and 33, but in the InnoDB data dictionary they are 172 and 33. Have you moved InnoDB .ibd files around without using the commands DISCARD TABLESPACE and IMPORT TABLESPACE? Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.
2025-05-26T06:01:45.628064Z 138 [ERROR] InnoDB: Operating system error number 22 in a file operation.
2025-05-26T06:01:45.628074Z 138 [ERROR] InnoDB: Error number 22 means 'Invalid argument'
2025-05-26T06:01:45.628077Z 138 [Note] InnoDB: Some operating system error numbers are described at http://dev.mysql.com/doc/refman/5.7/en/operating-system-error-codes.html
2025-05-26T06:01:45.628081Z 138 [ERROR] InnoDB: Could not find a valid tablespace file for `commercial_push_1/#sql-13fd_3`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.

3. 如果 frm
 和 ibd
 文件不一致,可以参考文档中,先 mv
 成相同名,然后再 drop

例如某位群友的案例:

[root xxx]# ls
-rw-r----- 1 mysql mysql  15196 Mar 20 15:13 '#sql-1076b_15b58.frm'
-rw-r----- 1 mysql mysql 131072 Mar 20 15:15 '#sql-ib1814-561096274.ibd'
[root xxx]# mv '#sql-1076b_15b58.frm' '#sql-ib1814-561096274.frm'

MySQL [xxx]> DROP TABLE `#mysql50##sql-1076b_15b58`;
Query OK, 0 rows affected (0.0362 sec)

总结

  1. 这里其实笔者最一开始就是直接 rm
     了文件,然后重启发现 error log
     报错,才意识到这个问题。当然是在从库搞得,本质上 rename
     倒腾库也是可以解决的。
  2. error log
     中的报错链接确实会经常忽略掉,但是其实官方文档中很多问题的解决方法,都是可以参考的。
  3. 一定要在从库复现模拟,切勿直接在主库执行。笔者这里只有主库和其中一个从库有问题,直接操作可能会导致主从复制报错。
参考资料
[1] 

innodb-troubleshooting-datadict: http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html


本文关键字:#MySQL #Online DDL #





故障分析 | MySQL 8.0 中多字段虚拟列引发的宕机
故障分析 | 如何解决由触发器导致 MySQL 内存溢出?
故障分析 | 查询 ps.data_locks 导致 MySQL hang 住
故障分析 | TCP 缓存超负荷导致的 MySQL 连接中断
生产运维脚本引发的 MDL 锁故障排查之旅


✨ Github:https://github.com/actiontech/sqle

📚 文档:https://actiontech.github.io/sqle-docs/

💻 官网:https://opensource.actionsky.com/sqle/

👥 微信群:请添加小助手加入 ActionOpenSource

🔗 商业支持:https://www.actionsky.com/sqle


文章转载自爱可生开源社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论