mysql容器删了就丢数据是设计使然,因默认未挂载/var/lib/mysql,数据写入容器可写层,删除后overlayfs上层被清空;必须显式用-v挂载命名卷或宿主机目录才能持久化。

MySQL容器删了就丢数据,不是bug,是设计如此;持久化必须显式挂载 /var/lib/mysql,备份必须由宿主机发起,容器内不提供自动备份机制。
为什么直接运行 docker run mysql:8.0 会丢数据?
官方镜像虽在 Dockerfile 中声明了 VOLUME /var/lib/mysql,但这只是“提示”,不等于自动绑定宿主机路径。没加 -v 参数时,数据全写在容器可写层(OverlayFS 上层),容器 rm 后物理删除,ibdata1、系统库、所有数据库一并清空。
- 验证方法:停容器 →
docker rm→ 用相同命令重跑 → 连上去执行SHOW DATABASES;,若旧库消失,说明没挂对 - 别信“重启保留数据”——那是容器没删,数据还在临时文件系统里,不是持久化
-
docker volume ls看不到卷名,基本可以确定没生效
挂载 /var/lib/mysql 的两种方式怎么选?
命名卷(docker volume)和绑定挂载(-v /host/path:/var/lib/mysql)都能持久化,但适用场景不同。
MiniMax 图片理解 + 网络搜索 MCP 工具。适配 Docker 环境(极空间等),支持图片 OCR 识别、图像内容理解、网络搜索。API Key 安全存储在本地 credentials 文件,不暴露在代码中。
- 生产环境优先用命名卷:
docker volume create mysql-data→ 启动时-v mysql-data:/var/lib/mysql。Docker 自动管理路径、权限、SELinux 标签,不用操心 UID 999 冲突或 macOS 文件系统异常 - 开发/调试需直访文件时用绑定挂载:必须提前
mkdir -p /data/mysql8并chown -R 999:999 /data/mysql8,否则容器卡在Initializing database或报Permission denied - 绝对不要挂载非空目录到新容器:如果
/data/mysql8里已有旧数据,得确认是同版本 MySQL 8.x 生成的,否则启动失败,日志里出现mysqld: Can't read dir of '/var/lib/mysql/' (Errcode: 13)
定时备份脚本必须避开哪些坑?
备份不能塞进容器,也不能依赖容器内 cron —— MySQL 镜像不带 cron,且备份是运维职责,不是数据库职责。
- 密码别硬编码:用
MYSQL_ROOT_PASSWORD_FILE环境变量 +secrets(docker-compose)或宿主机~/.my.cnf(映射进容器时加:ro),避免出现在ps aux或 shell history 中 - 备份命令必须从宿主机发:例如
docker exec mysql8 mysqldump -u root --password="$MYSQL_ROOT_PASSWORD" --all-databases,输出重定向到宿主机路径如/backup/mysql-$(date +%F).sql.gz,不能写进容器临时文件系统 - 压缩和清理要写进脚本:用
| gzip减小体积;用find /backup -name "*.sql.gz" -mtime +7 -delete控制保留天数,否则磁盘迟早爆掉 - 测试脚本前先手动跑一次:
sh /opt/mysql_backup.sh,确认能生成文件、无权限错误、docker exec能连上容器
my.cnf 挂载后不生效?检查加载顺序和段名
MySQL 8.0 启动时按固定顺序读配置:/etc/mysql/my.cnf → /etc/mysql/conf.d/*.cnf → /etc/mysql/mysql.conf.d/*.cnf。挂错位置或缺关键段,配置就静默失效。
- 自定义配置应放
/etc/mysql/conf.d/my-custom.cnf(挂载时用-v ./conf.d/my.cnf:/etc/mysql/conf.d/my.cnf:ro),且文件开头必须有[mysqld]段,否则被忽略 - 别覆盖
/etc/mysql/my.cnf主文件——镜像升级可能破坏结构;也别挂到/etc/mysql/mysql.conf.d/下却起名01-my.cnf,MySQL 8.0 不识别数字前缀 - 废弃参数如
query_cache_type会导致启动失败,日志里只报unknown variable,不会说明哪行出错,建议用mysqld --verbose --help | grep "max_connections"核对参数是否支持
最易被忽略的是:备份脚本里的 docker exec 命令必须用容器名(mysql8),不是镜像名(mysql:8.0);挂载目录权限设错一次,容器就永远卡在初始化,而日志里未必明确提示 UID 问题——得看 docker logs mysql8 最开头几行有没有 mysqld: Can't create/write to file。










