lower_case_table_names=1必须在mysql首次初始化时通过命令行参数--lower-case-table-names=1显式指定,不可写入my.cnf或环境变量;mysql 8.4已弃用lower_case_table_names配置项,仅支持带连字符的命令行参数,且初始化后永久不可修改。

MYSQL_ROOT_PASSWORD 是唯一必须设置的环境变量,其他如 MYSQL_DATABASE、MYSQL_USER 等只在空数据目录初始化时生效,重启或重挂载后全部失效。
为什么连不上、库不存在、用户没创建成功?
绝大多数连接失败或初始化失败,是因为你重复启动了容器,但 /var/lib/mysql 目录已存在——此时所有 MYSQL_* 环境变量都被 MySQL 容器直接忽略。
- 检查数据目录是否为空:
ls -A ./data;非空则说明已初始化过,再加MYSQL_DATABASE也没用 - 删掉旧容器和数据目录再试(开发环境):
docker rm -f mysql84 && rm -rf ./data - 生产环境想保留数据?那就别指望环境变量建库建用户,得进容器手动执行
CREATE DATABASE和CREATE USER
lower_case_table_names=1 必须在第一次启动时就定死
MySQL 8.4 不允许运行时修改 lower_case_table_names,且该参数不能写在 my.cnf 或环境变量里——它必须作为命令行参数传入,且只能在首次初始化时生效。
- 错误写法:
environment: LOWER_CASE_TABLE_NAMES=1或放在my.cnf里 → 完全无效,容器卡住,日志反复报InnoDB: Operating system error number 22 - 正确写法:在
docker-compose.yml的command中显式声明:["--lower-case-table-names=1", "--character-set-server=utf8mb4"] - 注意拼写:
--lower-case-table-names(带连字符),不是lower_case_table_names,后者在 8.4 已被弃用
时区和字符集不能只靠 TZ 环境变量
TZ=Asia/Shanghai 只改容器系统时间,MySQL 服务本身仍默认用 UTC,且不自动读取系统时区。
-
TZ配合--default-time-zone='+08:00'才真正生效(后者必须写进command或my.cnf) -
character-set-server=utf8mb4和collation-server=utf8mb4_0900_ai_ci必须显式指定,否则默认仍是utf8mb3,导致 emoji 存储异常 - 如果挂载了自定义
my.cnf,确保它放在/etc/mysql/conf.d/下(不是/etc/mysql/my.cnf),否则会被忽略
持久化目录权限和 SELinux(CentOS/RHEL 常见坑)
Linux 上挂载 ./data:/var/lib/mysql 后容器起不来?大概率是权限或 SELinux 拦截。
- MySQL 容器内以
mysql用户(UID 999)运行,宿主机目录需允许该 UID 写入:chown -R 999:999 ./data - CentOS 7/8/9 默认启用 SELinux,挂载目录需加
:z标签:-v ./data:/var/lib/mysql:z - 若用
--privileged=true,只是绕过限制,不解决根本问题,生产环境应避免
lower_case_table_names 和 character-set-server 这两个参数一旦错过初始化窗口,就再也无法通过常规方式修改——不是配置错了能 reload,而是数据库结构层已固化。这点比 MySQL 8.0 更严格,务必在第一次 docker-compose up 前确认 command 和目录状态。











