在 Docker 中安装 MySQL 时,持久化数据是关键操作,否则容器删除后所有数据会丢失。以下是详细步骤和最佳实践,确保 MySQL 数据安全存储在主机上,即使容器重启或删除也能恢复。
一、持久化原理
MySQL 的数据存储在容器的 /var/lib/mysql
目录中。通过 Docker 的 卷挂载(Volume Mount) 或 绑定挂载(Bind Mount),将该目录映射到主机的某个路径,实现数据持久化。
二、持久化安装步骤
1. 创建本地数据目录
在主机上创建一个目录用于存储 MySQL 数据(例如 /data/mysql
):
bash
sudo mkdir -p /data/mysql |
2. 设置目录权限
MySQL 容器默认以用户 mysql
(UID/GID 为 999
)运行,需确保主机目录有正确权限:
bash
sudo chown -R 999:999 /data/mysql # CentOS/Ubuntu 通用 |
注意:如果主机用户系统没有 UID 999,也可直接赋予
777
权限(测试环境临时使用):
bash
sudo chmod -R 777 /data/mysql
3. 运行 MySQL 容器并挂载数据卷
使用 -v
参数将主机目录挂载到容器:
bash
docker run -d \ |
--name mysql-persistent \ |
-p 3306:3306 \ |
-e MYSQL_ROOT_PASSWORD=yourpassword \ |
-e TZ=Asia/Shanghai \ |
-v /data/mysql:/var/lib/mysql \ |
mysql:8.0.33 |
参数说明:
-v /data/mysql:/var/lib/mysql
:将主机/data/mysql
挂载到容器的/var/lib/mysql
。- 其他参数同普通安装(如端口、密码、时区)。
三、验证持久化
1. 测试数据写入
- 进入 MySQL 容器:
bash
docker exec -it mysql-persistent mysql -uroot -p
- 创建测试数据库并退出:
sql
CREATE DATABASE test_db;
EXIT;
2. 删除并重建容器
模拟容器故障或升级,删除原容器并重新创建:
bash
# 停止并删除容器(数据目录 `/data/mysql` 保留) |
docker stop mysql-persistent |
docker rm mysql-persistent |
# 重新运行容器(挂载同一数据目录) |
docker run -d \ |
--name mysql-persistent \ |
-p 3306:3306 \ |
-e MYSQL_ROOT_PASSWORD=yourpassword \ |
-v /data/mysql:/var/lib/mysql \ |
mysql:8.0.33 |
3. 检查数据是否恢复
再次进入 MySQL 容器,确认 test_db
仍存在:
bash
docker exec -it mysql-persistent mysql -uroot -p -e "SHOW DATABASES;" |
输出应包含 test_db
,证明数据持久化成功。
四、高级持久化方案
1. 使用 Docker 命名卷(推荐生产环境)
Docker 命名卷比绑定挂载更安全,由 Docker 管理存储驱动:
bash
# 创建命名卷 |
docker volume create mysql_data |
# 运行容器并挂载命名卷 |
docker run -d \ |
--name mysql-volume \ |
-p 3306:3306 \ |
-e MYSQL_ROOT_PASSWORD=yourpassword \ |
-v mysql_data:/var/lib/mysql \ |
mysql:8.0.33 |
优点:
- 自动处理权限和存储路径。
- 支持卷备份和迁移(通过
docker volume
命令)。
2. 备份与恢复数据
备份数据
bash
# 停止 MySQL 服务(避免数据不一致) |
docker stop mysql-persistent |
# 打包数据目录(绑定挂载场景) |
tar -czvf mysql_backup_$(date +%Y%m%d).tar.gz /data/mysql |
# 或备份命名卷(需临时容器) |
docker run --rm -v mysql_data:/data -v $(pwd):/backup alpine tar czf /backup/mysql_volume_backup.tar.gz -C /data . |
恢复数据
bash
# 解压到数据目录(绑定挂载) |
tar -xzvf mysql_backup_20231001.tar.gz -C /data/mysql |
# 重新启动容器 |
docker start mysql-persistent |
五、常见问题解决
1. 权限错误(Permission denied
)
- 现象:容器启动失败,日志显示
mkdir /var/lib/mysql: permission denied
。 - 原因:主机目录权限不足。
- 解决:
bash
sudo chown -R 999:999 /data/mysql
sudo chmod -R 755 /data/mysql # 或 777(测试环境)
2. 数据目录已存在非空文件
- 现象:首次运行容器时提示
data directory "/var/lib/mysql" already exists and is not empty
。 - 原因:主机目录可能残留旧数据或配置文件。
- 解决:
- 清理目录(谨慎操作):
bash
rm -rf /data/mysql/*
- 或指定初始化参数(仅首次运行):
bash
docker run -d \
--name mysql-persistent \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-v /data/mysql:/var/lib/mysql \
-e MYSQL_DATABASE=init_db \ # 自动创建数据库
mysql:8.0.33 --initialize-insecure # 初始化(无密码)
- 清理目录(谨慎操作):
3. 性能优化建议
- 存储驱动:腾讯云服务器建议使用
overlay2
驱动(默认)。 - 文件系统:数据目录建议放在 SSD 磁盘(如腾讯云
SSD 云硬盘
)。 - 配置调优:挂载自定义
my.cnf
文件:bash
docker run -d \
--name mysql-optimized \
-v /data/mysql:/var/lib/mysql \
-v /path/to/my.cnf:/etc/mysql/my.cnf \
mysql:8.0.33
六、总结
方案 | 命令示例 | 适用场景 |
---|---|---|
绑定挂载 | -v /data/mysql:/var/lib/mysql |
开发/测试环境,快速访问主机文件 |
命名卷 | -v mysql_data:/var/lib/mysql |
生产环境,数据安全性和可管理性更高 |
备份与恢复 | tar -czvf backup.tar.gz /data/mysql |
定期备份关键数据 |