运行Docker和MySQL的服务器硬盘应该怎么划分系统盘和数据盘?

在运行 Docker 和 MySQL 的生产服务器上,合理的硬盘划分(尤其是系统盘与数据盘分离)是保障稳定性、性能、可维护性和数据安全的关键实践。以下是经过验证的推荐方案及详细说明:


✅ 核心原则(必须遵守)

  1. 系统盘(OS Disk)只存放操作系统、Docker 引擎、容器镜像元数据(非实际镜像层)、配置文件等;
  2. MySQL 数据目录(datadir)、Docker 卷(/var/lib/docker/volumes/)必须严格挂载到独立的数据盘;
  3. 避免 /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 mysqlsudo 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:XFSext4(开启 barrier=1)均可,但避免 Btrfs(Docker 官方不推荐);
  • 云环境适配
    • AWS:/ 用 gp3(小容量),MySQL 用 io2 Block Express(高 IOPS),Docker 用 gp3 卷;
    • 阿里云:系统盘 ESSD PL1,数据盘用 ESSD PL3 + 多路挂载。

✅ 总结:一句话黄金准则

“系统盘管生死,数据盘管存续;MySQL 与 Docker 的 I/O 路径必须物理隔离,且各自拥有独立的容量规划、监控与备份策略。”

如需,我可为你提供:

  • 完整的 fstab + daemon.json + my.cnf 配置模板
  • 自动化部署脚本(Ansible / Shell)
  • 云平台(AWS/Aliyun)具体磁盘类型与大小选型建议

欢迎随时告知你的环境细节(物理机/云服务器?MySQL 版本?预计数据量?QPS?),我来定制优化方案 👇

未经允许不得转载:CLOUD云枢 » 运行Docker和MySQL的服务器硬盘应该怎么划分系统盘和数据盘?