几乎可以确定是MySQL进程启动失败后立即退出导致日志未刷出,需通过docker inspect查ExitCode和OOMKilled、exec进容器检查/var/lib/mysql内容、禁用健康探针或加--console参数获取实时错误输出。
docker logs 看不到错误但容器反复 restarting
这种情况几乎可以确定是 MySQL 进程启动失败后立即退出,而日志缓冲没来得及刷出就终止了。Docker 默认不会强制 flush stdout/stderr,尤其当 mysqld 因配置或权限问题在初始化阶段崩溃时,docker logs 可能为空或只显示半行启动信息。
真正有效的做法是加 --log-level=debug 并强制输出到前台:
- 用
docker run -it --rm -e MYSQL_ROOT_PASSWORD=test mysql:8.0 --log-error-verbosity=3临时测试,观察终端实时输出 - 若用
docker-compose,在command中显式指定mysqld --console --log-error-verbosity=3,绕过默认 entrypoint 的日志静默逻辑 - 避免依赖
docker logs,改用docker logs --previous(对已退出容器)或docker exec -it container_id cat /var/log/mysql/error.log(如果挂载了日志卷)
挂载路径写错导致 /var/lib/mysql 是空目录
最隐蔽也最常见的原因:你写了 -v ./mysql-data:/var/lib/mysql,但宿主机 ./mysql-data 是个空目录,MySQL 启动时发现 /var/lib/mysql 下没有 ibdata1、mysql 子目录,就拒绝初始化并静默退出——此时容器状态是 Exited (1),但日志里什么也不打。
验证方式非常直接:
- 运行
docker exec -it some-mysql ls -A /var/lib/mysql,如果返回空,说明挂载点存在但没数据 - 运行
docker volume inspect mysql-data(如果是命名卷),看Mountpoint路径下是否有文件;如果是宿主机路径,用ls -l /host/path/to/mysql-data确认目录非空且属主是mysql(UID 999) - 别信
docker volume ls显示“存在”就万事大吉——匿名卷和命名卷混用时,docker run -v /var/lib/mysql mysql:8.0这种写法会创建匿名卷,每次都是新卷,旧数据永远找不回来
内存不足触发 OOM Killer 却不报错
MySQL 启动初期会申请大量内存做 buffer pool 初始化,如果容器设置了 --memory=512m 但实际需要 1G,Linux 内核会直接 kill 掉 mysqld 进程,退出码为 137,而 MySQL 自身来不及写任何日志。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
查证方法:
- 运行
docker inspect some-mysql | grep -A 5 'Status\|OOMKilled',重点看"OOMKilled": true和"ExitCode": 137 - 用
docker stats some-mysql观察内存峰值是否逼近限制值 - 临时去掉内存限制跑一次:
docker run -m 0或干脆不加-m,确认是否稳定;再逐步收紧到1g或2g
健康检查(livenessProbe)误判导致循环重启
在 Kubernetes 或 docker-compose v2.4+ 中,如果配置了 livenessProbe 但路径/端口/超时不合理,MySQL 还没完成初始化就被探活失败,然后被强制 kill 重启——看起来像“无日志重启”,其实日志里早有 Liveness probe failed 记录,只是你没注意。
典型陷阱:
-
initialDelaySeconds设太小(比如 5s),而 MySQL 在慢盘上首次初始化要 30s+ -
timeoutSeconds设成 1,但网络抖动或磁盘延迟导致连接偶尔超时 - 探针用
tcpSocket检 3306 端口,但 MySQL 已监听却还没接受连接(mysqld启动后需几秒才 ready) - 解决办法:先注释掉 livenessProbe,确认容器能稳定跑起来;再逐步调大
initialDelaySeconds(建议 ≥60),并改用exec执行mysqladmin ping -u root -p$MYSQL_ROOT_PASSWORD
真正难排查的点不在 MySQL 本身,而在 Docker 的抽象层:挂载是否生效、资源是否被掐断、探针是否抢跑。别急着改配置,先确认 /var/lib/mysql 里有没有东西、容器退出码是不是 137、docker inspect 里有没有 OOMKilled 字样——这些比翻 MySQL 错误日志快十倍。