MySQL容器重启数据丢失90%是挂载失效:需验证/var/lib/mysql是否真实挂载,检查Mounts中Destination为该路径、Source指向命名卷或宿主机绝对路径,并区分匿名卷(不可复用)与命名卷(推荐)。

不是 MySQL 本身出问题,而是 /var/lib/mysql 根本没落到持久化位置——容器重启后数据“消失”,90% 是挂载失效或压根没挂对路径。
检查 /var/lib/mysql 是否真被挂载
别只看 docker run 命令里写了 -v,要进容器验证实际挂载状态:
- 执行
docker exec -it some-mysql ls -ld /var/lib/mysql:如果显示drwxr-xr-x 1 root root,说明是空目录或匿名卷;正常挂载后应为drwx------ 1 mysql mysql - 再跑
docker exec -it some-mysql find /var/lib/mysql -maxdepth 1 -type d | wc -l:返回值大于 1 才说明里面有子目录(如mysql/、sys/),返回 1 就是空的 - 用
docker inspect some-mysql查Mounts字段,确认Destination确实是/var/lib/mysql,且Source指向命名卷(如/var/lib/docker/volumes/mysql-data/_data)或宿主机绝对路径
命名卷 vs 匿名卷:一眼识别“假持久化”
匿名卷是 Docker 的“自动兜底机制”,不是设计用来复用的:
- 错误写法:
docker run -v /var/lib/mysql mysql:8.0→ 这会创建匿名卷,每次运行都生成新哈希名,旧数据彻底隔离 - 正确写法:
docker run -v mysql-data:/var/lib/mysql mysql:8.0→mysql-data是你定义的名字,docker volume ls能稳定看到它 - 自查命令:
docker volume ls --filter dangling=true,如果输出一堆随机 ID,说明你长期在用匿名卷,历史数据已散落各处
权限错位:宿主机目录可读但不可写
绑定挂载(-v /host/path:/var/lib/mysql)时,权限不匹配会导致 MySQL 初始化失败,悄悄退回到容器可写层:
- MySQL 容器内默认以用户
mysql(UID=999)运行,宿主机目录必须属主属组都是 999 - 修复命令:
sudo chown -R 999:999 /host/path(Linux);macOS/WSL 需额外注意文件系统兼容性,首次启动失败优先查docker logs里的Permission denied - 生产环境更推荐命名卷:
docker volume create mysql-data后直接-v mysql-data:/var/lib/mysql,Docker 自动处理权限,不操心 UID/GID 映射
路径对齐:漏一个字符,数据就掉进可写层
官方镜像的数据目录是硬编码的,改不了。挂载路径必须 100% 匹配:
- MySQL 必须是
/var/lib/mysql,不是/var/lib/mysql/(末尾斜杠有时导致挂载失败) - PostgreSQL 是
/var/lib/postgresql/data,漏掉/data就白挂了 - 验证方法:
docker exec -it some-mysql ls -l /var/lib/,确认目标路径是挂载点(显示mountpoint),而不是普通目录
最容易被忽略的是:挂载命令写了,但没验证是否生效;卷创建了,但没确认 Source 和 Destination 是否真正对齐;权限设了,但没覆盖子目录或忽略了 macOS/WSL 的特殊限制。持久化不是“加个 -v 就完事”,而是三步闭环:挂对路径 → 写入测试数据 → 删除重建容器 → 验证数据还在。


















