MySQL 5.7 升级到 8.0 时,索引统计信息持久化配置(innodb_stats_persistent)默认均为开启状态,通常无需手动迁移配置参数,但逻辑迁移时必须排除 mysql 系统库中的统计信息表,避免权限报错。
先说结论:配置参数本身兼容,但统计信息数据表结构变更,禁止直接导入旧版系统统计信息。
- 适合:使用 mysqldump 逻辑迁移或原地升级的场景
- 先准备:备份前排除 mysql.innodb_index_stats 等系统表
- 验收:升级后检查变量状态及执行计划稳定性
命令速用版
检查当前统计信息持久化配置状态:
SHOW VARIABLES LIKE 'innodb_stats_persistent';导出业务数据时排除 mysql 系统库(避免统计信息表冲突):
mysqldump -uroot -p `--single-transaction` `--databases` 你的库名 1 你的库名 2 > business_data.sql若已报错 ERROR 3554,编辑 SQL 文件删除涉及 mysql.innodb_index_stats 的语句:
DROP TABLE IF EXISTS `innodb_index_stats`;为什么会这样
MySQL 8.0 对系统表的访问权限控制比 5.7 更严格,直接导入旧版统计信息表会被拒绝。
MySQL 5.7 和 8.0 默认都开启 innodb_stats_persistent,统计信息存储在磁盘上的 mysql.innodb_table_stats 和 mysql.innodb_index_stats 表中。但在 8.0 中,这些表被视为内部系统表,普通用户或导入操作无权直接写入。若在 5.7 导出的 SQL 文件中包含这些表的创建或插入语句,在 8.0 恢复时会触发 ERROR 3554 (HY000): Access to system table 'mysql.innodb_index_stats' is rejected。
分步处理
1. 升级前检查配置
在 5.7 实例确认 innodb_stats_persistent 值为 ON,8.0 默认保持一致,无需修改配置文件。
2. 数据导出策略
使用 mysqldump 时仅导出业务数据库,不要导出 mysql 系统库。若已全库备份,需手动清理 SQL 文件中关于 mysql.innodb_index_stats 和 mysql.innodb_table_stats 的语句。
3. 执行升级或导入
原地升级时,MySQL 启动过程会自动升级数据字典;逻辑迁移时,导入清理后的业务数据 SQL 文件。
4. 重新生成统计信息
升级完成后,对核心表执行 ANALYZE TABLE,让 8.0 重新收集并持久化统计信息,确保执行计划准确。
怎么验证是否生效
1. 确认配置参数
执行 SHOW VARIABLES LIKE 'innodb_stats_persistent'; 确保值为 ON。
2. 检查系统表访问
尝试 SELECT * FROM mysql.innodb_index_stats; 确认当前用户是否有权限读取(通常只读或受限)。
3. 验证执行计划
对复杂查询执行 EXPLAIN,观察 rows 估算值是否合理,若无明显偏差则统计信息工作正常。
常见坑
1. 全库备份直接导入:包含 mysql 库的备份文件直接导入 8.0 必报系统表权限错误。
2. 忽略统计信息重建:升级后未执行 ANALYZE TABLE,可能导致优化器选择错误索引,性能波动。
3. 兼容性问题:5.7 的某些统计信息采样方式与 8.0 不同,强制导入旧数据可能导致执行计划异常。
常见问题
升级后 innodb_stats_persistent 会自动关闭吗?
不会,MySQL 8.0 默认保持开启,与 5.7 行为一致。
遇到 ERROR 3554 怎么快速解决?
编辑备份的 SQL 文件,删除所有涉及 mysql.innodb_index_stats 的 CREATE 和 INSERT 语句。
需要手动迁移统计信息数据吗?
不需要,8.0 会在启动或 ANALYZE TABLE 时自动重新生成统计信息。
参考来源
- MySQL5.7 升级到 MySQL8.0 并进行数据迁移 -CSDN 博客
- MySQL 从 5.7 升级到 8.0 步骤及其问题
- MySQL5.7 到 8.0 无缝迁移:关键步骤与避坑指南-CSDN 博客