MySQL 8.0 的 lower_case_table_names 值在初始化时即固化进数据字典,不可更改;修改配置文件或执行 SET GLOBAL 无效,启动时若服务器配置与数据字典值不一致(如日志报 MY-011087 错误),必须清空 datadir 并用 --lower-case-table-names=0(或目标值)重新初始化。

直接改配置文件重启 MySQL 8.0,lower_case_table_names 不会生效——这不是你配错了,而是 MySQL 已经拒绝承认这个改动。
为什么 SET GLOBAL 或 my.cnf 修改后 lower_case_table_names 还是 0?
MySQL 8.0 的数据字典在初始化时就锁死了 lower_case_table_names 的值,之后任何修改都会被忽略。你看到的 SELECT @@lower_case_table_names 返回 0,很可能只是服务启动失败后 fallback 到默认值,不是真实生效状态。
-
SET GLOBAL lower_case_table_names = 1必报ERROR 1238,该变量只读 - 编辑
/etc/my.cnf后重启失败?查日志,大概率是[ERROR] [MY-011087] Different lower_case_table_names settings for server ('1') and data dictionary ('0') -
mysqld --verbose --help | grep lower_case显示的才是启动时实际采用的值,不是配置文件里写的那个
Docker 环境下首次启动必须带 --lower-case-table-names=1
这是唯一能绕过“初始化即锁定”限制的方式:参数必须在 mysqld 第一次写入数据字典前就传进去。
- 错误做法:先
docker run启动容器生成数据目录,再进容器改my.cnf,再重启 → 必然报错 - 正确命令示例:
docker run -d --name mysql8 -e MYSQL_ROOT_PASSWORD=123 -v /data:/var/lib/mysql -p 3306:3306 mysql:8.0 --lower-case-table-names=1 - 如果用了自定义配置文件(
conf.d/),确保它没覆盖或冲突;Docker 启动参数优先级高于配置文件
已有数据目录时,lower_case_table_names=1 不是“开启”,而是“重建”
你不能让旧表自动变小写。MySQL 8.0 不提供在线转换工具,所谓“设为 1 就兼容”,前提是所有表名在磁盘上已经是小写。
- 停服务后检查
/var/lib/mysql/your_db/目录下的.ibd文件名:如果有UserOrder.ibd、XXL_JOB_QRTZ.ibd这类大写表,说明数据字典记录的是模式 0 - 安全路径只有两条:
– 全量导出mysqldump --all-databases→ 清空/var/lib/mysql→ 用--lower-case-table-names=1重初始化 → 导入
– 或逐表RENAME TABLE `UserOrder` TO `userorder`,但必须同步改所有 SQL 引用、视图、存储过程、外键约束中的大小写 - 云数据库(如阿里云 RDS)通常已固定为 1,你只能改应用层 SQL,不能指望服务端适配你的大写表名
真正容易被忽略的点是:错误日志里 Different lower_case_table_names settings 那一行之前,往往还有一行 Failed to open binlog.index 或 Cannot open datadir——那才是 MySQL 拒绝启动的真实原因,不是权限问题,也不是磁盘满,而是大小写策略和已有文件结构对不上。


















