mysql 8.0 的 lower_case_table_names 值在首次初始化时即固化进数据字典,不可更改;启动失败因服务器配置与数据字典记录值不一致,必须清空 datadir 并用命令行参数 --lower-case-table-names=0 重新初始化。

lower_case_table_names 在 MySQL 8.0 初始化阶段就固化进数据字典
MySQL 8.0 启动失败、卡在 starting 状态,或者日志里反复出现 Different lower_case_table_names settings for server ('2') and data dictionary ('0'),根本原因不是配置写错了,而是数据字典(mysql.ibd)里已经按初始化时的值注册了所有对象名。这个值一旦写入,就不可逆——它不是配置项,而是元数据结构的一部分。
你改 my.cnf 没用,因为服务启动时会校验:磁盘上实际的表名(比如 /var/lib/mysql/test/MyTable.frm)和数据字典里记录的“规范名”是否匹配。不一致?直接拒绝加载。
Linux 默认是 0,但 Windows/macOS 默认不是 0,跨平台迁移必踩坑
不同系统默认值不同,但 MySQL 8.0 不会自动适配——它只认初始化那一刻的设定:
-
lower_case_table_names=0(区分大小写):Linux/Unix 默认,表名原样存储、原样比对 -
lower_case_table_names=1(小写存储+不区分比较):Windows 默认,所有表名强制转小写存盘 -
lower_case_table_names=2(原样存储+小写比较):macOS 默认,折中但容易和 Linux 部署冲突
常见翻车场景:
- 在 macOS 上用 Docker 跑过 MySQL 8.0 容器(默认
2),导出 SQL 迁到 CentOS 服务器想启用区分大小写(0),结果启动报错 - 云数据库 RDS 实例创建时选了“不区分大小写”,后续无法切换成区分模式
命令行参数 --lower-case-table-names=0 才有效,配置文件 my.cnf 无效
初始化命令(mysqld --initialize)读取参数的逻辑很严格:它只认命令行显式传入的 --lower-case-table-names,不读 my.cnf 里的同名配置。这是很多教程漏掉的关键点。
正确操作顺序:
- 清空
datadir(确保无残留ibdata1、mysql.ibd) - 执行:
mysqld --user=mysql --initialize --lower-case-table-names=0 --basedir=/usr --datadir=/var/lib/mysql - 再写
my.cnf里加lower_case_table_names=0做持久化确认 - 启动后立刻验证:
SHOW VARIABLES LIKE 'lower_case_table_names';必须返回0
误设为 1 或 2 后想改回 0,只能重做初始化
没有“热修复”方案。哪怕你只是临时改错了一次配置,只要 mysqld --initialize 已执行,且服务成功启动过一次,就代表数据字典已定型。这时候删配置、改 my.cnf、重启服务,只会让 MySQL 卡住或报错退出。
真正要命的是:你可能在开发环境试过一次错误配置,然后把整个 datadir 打包带到生产环境,结果上线就崩。这种问题不会在 SQL 层报错,而是在服务进程启动那一秒静默失败——日志里只有冷冰冰的 Data Dictionary initialization failed。











