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

在运行 Docker 和 MySQL 的生产服务器上,合理的硬盘划分对性能、可靠性、可维护性和安全性至关重要。以下是经过实践验证的推荐方案(兼顾通用性与最佳实践):


✅ 核心原则(先记住这4点)

  1. 分离系统与数据:操作系统、Docker 运行时、MySQL 数据必须物理/逻辑隔离
  2. 数据盘独立挂载:MySQL 数据目录(/var/lib/mysql)和 Docker 数据根目录(/var/lib/docker)应分别挂载到独立磁盘或 LVM 逻辑卷(避免 I/O 竞争)
  3. 日志与数据分离(进阶):MySQL 的 innodb_log_group_home_dir(redo log)、binary log、slow query log 建议与数据文件分盘(尤其高写入场景)
  4. 预留空间 + 监控:数据盘预留 ≥20% 空间防写满;所有关键路径需配置磁盘使用率告警

📦 推荐硬盘划分方案(以双盘服务器为例)

分区/挂载点 推荐大小 文件系统 说明与注意事项
/(系统盘) 50–100 GB XFS 或 ext4 仅存放 OS、内核、Docker Engine 二进制、配置文件。不存任何容器镜像或 MySQL 数据。XFS 对大文件和并发IO更优。
/var/lib/docker 独立磁盘/LVM(如 /dev/sdb XFS 必须单独挂载! 存放镜像、容器层、卷(volume)。避免与 MySQL 共享磁盘导致 I/O 冲突(如 MySQL 写 redo log + Docker 写 layer)。建议 ≥200 GB(根据镜像数量/容器规模调整)。
/var/lib/mysql 独立磁盘/LVM(如 /dev/sdc XFS 强制要求! MySQL 数据库文件(ibdata1, ib_logfile, .ibd, *.frm 等)。XFS 支持大文件、延迟分配、高效扩展。建议 ≥500 GB+(按业务数据量预估 × 3 倍冗余)。
/var/log/mysql 可选:与 /var/lib/mysql 同盘 或 单独小盘(10–20 GB) XFS/ext4 存放 error log、slow log、general log。高负载时日志写入频繁,分离可防日志刷爆数据盘。
/backup 独立大容量盘(如 /dev/sdd)或 NAS/NFS XFS 绝不与数据盘共用! 存放 mysqldump/xtrabackup 备份。建议容量 ≥ 数据盘的 2–3 倍(含保留多份全量+增量)。

💡 为什么不用默认的 /var/lib/docker/var/lib/mysql 在同一分区?

  • MySQL 是顺序+随机混合 IO,Docker overlay2 是大量小文件元数据操作 → 磁盘寻道竞争严重,TPS 下降 30%+
  • 任一服务写满会导致整个系统不可用(如 MySQL 日志填满 /var,Docker 无法创建容器,SSH 日志也无法写入)
  • 故障隔离:一块盘故障不影响另一服务(如 Docker 磁盘损坏,MySQL 仍可运行)

⚙️ 实施步骤(以 Linux 为例)

# 1. 新增两块数据盘(假设为 /dev/sdb, /dev/sdc)
# 2. 创建 XFS 文件系统并挂载(示例)
sudo mkfs.xfs -f -i size=512 /dev/sdb    # 优化小文件 inode
sudo mkfs.xfs -f -i size=512 /dev/sdc
sudo mkdir -p /var/lib/docker /var/lib/mysql

# 3. 永久挂载(/etc/fstab)
echo '/dev/sdb /var/lib/docker xfs defaults,noatime,inode64 0 0' >> /etc/fstab
echo '/dev/sdc /var/lib/mysql xfs defaults,noatime,inode64 0 0' >> /etc/fstab
sudo mount -a

# 4. 迁移现有 MySQL 数据(停机操作!)
sudo systemctl stop mysql
sudo rsync -avh /var/lib/mysql/ /var/lib/mysql_new/
sudo rm -rf /var/lib/mysql/*
sudo rsync -avh /var/lib/mysql_new/ /var/lib/mysql/
sudo chown -R mysql:mysql /var/lib/mysql
sudo systemctl start mysql

# 5. 配置 Docker 使用新路径(/etc/docker/daemon.json)
{
  "data-root": "/var/lib/docker",
  "storage-driver": "overlay2",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
sudo systemctl restart docker

🛡️ 进阶加固建议

场景 推荐方案
高可用 MySQL 使用 --datadir 指向独立盘;启用 innodb_flush_method=O_DIRECT(绕过 OS cache,避免双缓存)
Docker 卷管理 创建命名卷时指定 --driver local --opt o=bind --opt type=none --opt device=/mnt/mysql_data 显式绑定到高性能盘
监控告警 df -h + Prometheus + Node Exporter 监控各挂载点;阈值设为 85% 触发告警
备份策略 xtrabackup 全量备份到 /backup;binlog 实时同步到异地;备份后 du -sh /backup 校验大小
安全加固 /var/lib/mysql 设置 chown mysql:mysql + chmod 700;禁用 root 登录,最小权限账号

❌ 常见错误(务必避免)

  • ❌ 将 MySQL 和 Docker 共用 /var 分区(最常见事故源头)
  • ❌ 使用 ext4 且未调优(如未禁用 atime、未增大 inode 数量)→ 小文件性能差
  • ❌ 忽略 swap 分区影响:Docker 容器内存超限时,swap 可能被频繁使用拖慢 MySQL → 建议关闭 swap(swapoff -a)或严格限制容器内存
  • ❌ 不做磁盘健康检查:定期 sudo smartctl -a /dev/sdX 检查坏道

✅ 总结:一句话黄金法则

“系统盘只跑 OS,数据盘专盘专用——MySQL 一盘,Docker 一盘,备份再一盘,日志可选一盘。”
三盘起步(系统+MySQL+Docker),四盘更稳(+备份),五盘极致(+日志+监控日志)。

如需根据你的具体场景(云服务器 EBS?本地 NVMe?MySQL 版本?QPS 预估?)定制方案,欢迎提供细节,我可为你生成完整部署脚本和参数调优清单。

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