在运行 Docker 和 MySQL 的生产服务器上,合理的硬盘划分(尤其是系统盘与数据盘分离)是保障稳定性、性能、可维护性和数据安全的关键实践。以下是经过验证的推荐方案及详细说明:
✅ 核心原则(必须遵守)
- 系统盘(OS Disk)只存放操作系统、Docker 引擎、容器镜像元数据(非实际镜像层)、配置文件等;
- MySQL 数据目录(
datadir)、Docker 卷(/var/lib/docker/volumes/)必须严格挂载到独立的数据盘; - 避免
/var/lib/mysql或/var/lib/docker位于根分区(/)——否则磁盘写满将导致系统崩溃或服务不可用。
📦 推荐硬盘划分方案(以双盘为例)
| 分区/挂载点 | 类型 | 建议大小 | 说明 |
|---|---|---|---|
/(系统盘) |
SSD/NVMe(小容量) | 40–80 GB | 仅装 OS(如 Ubuntu/CentOS)、Docker Engine、基础工具、日志轮转后的 journalctl 日志(需限制大小)。✅ 关键:不存任何业务数据或大体积容器层。 |
/var/lib/docker |
独立数据盘(SSD/NVMe 优先) | ≥200 GB(按容器镜像+卷预估) | Docker 默认存储路径。若使用 overlay2 驱动,I/O 密集;建议单独挂载(如 /data/docker → 符号链接或 --data-root 配置)。 |
/var/lib/mysql |
独立数据盘(高性能 SSD/NVMe,最好与 Docker 盘物理隔离) | ≥500 GB+(按数据量+增长预留 30–50%) | MySQL 数据库文件(.ibd, ibdata1, binlog, redo log 等)所在。必须独立!⚠️ 若与 Docker 共用一盘,高并发 I/O 可能互相干扰。 |
/var/log/mysql |
可选:同 MySQL 盘 或 单独日志盘 | ≥50 GB | 归档 binlog、slow query log、error log,便于审计与故障排查。 |
/backup(可选) |
大容量 HDD 或 NAS/S3 挂载 | 按备份策略(如全量+增量7天) | 绝不与数据盘同物理设备! 用于定期 mysqldump/xtrabackup 存储,或直接挂载对象存储(rclone/s3fs)。 |
💡 为什么强调物理分离?
- MySQL 的随机读写 + Docker 的顺序写入混合会导致 SSD 耗损加剧和延迟抖动;
- 单盘故障将同时丢失数据库和容器状态(灾难性);
- 便于分别做监控(
iostat -x 1)、限速(ionice/cgroups)、快照(LVM/ZFS)。
⚙️ 实施步骤(关键操作)
1. 安装时规划(最佳时机)
- BIOS/UEFI 中启用 RAID(如 RAID 10 提升 MySQL 性能与冗余)或直通多块 SSD;
- 安装系统时:手动分区,将
/分配小空间,剩余空间留作 LVM PV 或直接格式化为/data。
2. 挂载数据盘(示例)
# 假设新盘为 /dev/nvme1n1
sudo mkfs.xfs -f /dev/nvme1n1
sudo mkdir -p /data/mysql /data/docker
echo '/dev/nvme1n1 /data xfs defaults,noatime,prjquota 0 0' | sudo tee -a /etc/fstab
sudo mount -a
# 创建子目录并设置权限
sudo chown -R mysql:mysql /data/mysql
sudo chown -R root:docker /data/docker
sudo chmod -R 750 /data/mysql /data/docker
3. 配置 MySQL 使用新路径
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
datadir = /data/mysql
socket = /var/run/mysqld/mysqld.sock
log_error = /var/log/mysql/error.log
# binlog & redo log 建议也放 /data/mysql 下(或单独挂载)
innodb_log_group_home_dir = /data/mysql
✅ 执行前:
sudo systemctl stop mysql→sudo rsync -avP /var/lib/mysql/ /data/mysql/→ 更新权限 → 启动。
4. 配置 Docker 使用新根目录
// /etc/docker/daemon.json
{
"data-root": "/data/docker",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
sudo systemctl restart docker
# 验证:docker info | grep "Docker Root Dir"
5. (强烈推荐)使用命名卷 + 显式挂载
# 创建专用卷(自动在 /data/docker/volumes 下)
docker volume create mysql-data
# 运行 MySQL 容器时显式绑定
docker run -d
--name mysql-prod
-v mysql-data:/var/lib/mysql
-v /data/mysql/conf:/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=xxx
-p 3306:3306
mysql:8.0
🚫 绝对避免的错误做法
| ❌ 错误方式 | 风险 |
|---|---|
MySQL 数据放在 /var/lib/mysql(默认,即根分区) |
磁盘写满 → systemd-journald 崩溃 → SSH 登录失败 → 无法抢救 |
| Docker 和 MySQL 共用一块 SATA HDD | I/O 竞争严重,MySQL 响应延迟 >1s,主从复制延迟飙升 |
不限制 Docker 日志大小(/var/lib/docker/containers/*/*.log) |
日志暴涨数 GB/天,悄无声息占满磁盘 |
备份目录 /backup 与数据盘同一物理设备 |
磁盘损坏 → 数据 + 备份全丢 |
📈 扩展建议(进阶)
- 监控告警:用 Prometheus + Node Exporter 监控
/、/data/mysql、/data/docker使用率(阈值 80% 告警); - 自动清理:
# 清理旧 Docker 镜像/悬空卷(加入 cron) docker system prune -af --volumes # MySQL 自动 purge binlog(set global binlog_expire_logs_seconds=259200;) - 文件系统选择:
- MySQL:
XFS(支持大文件、配额、在线扩容)优于 ext4; - Docker:
XFS或ext4(开启barrier=1)均可,但避免 Btrfs(Docker 官方不推荐);
- MySQL:
- 云环境适配:
- AWS:
/用 gp3(小容量),MySQL 用 io2 Block Express(高 IOPS),Docker 用 gp3 卷; - 阿里云:系统盘 ESSD PL1,数据盘用 ESSD PL3 + 多路挂载。
- AWS:
✅ 总结:一句话黄金准则
“系统盘管生死,数据盘管存续;MySQL 与 Docker 的 I/O 路径必须物理隔离,且各自拥有独立的容量规划、监控与备份策略。”
如需,我可为你提供:
- 完整的
fstab+daemon.json+my.cnf配置模板 - 自动化部署脚本(Ansible / Shell)
- 云平台(AWS/Aliyun)具体磁盘类型与大小选型建议
欢迎随时告知你的环境细节(物理机/云服务器?MySQL 版本?预计数据量?QPS?),我来定制优化方案 👇
CLOUD云枢