
做运维这些年我碰到最多的新手问题之一就是分不清云服务器上的系统盘和数据盘。很多人买完服务器登录上去直接 df -h发现容量对不上或者习惯性把文件都传到根目录过俩月系统盘满了数据库直接写不进去。这篇文章会讲透一件事Linux 云服务器里系统盘和数据盘到底有什么区别怎么判断某个文件存在哪个盘上以及数据盘从购买、挂载到长期使用的完整流程。内容偏实操命令我都按主流云厂商的 Linux 镜像验证过Ubuntu、CentOS、Alibaba Cloud Linux、TencentOS 基本通用个别差异我会单独指出。刚买云服务器不知道怎么规划磁盘的小白或者正在被“磁盘满了”折磨的业务开发者都可以照着操作。1. 系统盘和数据盘到底差在哪1.1 生命周期不一样这才是核心首先说结论系统盘System Disk / Root Disk是创建云服务器实例时自动生成并挂载的磁盘操作系统就装在上面数据盘Data Disk是你在系统之外额外购买、单独挂载给实例的磁盘。最本质的区别不是“谁的系统文件在上面”而是生命周期绑定关系不同。系统盘的生命周期和实例强绑定。绝大多数云厂商默认的选项里你释放销毁实例时系统盘会跟着一起删除。这就是为什么有些上了生产的机器一旦被误释放整个系统连数据全没了——因为系统盘本身就不是持久化存储的“安全区”。而数据盘不一样它可以设置为“随实例释放”或“不随实例释放”。如果你构建数据盘时选择不随实例释放就算实例被删了数据盘还保留在账号下可以重新挂载到新实例上继续用。所以我对所有新手的第一个建议是操作系统、应用程序、临时文件放系统盘没问题但业务数据、数据库文件、日志这些“不能丢的东西”一律规划到数据盘。这句话我在后面会反复强调因为它能帮你避免九成以上的磁盘灾难。1.2 容量和性能的差异没那么玄乎很多人以为系统盘一定比数据盘快或者数据盘一定更贵其实不准确。云厂商提供的系统盘和数据盘底层都是同一批分布式存储资源大多可以被配置成 SSD、ESSD 或者普通云盘。也就是说同样是 ESSD系统盘和数据盘的 IOPS、吞吐上限如果规格相同性能几乎没有差别。真正的差别在两点第一容量。系统盘创建时的默认容量一般比较小通常是 20GB 到 80GB 之间很多镜像不自带大容量系统盘选项你买的时候也不一定会想到去调整。第二扩容方式。虽然现在很多厂商支持在线扩容系统盘但通常需要关机或者重启才能生效这在生产环境里就意味着业务中断。而数据盘扩容后很多场景下可以做到不停机在线扩容文件系统对业务影响小得多。因此从运维友好度来看把大数据量业务放在数据盘也是更合理的选择。1.3 计费与备份策略也可能不同计费上系统盘一般绑定实例的付费方式比如包年包月实例系统盘费用就跟着包年包月走数据盘则更灵活可以选择包年包月、按量付费甚至单独的存储包。这直接影响你做成本规划时怎么拆分账单。我自己建服务器有个习惯系统盘跟着实例走但数据盘单独按需购买因为数据盘的需求是随业务增长的一开始买太多纯属浪费钱。再说备份。很多云厂商的快照是按“云盘”为维度做的你可以只给数据盘开启自动快照策略把它作为数据库备份的一部分。系统盘虽然在创建时有默认快照或镜像机制但在实践中我更建议直接把系统盘做成自定义镜像配合数据盘快照形成一套“系统可重建、数据可恢复”的方案。这个思路比单纯依赖某一块盘更稳重点是无论系统盘怎么折腾业务数据都有独立副本。2. 上机第一步三个命令看清磁盘布局2.1 lsblk磁盘拓扑一眼看穿登录服务器之后第一步永远是用 lsblklist block devices查看块设备布局。这是我最常用的命令没有之一。执行 lsblk你会看到类似下面的输出$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS vda 253:0 0 40G 0 disk ├─vda1 253:1 0 40G 0 part / vdb 253:16 0 100G 0 disk └─vdb1 253:17 0 100G 0 part /data我来逐列解释一下NAME 是设备名vda、vdb 这种前缀在大部分云服务器上是虚拟磁盘的命名风格也有叫 sda、sdb 的取决于虚拟化驱动MAJ:MIN 是设备的主次设备号一般不用管SIZE 是磁盘或分区大小TYPE 分两类disk 代表整块物理磁盘云厂商视角下的一块云盘part 代表这块磁盘上的分区MOUNTPOINTS 分区挂载到了哪个目录。从上图你能立刻得出结论vda 是系统盘40G挂载在根目录vdb 是数据盘100G已经分区并挂载到 /data。如果你的数据盘买回来了但 lsblk 里看不到 vdb或者看到了 vdb 但它下面没有分区、MOUNTPOINTS 为空说明数据盘还没初始化或没挂载后面第 4 节会专门讲怎么处理。2.2 df -h从文件系统视角看容量lsblk 是“设备视角”df 是“文件系统视角”。df -h-h 表示 human-readable自动换算成 G/M看的是已经格式化并挂载的文件系统占用情况$ df -h Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G 28G 11G 73% / /dev/vdb1 100G 62G 34G 66% /data tmpfs 7.8G 0 7.8G 0% /dev/shm看这里有个容易混淆的点df 输出的是挂载点的容量和用量不是“磁盘还剩多少”。很多人看到 Use% 90% 就慌了其实要结合 Inodes 和其他挂载点一起看。比如 /var/log 如果单独挂了一块盘那么根目录“满了”和“日志盘满了”是两回事。另外 df 还有两个衍生用法df -hT 会多显示文件系统类型ext4、xfs、overlay 等df -i 显示 inode 用量。inode 用满也会导致“磁盘没空间但写不进文件”的诡异现象后面第 5 节我会展开。2.3 mount 与 blkid补充确认细节如果 lsblk 和 df 对不上或者你想确认某个设备到底是怎么被挂载的用 mount 看完整的挂载参数$ mount | grep /dev/vd /dev/vda1 on / type ext4 (rw,relatime) /dev/vdb1 on /data type xfs (rw,relatime)再配合 blkid 拿 UUID 和文件系统类型$ blkid /dev/vda1 /dev/vdb1 /dev/vda1: UUIDa1b2... TYPEext4 /dev/vdb1: UUIDc3d4... TYPExfs为什么要记 UUID因为 /etc/fstab 里推荐用 UUID 而不是 /dev/vdb1 这种设备名来配置开机会自动挂载。原因很直接设备名在系统重启后有可能变化比如新插了一块盘原来的 vdb 可能变成 vdc而 UUID 是文件系统创建时生成的唯一标识只要不重新格式化就不会变。用 UUID 配自动挂载是避免“重启后挂载点错乱”的经典做法。3. 怎么判断一个文件到底存在哪个盘3.1 findmnt从路径反推挂载点很多时候你根本不需要管整张磁盘表只想知道“我有一个路径 /opt/app/data/xxx.db它到底在系统盘还是在数据盘” 一条命令解决$ findmnt -T /opt/app/data/xxx.db TARGET SOURCE FSTYPE OPTIONS /data /dev/vdb1 xfs rw,relatimefindmnt -T 表示 target后面接任意文件或目录的绝对路径它会向上逐级查找直到找到该路径真正所在的挂载点。这是我在排查“为什么 /opt 下传的文件把系统盘塞满了”时最常用的命令比盲猜 du df 效率高得多。如果系统里没有 findmnt一般 util-linux 包里都有极少见没有的情况也可以用 df 直接查看特定文件所在文件系统$ df -h /opt/app/data/xxx.dbdf 后面接文件路径时会直接显示该文件所在文件系统的容量和使用情况输出里的 Filesystem 那一列就是答案。这个方法虽然简单但很适合日常巡检时快速确认某个目录的归属。3.2 常见目录究竟属于谁搞清楚默认目录归属能帮你从源头避免问题。我列一张常用目录的对照表基于主流的 Linux 云服务器镜像默认布局目录默认位置备注/系统盘根文件系统位于系统盘分区/usr、/bin、/lib系统盘系统软件和运行库必须随根文件系统/etc系统盘配置文件目录必须随根文件系统/var系统盘默认在系统盘日志、缓存都在这/home系统盘镜像默认在系统盘生产环境建议单独挂/tmp系统盘临时文件默认在系统盘/data、/mnt/data 等需要手动挂载数据盘最常见的挂载点看到没有默认情况下几乎一切都在系统盘。所以如果你买了一块 100G 数据盘却从来没做过分区挂载那你的数据其实全部还是写在系统盘上数据盘只是“买了个寂寞”。很多新人的磁盘爆满本质上是“买了数据盘但没用起来”。3.3 规划挂载点这套方案我一直在用我自己的挂载规划通常是这样的系统盘保持默认只承担操作系统、运行库和应用二进制单独买一块数据盘挂到 /data然后在 /data 下按业务建子目录比如 /data/mysql、/data/www、/data/logs。如果是容器环境我会把 Docker 的数据目录/var/lib/docker 或自定义的 /data/docker也挪到数据盘上。这样做的收益很直接日志再膨胀也不会把系统盘撑爆重装系统系统盘重置时业务数据还在数据盘上恢复成本极低。这里有一个容易忽略的点如果你的 /var/log 目录增长很快但你又不太想改应用配置可以在数据盘上建一个目录并 bind mount 到 /var/log。bind mount 的写法是在 /etc/fstab 里加一行/data/logs /var/log none bind 0 0这个方式不改变任何应用行为但把日志实际存储位置挪到了数据盘。我用这个招数救过好几台被日志塞满系统盘的生产机器强烈推荐。4. 实操给云服务器挂上第一块数据盘4.1 控制台购买与挂载在云厂商控制台找到“云盘”或“磁盘”入口选择地域必须和实例所在的地域一致否则挂不上、可用区通常也要一致某些厂商支持跨可用区挂载但是有网络性能损耗不建议、容量、类型ESSD/SSD/普通云盘以及付费方式。购买完成后在磁盘列表右侧会有“挂载”按钮选择目标实例确认即可。不同厂商细节略有差异有的厂商在购买时可以直接选择“挂载到某实例”有的必须先购买再挂载。还有的厂商提供“创建时自动格式化并挂载”的选项我建议新手慎重使用这个选项——不是因为它不好而是因为如果你不理解它做了什么以后出问题会一脸懵。手动走一遍分区、格式化、挂载的流程你会对整个机制有更清晰的认识。4.2 实例内分区与格式化挂载完成后控制台显示“已挂载”回到实例里执行 lsblk如果看到一块新的、没有分区的磁盘比如 /dev/vdb说明系统已经识别到了。接下来是标准三步分区、格式化、挂载。先分区。小于 2TB 的盘用 fdisk 就行$ fdisk /dev/vdb进入交互模式后依次输入 n新建分区、p主分区、1分区号然后直接回车接受默认起始和结束扇区也就是把整块盘都划分为一个分区最后输入 w 写入分区表。如果是在较新的环境里也可以直接用 parted 一把梭$ parted /dev/vdb --script mklabel gpt mkpart primary 0% 100%这里要提醒一句超过 2TB 的磁盘传统 MBR 分区表不支持必须用 GPT。fdisk 在新版本里默认也会用 GPT但为了保险遇到大容量盘我从来不纠结直接 parted 指定 gpt 标签避免回头还得转换格式。然后是格式化。文件系统我一般选 ext4 或 xfs各有侧重ext4 兼容性好、误删恢复工具多xfs 对超大文件、高并发写入表现更稳定也是 RHEL/CentOS 系的默认选择。格式化的命令是$ mkfs.ext4 /dev/vdb1或者$ mkfs.xfs /dev/vdb1注意mkfs 是格式化命令会把分区上的所有数据清空。操作前务必确认设备名没错尤其是用通配符或脚本批量操作的时候打错一个字母就可能把系统盘数据抹掉。最后挂载$ mkdir -p /data $ mount /dev/vdb1 /data先创建挂载点目录 /data挂载点本身必须是一个空目录再用 mount 命令把 /dev/vdb1 挂上去。执行完 df -h 看到 /data 有了 100G 容量就说明基本成功了。4.3 配置开机自动挂载手动 mount 只在当前运行期间生效不写进配置的话重启后挂载关系就没了系统会回到“数据盘存在但没用起来”的状态。所以必须配置 /etc/fstab。先用 blkid 拿到数据盘分区的 UUID$ blkid /dev/vdb1 /dev/vdb1: UUIDc3d4e5f6... TYPExfs然后在 /etc/fstab 末尾追加一行UUIDc3d4e5f6... /data xfs defaults 0 0字段依次是分区标识、挂载点、文件系统类型、挂载选项、是否 dump 备份0 即可、是否 fsck 检查根分区一般是 1其他分区 0。写完先别急着重启先执行 mount -a 验证配置是否正确$ mount -a如果没有任何报错说明 fstab 配置没有问题。这一步非常重要因为 fstab 写错是导致云服务器重启后无法进入系统的最常见原因之一后面第 5 节我会讲怎么救。4.4 数据盘没出现的排查流程“我在控制台挂载了数据盘但登录服务器 lsblk 里根本看不到”——这是我被问到最多的问题之一。排查顺序我总结成了四步第一确认控制台里磁盘状态是“已挂载”并且挂载到了当前实例。有时候你挂到了另一个实例或者磁盘还在“待挂载”状态实例里自然看不到。第二在实例里执行 lsblk 和 fdisk -l 看有没有新设备。fdisk -l 能看到原始磁盘即使它没有分区。如果 lsblk 没有但 fdisk -l 有大概率是设备尚未扫描到位可以尝试 partprobe /dev/vdb 让内核重新读取分区表。第三用 dmesg 查看内核日志里有没有磁盘相关报错$ dmesg | tail -30如果看到类似 “vdb: unknown partition table” 这样的信息其实是好消息说明设备已被内核识别只是没有分区表。这是正常的新盘还没有分区接下来按第 4.2 节流程走就行。第四如果上面都没有检查实例类型是否支持挂载数据盘。某些突发性能型实例或者轻量应用服务器根本没有数据盘功能只能靠升级系统盘容量来解决。这一点在购买前就应该看清楚别等买完才发现白折腾。5. 磁盘相关坑位汇总这些都是我踩过的5.1 系统盘被写满服务全线告警现象df -h 显示 / 使用率 100%应用开始报“No space left on device”但你可能觉得很奇怪明明没传多少文件啊。最常见元凶有三个。第一个是日志。/var/log/journal 如果不清systemd 日志会无限增长。用 journalctl --vacuum-size200M 可以快速收敛长期方案是在 /etc/systemd/journald.conf 里设置 SystemMaxUse200M。第二个是 Docker。如果 docker 目录默认在系统盘镜像和 overlay2 层会悄悄吃掉几十 GB。上面说的把 docker 数据目录迁到数据盘是最彻底的办法。第三个是临时文件和大文件。排查时用 du 逐级定位$ du -h -x -d 1 / | sort -hr | head -20-x 参数很重要意思是不要跨越文件系统统计。加上它之后du 只会统计根文件系统系统盘上的内容不会把 /data 等独立挂载点里的数据也算进来否则你会被误导以为系统盘很大。这条命令我在排障时的使用频率极高几乎成了肌肉记忆。5.2 /etc/fstab 写错导致进不了系统配置 fstab 后如果出现“重启后起不来”的情况大概率是 fstab 里路径、UUID 或挂载项写错了。云服务器一般都有“救援模式”或“VNC 登录”进入单用户/救援环境后把有问题的行注释掉再重启即可。具体步骤因厂商而异但思路一致先找到问题行注释掉恢复正常。为了避免走到这一步我有个习惯fstab 写完后连续执行两次 mount -a第一次检查第二次复查然后重启前先执行 sync 和 umount 测试。另外给数据盘挂载的 fstab 行里建议加上 nofail 选项UUIDc3d4e5f6... /data xfs defaults,nofail 0 0nofail 的意思是如果这块盘不存在或挂载失败不要阻止系统继续启动而是跳过它。这在数据盘因故障掉线时能救命——系统不会因为一块数据盘而整个卡死。对于我管理的生产机器凡是数据盘的 fstab 行nofail 是必须加的这个习惯帮我避免过好几次大半夜被叫起来处理“重启后起不来”的麻烦。5.3 数据盘卸载后数据还在吗碰到过不止一次有人跑来问“我在控制台把数据盘卸载了是不是数据就没了” 不是。云盘在控制台的“卸载”动作只是切断了磁盘和实例之间的连接相当于你从 USB 底座上拔下移动硬盘硬盘里的数据还在。真正危险的操作是“释放”或“删除磁盘”那才意味着云盘被销毁数据不可恢复。所以在你打算卸载重挂、换实例挂载之前先确认一下操作入口是“卸载”还是“释放”。我自己的经验是所有涉及磁盘删除的按钮点击前都默念一遍“数据还在里面吗有快照吗有备份吗”宁可多问自己三次也不要事后去找快照。真出过事的人才会懂这句念叨不是矫情。5.4 扩容了磁盘容量却还是看到旧空间控制台对数据盘点了“扩容”但 df -h 里看到的还是原来的容量这也是高频问题。原因很简单扩容有两层磁盘设备扩容了但分区表和文件系统还没扩展。完整流程分三步确认磁盘识别到新容量lsblk 会显示扩展分区growpart /dev/vdb 1 或者 parted resizepart然后扩展文件系统ext4 用 resize2fsxfs 用 xfs_growfs /data。举个例子$ growpart /dev/vdb 1 $ xfs_growfs /data如果系统盘扩容很多厂商要求先重启实例才能识别到新容量这也是为什么我前面建议系统盘扩容要安排在业务低峰期并提前告知团队可能的短暂中断。数据盘扩容虽然多数能在线完成我也建议先在文档里确认当前文件系统是否支持在线 grow不要盲目操作。5.5 误格式化数据盘的后悔药最严重的事故mkfs 打错了盘符把原本有数据的盘格式化成了全新的文件系统。第一时间停掉对这块盘的写入然后想办法恢复。如果之前开通过快照直接回滚快照是最快的没有快照的情况下可以用 extundelete针对 ext4尝试找回。这类恢复不是 100% 成功而且很依赖“越早停写越好”的时机。所以我对所有机器的铁律是重要数据盘一定开启自动快照或定期备份。云厂商的快照通常按次计费成本不高但在事故发生时它就是你的后悔药。没有备份意识的人才会在出事以后满世界找恢复工具。这个道理说说都懂但是真正做到并长期坚持的人不多希望读到这里的你能当那个“做到的人”。6. 一点个人体会这篇文章里的大部分教训其实根源都是一句话没有在一开始就想清楚“数据该放在哪”。我自己刚入门时也踩过系统盘爆满的坑那次是半夜被监控告警吵醒登录上去发现 / 目录 100%原来是一直没人清理的日志和 Docker 镜像把空间吃光了。经历了那次之后我把自己管理的每一台服务器都定了规矩系统盘只装系统和应用数据盘统一挂到 /data日志和容器目录全部用 bind mount 或迁移方式放到数据盘fstab 全部带 nofail快照策略至少保留一周。这套规矩执行下来几年里再没发生过因为磁盘规划导致的线上事故。建议你拿到新服务器后也先花十分钟按这个思路规划好磁盘别等出事了再来救火。