docker logs为空且状态为exited (1),说明mysql进程未启动成功,应优先检查挂载的conf.d下.cnf文件语法错误及data目录权限问题,并用docker run -it --rm mysql:8.0 --verbose --log-error-verbosity=3手动验证报错。

docker logs 为空但容器状态是 Exited (1) 怎么办
这说明 MySQL 进程根本没跑起来,不是运行中崩溃,而是启动校验失败后立刻退出。docker logs 没内容,是因为进程太快退出,日志根本没刷到磁盘。
优先检查这两项:
- 挂载的
/etc/mysql/conf.d/下自定义.cnf文件是否有语法错误——MySQL 启动时会校验配置,错一条就直接退出,不写日志 - 宿主机挂载的
data目录权限是否正确:比如目录是root:root写入的,但容器内 MySQL 默认以mysql用户运行,无权读写,也会静默失败
验证方法:用 docker run -it --rm mysql:8.0 --verbose --log-error-verbosity=3 手动执行 mysqld 命令,绕过容器 init 脚本,直接看 stderr 报错。
为什么挂载了 cnf 却没生效
MySQL 容器加载配置有固定顺序:/etc/my.cnf → /etc/mysql/my.cnf → /etc/mysql/conf.d/*.cnf → /etc/mysql/mysql.conf.d/*.cnf,且只认 .cnf 后缀。
常见失效原因:
- 挂载路径不对:比如挂载到了
/etc/mysql/my.cnf,但文件名是my.conf(少个f)或custom.cfg(不是.cnf) - 挂载目标不是
/etc/mysql/conf.d/,而是/etc/mysql/,导致文件被覆盖或忽略 - 容器内执行
docker exec -it <container_id> mysql --verbose --help | grep "Default options"</container_id>,确认实际加载路径
保险做法:在自定义配置里显式加 log_error = /var/log/mysql/error.log,再挂载 /var/log/mysql 出来,比依赖 docker logs 更可靠。
退出码是 137 或日志里出现 “Killed process mysqld”
这是 OOM Killer 干的,不是 MySQL 自己崩了。系统内存不够,内核强制 kill 掉 mysqld 进程。
查证方式:
-
dmesg -T | grep -i "killed process.*mysqld"—— 有输出就是 OOM -
sudo journalctl -u mysql --since "1 hour ago" | grep -E "(exited|killed|OOM)"—— 看 systemd 是否记录了code 137 - 对比
innodb_buffer_pool_size+sort_buffer_size × max_connections等内存参数总和,是否明显超过宿主机可用内存
Docker 启动时加 --memory=2g 只是限制 cgroup 上限,不解决配置超限问题;真正要调的是 my.cnf 里的 innodb_buffer_pool_size,建议设为宿主机内存的 50%–70%。
容器反复 restart 但没报错,systemd 日志却显示 Started→Stopped→Started
这不是 MySQL 的问题,是 systemd 在兜底重启。它看到服务退出,就按 Restart=on-failure 策略拉起,掩盖了原始问题。
先停掉干扰:
-
sudo systemctl stop mysql(如果宿主机也装了 MySQL 服务) - 检查
/usr/lib/systemd/system/mysql.service或/etc/systemd/system/multi-user.target.wants/mysql.service,注释掉Restart=行 - 再试一次
docker run,让容器真实暴露退出原因
特别注意凌晨 2–4 点集中重启——很可能是 logrotate、备份脚本或监控任务触发资源争抢,而非 MySQL 自身异常。











