在运行 Docker 和 MySQL 的生产服务器上,合理的硬盘划分对性能、可靠性、可维护性和安全性至关重要。以下是经过实践验证的推荐方案(兼顾通用性与最佳实践):
✅ 核心原则(先记住这4点)
- 分离系统与数据:操作系统、Docker 运行时、MySQL 数据必须物理/逻辑隔离
- 数据盘独立挂载:MySQL 数据目录(
/var/lib/mysql)和 Docker 数据根目录(/var/lib/docker)应分别挂载到独立磁盘或 LVM 逻辑卷(避免 I/O 竞争) - 日志与数据分离(进阶):MySQL 的
innodb_log_group_home_dir(redo log)、binary log、slow query log 建议与数据文件分盘(尤其高写入场景) - 预留空间 + 监控:数据盘预留 ≥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技术博