mysql 5.7 升级至 8.0 后需重点调整 sql_mode、innodb_buffer_pool_size、max_connections、lower_case_table_names 等配置,避免 strict 模式报错、缓冲池异常、连接数受限及表名找不到等问题,且必须校验变量兼容性与初始化约束。

MySQL 5.7 升 8.0 后 sql_mode 报错怎么办
升级后执行 INSERT 或 UPDATE 突然报 ERROR 1364 (HY000): Field doesn’t have a default value,大概率是 sql_mode 默认值变了。5.7 默认含 STRICT_TRANS_TABLES,但 8.0 新增了 STRICT_ALL_TABLES 和更严的校验逻辑,且默认启用 ONLY_FULL_GROUP_BY。
实操建议:
- 先查旧库:运行
SELECT @@global.sql_mode;,把结果存下来 - 新库别直接覆盖,先用
SET GLOBAL sql_mode = '...';临时设回旧值,验证业务是否跑通 - 确认无误后,在新配置文件
/etc/my.cnf的[mysqld]段加一行:sql_mode = "YOUR_OLD_VALUE" - 注意:8.0 对空字符串、零日期等校验更硬,光调
sql_mode不一定能绕过,得同步检查字段NOT NULL和默认值定义
my.cnf 里 innodb_buffer_pool_size 升级后要不要改
要改,而且必须重算。8.0 的 InnoDB 内存管理机制有变化,尤其在大内存机器上,旧值可能导致缓冲池初始化失败或频繁刷脏页。
实操建议:
- 别直接复制旧值——比如旧库设了
innodb_buffer_pool_size = 12G,而新服务器内存翻倍,不调可能浪费资源;若内存减半还照搬,会触发大量磁盘 IO - 8.0 推荐值仍是物理内存的 50%–75%,但需避开
buffer_pool_chunk_size * chunk 数对齐问题(默认chunk_size=128M),否则启动时日志会警告Buffer pool size not aligned - 启动前用
mysql --verbose --help | grep "buffer-pool-size"看实际生效值,避免配置被注释或拼写错误(如写成innodb_buffer_pool_size_)
迁移后 max_connections 突然被限制在 214
不是配错了,是 8.0 默认启用了 super_read_only + read_only 组合锁死部分系统变量,max_connections 在只读实例上会被强制压到极低值(214 是典型表现)。
实操建议:
- 先查状态:
SELECT @@global.read_only, @@global.super_read_only;,如果都是ON,就得先关掉再调参 - 执行:
SET GLOBAL super_read_only = OFF; SET GLOBAL read_only = OFF;(注意:仅限非从库或已确认主从关系正常时操作) - 再设
max_connections,并写入配置文件——8.0 不再允许运行时动态调高超过max_connections的当前连接数,所以务必先断开闲置连接再改 - 改完重启前,用
mysqld --validate-config检查配置语法,避免因格式错误导致服务起不来
lower_case_table_names 设错导致表找不到
这是最隐蔽的坑:5.7 允许设为 1(小写存储),但 8.0 要求初始化时就定死,运行中不可改,且一旦数据目录已有混合大小写的表,强行设 1 会导致 SHOW TABLES 空,SELECT 报 Table doesn't exist。
实操建议:
- 迁移前必须确认旧库的
lower_case_table_names值(SELECT @@global.lower_case_table_names;),不能只看配置文件 - 8.0 初始化实例时,必须用
--lower-case-table-names=1参数启动首次 mysqld,否则后续无法补救 - 如果旧库是
0(区分大小写)且表名混用大小写,升级后别碰这个参数——宁可应用层统一小写访问,也别试图“修正” - 备份时用
mysqldump --skip-triggers --skip-routines配合--set-gtid-purged=OFF,避免导出语句里带大小写敏感的反引号陷阱
变量迁移不是复制粘贴配置文件的事,每个值背后都绑着存储引擎行为、SQL 解析路径和权限校验链。最容易被跳过的,是那些没报错、但悄悄降级功能的配置项,比如 explicit_defaults_for_timestamp 或 default_authentication_plugin ——它们不会让你连不上,但会让某些客户端认证失败或时间字段语义突变。











