挂载 /etc/mysql/my.cnf 无效,因 MySQL 8.0 官方镜像默认不读该路径;唯一可靠方式是将配置文件(如 custom.cnf)挂载至 /etc/mysql/conf.d/ 目录,且需含 [mysqld] 段及 skip-host-cache 等必要项。

my.cnf 挂载到 /etc/mysql/my.cnf 是无效的 —— MySQL 8.0 官方镜像根本不会读它。
为什么挂载 /etc/mysql/my.cnf 不生效
官方镜像启动时,docker-entrypoint.sh 脚本不传 --defaults-file 参数,而是让 mysqld 按默认顺序加载配置:/etc/mysql/my.cnf → /etc/mysql/conf.d/*.cnf → /etc/mysql/mysql.conf.d/*.cnf。但镜像里 /etc/mysql/my.cnf 是个符号链接或空文件,且入口脚本会跳过它;真正被无条件扫描的只有 conf.d 和 mysql.conf.d 目录。
常见现象包括:unknown variable 'lower_case_table_names=1'、字符集没生效、bind-address 不生效——基本都能归因于配置压根没加载。
-
/etc/mysql/conf.d/是唯一被 entrypoint 显式支持的自定义挂载点 - 挂载
/etc/mysql/my.cnf会绕过初始化逻辑,可能丢失 socket 路径、pid-file 设置等关键项 - 即使你硬塞进
/etc/mysql/my.cnf,只要没加--defaults-file=/etc/mysql/my.cnf启动参数,它就静默忽略
docker run 中挂载 my.cnf 的正确写法
必须把宿主机上的配置文件映射进容器的 /etc/mysql/conf.d/ 目录,且文件名以 .cnf 结尾。
- 宿主机创建配置文件,例如:
/mydata/mysql/conf.d/custom.cnf - 内容必须以
[mysqld]开头,不能缺段标识 - 必须包含
skip-host-cache和skip-name-resolve,否则容器启动卡在 DNS 解析 - 挂载命令用:
-v /mydata/mysql/conf.d:/etc/mysql/conf.d(注意不是/etc/mysql) - 不要起名
my.cnf—— 镜像自带/etc/mysql/my.cnf里有!includedir /etc/mysql/conf.d/,重名可能导致解析冲突
lower_case_table_names=1 这类参数为什么改了也不生效
这个参数只在 mysqld 第一次初始化 datadir 时生效。如果容器已运行过、宿主机挂载的 /var/lib/mysql 目录非空,再改配置重启,MySQL 会直接拒绝启动,并报类似错误:
Cannot set lower_case_table_names = 1 with innodb_file_per_table = 1
这不是配置写错了,是数据目录状态和参数不兼容。
- 唯一安全解法:删掉宿主机上对应的
/mydata/mysql/data目录(确认无重要数据!) - 不能靠
docker restart或重建容器解决 —— 只要/var/lib/mysql卷里有旧数据,就无效 - 该参数影响 InnoDB 数据字典底层存储方式,不可热更新
配置文件内容里容易漏的关键项
除了业务参数(如 character-set-server=utf8mb4),以下几项不写,容器大概率起不来或行为异常:
-
skip-host-cache和skip-name-resolve:防止启动卡 DNS -
default-authentication-plugin=mysql_native_password:避免客户端连接时报Client does not support authentication protocol -
innodb_buffer_pool_size建议设为物理内存的 50%~75%,别写成2G这种绝对值(容器内存限制下可能超限) - 所有路径(如
slow_query_log_file)必须指向容器内可写位置,比如/var/log/mysql/slow.log,且确保目录存在、权限正确
docker logs mysql 有没有报错,以及进容器执行 mysql --verbose --help | grep "Default options" 确认加载路径是否包含 /etc/mysql/conf.d/ —— 这比反复重启更省时间。


















