MySQL 5.7升级至8.0遇FTS索引遗留问题求助
解决MySQL 5.7升8.0(AWS RDS)中FULLTEXT索引悬空临时表问题
问题根源
由于MySQL 5.7的Bug#72132,创建FULLTEXT索引时,其辅助临时表被错误存储在系统表空间而非独立表空间。升级到8.0后,这些遗留的临时表记录残留在INFORMATION_SCHEMA.INNODB_SYS_TABLES中,但物理文件已不存在,导致DDL操作触发"找不到临时表"的错误,甚至引发数据库不可用。
预升级彻底清理方案(针对未升级的实例)
针对多租户环境下每个{UUID}库中的customers/lineitems表,批量执行以下操作,替代原Laravel作业流程:
- 步骤1:删除所有FULLTEXT索引
-- 查询目标表的FULLTEXT索引名 SELECT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = '租户库UUID' AND TABLE_NAME = '表名' AND INDEX_TYPE = 'FULLTEXT'; -- 删除索引 ALTER TABLE 租户库UUID.表名 DROP INDEX 索引名; - 步骤2:强制重建表到独立表空间
不要使用OPTIMIZE TABLE(会生成新的临时表加重问题),改用指定表空间的ALTER语句:ALTER TABLE 租户库UUID.表名 ENGINE=InnoDB, TABLESPACE=innodb_file_per_table; - 步骤3:验证清理结果
检查是否还有关联到租户库的悬空临时表记录:SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql-ib%' AND NAME LIKE '租户库UUID/%'; - 批量处理注意事项:Laravel作业中按租户库分批处理,每批数量不宜过多,避免长时间锁表;添加失败重试和日志记录,单独标记处理失败的库表。
已出现悬空临时表的应急清理方案(当前状态)
由于AWS RDS无法直接操作底层文件,使用MySQL内置机制清理:
- 低峰期暂停应用,避免新的DDL/DML生成临时表
- 执行只读锁表(仅在业务允许的短时间内执行):
FLUSH TABLES WITH READ LOCK; - 强制清理无效系统表记录:
注:RECOVERY=1为只读模式,仅清理无效表记录,不会修改业务数据ALTER INSTANCE FORCE RECOVERY = 1; - 验证清理结果:
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#sql-ib32025827-3477973988%'; - 解锁表并恢复应用:
UNLOCK TABLES;
如果上述方法无效,可采用RDS托管方案:
- 创建当前实例的只读副本,待同步完成后将副本提升为新实例,副本同步过程中会自动重建表空间并清理悬空记录
- 用当前实例的快照恢复新实例,恢复过程中InnoDB会自动校验并清理系统表空间中的无效记录
升级后验证
完成升级后,执行以下操作确保问题彻底解决:
- 对所有
customers/lineitems表执行表检查:CHECK TABLE 租户库UUID.customers; CHECK TABLE 租户库UUID.lineitems; - 确认FTS辅助表都在独立表空间:
正常记录格式应为SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%fts%';租户库UUID/表名_fts_xxx,而非临时表格式 - 测试DDL操作(如添加字段),确认无报错且数据库正常运行
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

