在运行 Docker 和 MySQL 的生产服务器上,合理的硬盘划分(尤其是系统盘与数据盘分离)对性能、可靠性、可维护性和安全性至关重要。以下是经过实践验证的推荐方案和关键原则:
✅ 一、核心原则(为什么必须分离?)
| 维度 | 系统盘(/) |
数据盘(MySQL + Docker) |
|---|---|---|
| I/O 特性 | 随机小IO为主(日志、包管理、配置) | MySQL:高并发随机读写;Docker:镜像层写入、容器卷IO → 需高IOPS/低延迟 |
| 故障影响 | 系统崩溃可重装 | 数据盘损坏 = 业务数据丢失(MySQL数据文件、Docker volumes) |
| 扩容性 | 通常固定大小(50–100GB足够) | 数据持续增长,需独立扩容(如挂载新LVM卷、云盘扩容) |
| 备份策略 | 系统配置可版本化(Ansible/Terraform) | MySQL必须物理/逻辑备份 + binlog;Docker volumes需单独快照/备份 |
| 安全隔离 | SELinux/AppArmor 策略作用域 | 避免容器或MySQL进程因磁盘满导致系统OOM或服务僵死 |
⚠️ 反面案例:所有内容放在
/分区 → MySQLibdata1或 Docker overlay2 占满根分区 → SSH无法登录、systemd崩溃、MySQL拒绝连接。
✅ 二、推荐分区方案(以 2TB NVMe SSD 为例)
| 挂载点 | 推荐大小 | 文件系统 | 用途说明 | 关键配置 |
|---|---|---|---|---|
/(系统盘) |
40–60 GB | ext4 或 xfs |
OS、内核、Docker Engine二进制、/etc、/var/log(不包括Docker/MySQL日志) |
noatime,errors=remount-ro |
/var/lib/docker |
独立分区(建议 500GB–1TB) | xfs(推荐)或 ext4 |
Docker 镜像、容器层、overlay2 存储驱动数据 | xfs 启用 inode64,allocsize=64k;禁用 barrier=0(仅限SSD) |
/var/lib/mysql |
独立分区(建议 800GB–1.5TB) | xfs(强烈推荐) |
MySQL 数据文件(ibdata1, .ibd, ib_logfile*)、tmpdir |
xfs 启用 logbsize=256k,swalloc,allocsize=64k;禁用 journal(-J size=0) |
/var/log/mysql |
(可选)软链接至 /var/lib/mysql/log 或独立小分区 |
— | MySQL 错误日志、慢查询日志(避免占满系统盘) | logrotate + maxsize 100M |
/backup |
(可选,独立挂载) | xfs |
MySQL 备份(mysqldump/xtrabackup)、Docker volume 快照 |
每日轮转 + 异地同步 |
💡 为什么选 XFS?
- MySQL 官方文档明确推荐 XFS(尤其大文件、高并发场景)
- 支持
allocsize优化大块写入(InnoDB 默认页16KB)- 日志性能优于 ext4,且无 ext4 的“extents 耗尽”风险
✅ 三、Docker & MySQL 关键配置(确保数据落盘到正确位置)
🔹 Docker 配置(/etc/docker/daemon.json)
{
"data-root": "/var/lib/docker",
"storage-driver": "overlay2",
"default-ulimits": {
"nofile": { "Name": "nofile", "Hard": 65536, "Soft": 65536 }
},
"log-driver": "local",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
✅ 验证:docker info | grep "Docker Root Dir" → 应显示 /var/lib/docker
🔹 MySQL 配置(/etc/my.cnf 或 /etc/mysql/my.cnf)
[mysqld]
# 数据目录(必须指向独立数据盘)
datadir = /var/lib/mysql
# 临时文件(避免/tmp占满系统盘)
tmpdir = /var/lib/mysql/tmp
# InnoDB 日志(高性能关键!)
innodb_log_group_home_dir = /var/lib/mysql
innodb_log_file_size = 256M
innodb_log_buffer_size = 16M
# 表空间路径(若用独立表空间)
innodb_file_per_table = ON
# 禁用 swap(防止OOM)
innodb_flush_method = O_DIRECT
# 日志路径(避免污染系统盘)
log_error = /var/lib/mysql/error.log
slow_query_log_file = /var/lib/mysql/slow.log
general_log_file = /var/lib/mysql/general.log
✅ 验证:mysql -e "SHOW VARIABLES LIKE 'datadir';" → 输出 /var/lib/mysql
✅ 四、运维最佳实践
| 场景 | 操作 |
|---|---|
| 磁盘监控 | df -h + inotifywait 监控 /var/lib/mysql 使用率 >85% → 告警;iostat -x 1 查看 await < 10ms |
| MySQL 备份 | xtrabackup 全量 + binlog 增量 → 备份到 /backup;禁止用 cp 直接拷贝运行中的 MySQL 文件! |
| Docker 清理 | docker system prune -a --volumes(定期执行)+ 设置 --oom-score-adj -500 防止OOM杀MySQL |
| 升级安全 | 系统盘 / 保持最小化(禁用无关服务);MySQL 和 Docker 运行在非 root 用户(mysql、dockerroot) |
| 云环境特别注意 | AWS EBS:/var/lib/mysql 挂载 io2 卷(预配置 IOPS);阿里云:选择 ESSD PL3;禁用系统盘作为数据存储 |
❌ 常见错误(务必规避)
- 将 MySQL
datadir设为/var/lib/mysql但未创建独立分区 → 实际仍在系统盘 - Docker 使用默认
/var/lib/docker路径,却未单独挂载 → 与 MySQL 争抢同一块盘 - MySQL
tmpdir指向/tmp(常为内存tmpfs或小分区)→ 大排序/JOIN 导致磁盘满或OOM - 忽略
innodb_flush_method=O_DIRECT→ 双重缓存(OS cache + InnoDB buffer pool),浪费内存且延迟高
✅ 总结:一句话部署口诀
“系统盘求稳(40GB ext4),数据盘求快(XFS独立分区),MySQL和Docker各守一盘,日志备份另挂一盘。”
如需具体命令(如 LVM 创建、XFS 格式化参数、云平台挂载脚本),可告知您的环境(物理机/阿里云/AWS/腾讯云),我可提供一键脚本 👇
是否需要我为你生成:
- [ ] Ubuntu/CentOS 初始化磁盘分区脚本
- [ ] Docker + MySQL 生产级
docker-compose.yml(含 volume 映射) - [ ] Prometheus + Grafana 磁盘监控面板配置?
欢迎继续提问! 🚀
云服务器