生产服务器磁盘满报警这种事遇到一次就够长记性了。上周同事半夜发消息说监控报警根分区/使用率已到 98%业务日志写不进去数据库备份也卡住了。查了一圈系统盘当初只分了 40G应用日志和容器镜像早就把它吃干净了。这时候最直接的解决办法就是加一块新磁盘把它挂载到根目录下的指定目录把占空间的大户迁走相当于给根目录做了次扩容。这篇基于 Linux 的实操记录就把挂载磁盘扩容这件事完整讲清楚从新盘分区、格式化到挂载根目录或指定目录再到开机自动挂载和常见坑。如果你也在为目录空间不足发愁这篇文章值得照着抄一遍。1. 扩容思路先分清“加盘”和“改分区”1.1 目录空间告急的常见原因很多人以为磁盘空间满只是“硬盘太小”实际上一大半是分区规划的问题。常见场景有这么几种系统安装时根分区只分了 30G~50G当时觉得够用结果/var、/home、/opt这些目录被日志和业务数据慢慢塞满。云主机自带系统盘偏小数据盘是后加的但应用还是把数据写到了系统盘上。容器环境里镜像和容器层默认存在/var/lib/docker这个目录膨胀速度极快不迁移迟早爆炸。不管是哪一类最终表现都是df -h看到某个挂载点使用率接近 100%然后业务开始报错文件创建失败数据库进入只读保护模式。这时候多数人的第一反应是“删文件”但治标不治本删完之后过一个月又满了。正确思路是新增一块独立磁盘把它挂载到空间不足的目录上让新盘去承接增长的数据量。1.2 几种扩容思路的取舍针对“目录满了”这个症状实际上有好几种应对方式我整理成一张表方便对比方案适用场景是否需要重启风险等级新磁盘挂载到新目录新业务数据目录不用重挂载即可低新磁盘挂载到已有数据目录已有目录数据量大不用但要短暂停业务中迁移大目录绑定挂载根目录或系统盘目录不足不用但需要操作小心中LVM逻辑卷扩容系统装了LVM且有剩余物理卷文件系统在线扩展即可低标题里说的“挂载根目录或指定目录”核心就是第二、第三种思路。需要先说明一个事实对于非 LVM 的普通分区方案Linux 不支持把一块新盘直接“合并”进根文件系统你能做的是把根目录下某个体积大的子目录搬到新盘上再挂载回去这样该目录占用的空间就落到了新盘上根分区的使用率自然降下来。整个过程业务基本可以做到短时中断甚至不停机取决于你用的是停机拷贝还是在线同步。这也解释了为什么标题强调“适用于当前目录不足需要扩容”——这不是教你重新分区而是用挂载的方式做空间腾挪。操作得当比重新初始化系统或在线调整分区要安全得多。2. 实操前的三条命令看清磁盘、分区与挂载现状2.1 lsblk一眼看清当前磁盘拓扑动手之前必须先搞清楚机器上有几块盘、每块盘分了多少区、分别挂载在哪里。我最常用也最推荐先敲的命令是lsblk输出大概是这样的NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 40G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 39G 0 part / sdb 8:16 0 100G 0 disk这条命令的信息量很大。sda是系统盘sda2挂载到了根目录sdb是刚接入的新盘整整 100G还没有分区、没有被挂载这就是后续扩容的弹药。新手最容易犯的错是上来就拿fdisk对着/dev/sda一顿操作万一不小心把系统盘的分区删了系统直接起不来。先跑lsblk的目的就是让你对“哪块盘能动、哪块盘不能动”心里有数。2.2 fdisk -l 与 df -h 的正确配合lsblk看拓扑df -h看使用率两者要结合起来df -hdf -h输出的含义比较直观Filesystem列是文件系统设备Mounted on列是挂载点。我最关心的是根分区使用率比如输出显示/dev/sda2 39G 38G 0 100% /这就是典型的根目录爆满。再看一遍blkidblkid它用来查看分区的 UUID 和文件系统类型后面配置开机自动挂载时一定会用到。这三条命令的配合逻辑很简单先用lsblk确认新盘是谁再用df -h确认哪个目录满了最后用blkid记录新分区的 UUID 备用。2.3 新磁盘设备名的确认与常见命名规律Linux 的设备名有规律可循传统 SCSI/SATA 硬盘/dev/sda、/dev/sdb、/dev/sdc字母 a、b、c 按识别顺序递增。云主机虚拟磁盘可能是/dev/vda、/dev/vdb常见于 KVM 虚拟机。NVMe 固态硬盘/dev/nvme0n1、/dev/nvme0n2命名方式稍有不同但lsblk一样能看明白。判断新盘最稳妥的方法是记下接入磁盘前后的lsblk输出对比。新增了一块 100G 磁盘设备名一般就是多出来的那个。还有一个细节如果机器上有云盘控制台或阵列卡工具最好在控制台里确认磁盘状态避免把有数据的老盘当成空盘初始化。提示新盘上的数据操作全部不可逆。分区、格式化之前务必用lsblk和fdisk -l反复确认目标设备别拿生产环境练手。3. 新磁盘的分区、格式化与临时挂载3.1 用 fdisk 完成新盘分区确认新盘是/dev/sdb后开始分区。这里以传统 MBR 分区为例输入命令fdisk /dev/sdb进入交互式界面后按顺序执行以下步骤输入n创建新分区。输入p表示主分区。分区号默认为 1直接回车。起始扇区默认即可回车。结束扇区如果想整块盘分一个区直接回车。输入w保存分区表并退出。整个过程就是这 6 步。完成后再次执行lsblk会看到/dev/sdb1出现了。如果单块盘容量超过 2TMBR 分区表不支持需要改用 GPT 分区表操作可以使用partedparted /dev/sdb mklabel gpt mkpart primary 0% 100% print quit大部分场景下新数据盘直接整盘一个分区就够了。不需要把 100G 切成好几个区运维上也没必要挂载点规划比分区规划更影响使用体验。3.2 格式化ext4 还是 xfs分区完成后文件系统还是要选的。常见选择是 ext4 和 xfs两者对比如下对比项ext4xfs默认发行版Ubuntu/DebianCentOS/RHEL 7最大文件大小16TB8EiB在线扩容支持resize2fs支持xfs_growfs缩容支持不推荐不支持小文件并发表现稳定高并发下更优选型建议很直接CentOS 系默认用 xfsUbuntu 系默认用 ext4。如果拿不准就用发行版默认的文件系统兼容性最好。格式化命令mkfs.xfs /dev/sdb1 # CentOS/RHEL 系 mkfs.ext4 /dev/sdb1 # Ubuntu/Debian 系格式化速度一般很快100G 的盘几秒钟就完成。格式化完成后再用blkid查看新分区的 UUID这个值在配置 fstab 时必须用到。注意mkfs是格式化命令会清空目标分区原有数据。一定要对着新分区执行不要手滑敲成系统盘分区。3.3 临时挂载与验证先创建挂载点目录再执行mount完成临时挂载mkdir -p /data mount /dev/sdb1 /data df -h这时df -h里会出现/dev/sdb1 100G 33M 99G 1% /data说明挂载成功。所谓临时挂载是指重启后这个挂载关系会丢失所以要验证一下读写cd /data echo test test.txt cat test.txt rm -f test.txt能正常写文件、读文件说明磁盘和文件系统都正常。这一步验证很有必要如果文件系统有问题等到数据迁完才发现就非常被动。4. 真正给“根目录或指定目录”扩容的三种姿势4.1 场景A给全新数据目录挂载新盘这是最简单的场景适合新业务上线、目录刚刚创建还没有数据的情况。比如打算把应用数据放在/data/appmkdir -p /data/app mount /dev/sdb1 /data/app然后直接确认挂载效果df -h /data/app这种方式的好处是零风险因为目录里没有存量数据不需要迁移只需要把后续写入指向这个目录即可。很多人在这一层就停住了想着“反正能用了”结果重启之后挂载变成tmpfs或者丢失代码里配置的路径突然写不进东西才回头补 fstab。4.2 场景B已有数据目录迁移扩容这个场景更常见。比如/data目录已经积累了 500G 数据系统盘塞不下了新盘 1T。这时候不能直接把空的新盘挂到/data上否则挂载点会被新盘盖住原有数据“消失”实际还在原分区上只是被隐藏了。正确做法分四步第一步先把新盘挂载到一个临时目录mkdir /mnt/newdisk mount /dev/sdb1 /mnt/newdisk第二步同步数据。推荐用rsync在拷贝的同时能看进度rsync -avz --progress /data/ /mnt/newdisk/这里注意源目录/data/最后的斜杠不能少它表示复制目录内容而不是把/data整个目录复制过去。第三步确认数据一致后卸载临时目录再挂载到正式目录umount /mnt/newdisk mount /dev/sdb1 /data此时/data下应该能看到原来所有文件。第四步验证无误后更新 fstab 保证重启后依然生效。这里有几个必须强调的细节迁移期间写入/data的业务必须暂停否则边写边拷贝会丢数据如果服务没法完全停止可以使用rsync先做一次全量同步再短暂停服做增量同步这样停机时间只有几分钟拷贝完成前原本的/data目录不要删保留原分区数据等于留了一条退路。4.3 场景C根目录不足迁移大目录根目录/挂载的系统盘满了新增数据盘后不能直接给根目录“续命”但可以通过迁移大目录把根分区的空间释放出来。最常见的三大空间大户是/home、/var/log和/var/lib/docker。以迁移/var/lib/docker为例# 停掉 docker 服务避免有文件在写入 systemctl stop docker # 新盘挂载到临时目录 mkdir /mnt/newdisk mount /dev/sdb1 /mnt/newdisk # 同步 docker 数据 rsync -avx /var/lib/docker/ /mnt/newdisk/ # 原目录改名备份再挂载新盘 mv /var/lib/docker /var/lib/docker.bak mkdir /var/lib/docker mount /dev/sdb1 /var/lib/docker # 启动 docker 并验证 systemctl start docker docker ps验证正常后原备份目录可以保留一段时间再删除rm -rf /var/lib/docker.bak注意rsync参数我特意写了-x它表示不跨文件系统边界避免把其他挂载点比如/proc、/sys的内容拷进去。如果没有-x同步时可能带出莫名其妙的内容。根目录下的其他目录同理。迁移完后df -h会看到根分区使用率明显下降而/var/lib/docker对应的挂载点变成了新磁盘容量变成了新盘大小。这就是标题里“挂载根目录或指定目录”最典型的落地方式。4.4 开机自动挂载与fstab配置临时挂载只在当前运行周期有效重启后挂载关系就没了。要让系统开机自动挂载需要编辑/etc/fstab。先获取新分区的 UUIDblkid /dev/sdb1输出类似/dev/sdb1: UUID9c28e564-6b5a-4c4a-b1d9-9a8b2e2f1a38 TYPExfs然后编辑/etc/fstab追加一行UUID9c28e564-6b5a-4c4a-b1d9-9a8b2e2f1a38 /var/lib/docker xfs defaults 0 2字段含义依次是设备 UUID、挂载点、文件系统类型、挂载选项、是否备份、是否检查。第五列0表示不备份第六列2表示开机后进行文件系统检查根分区一般写1其他分区写2。配置完成后先用下面的命令测试配置是否正确mount -a如果没有任何报错再执行一次df -h确认挂载已生效。这里强烈建议用 UUID 而不是/dev/sdb1这种设备名因为系统启动时磁盘设备名有可能变化插拔、内核识别顺序变化都会导致UUID 是分区的唯一标识不会变。4.5 补充如果系统是 LVM如果你的系统在安装时就启用了 LVM扩容会简单很多。整体流程是新盘创建物理卷 - 加入卷组 - 扩展逻辑卷 - 扩展文件系统。CentOS 系常见命令pvcreate /dev/sdb1 vgextend centos /dev/sdb1 lvextend -l 100%FREE /dev/mapper/centos-root xfs_growfs /如果是 ext4最后一步要换成resize2fs /dev/mapper/centos-root这种方式的好处是逻辑卷容量可以动态扩展根分区直接变大不需要迁移目录。前提是当初安装系统时用了 LVM纯默认分区就用不了。判断方法很简单df -h里如果看到/dev/mapper/xxx-root这种路径说明根分区在逻辑卷上可以走 LVM 路线如果看到/dev/sda2说明是普通分区还是老老实实用目录迁移方案。5. 常见问题与排查实录5.1 mount 提示目录非空怎么办执行mount /dev/sdb1 /data时如果/data里已经存在文件系统警告mount: /data: mount point is not empty.这是 Linux 的保护机制。遇到这个情况先把新盘挂到临时目录把原目录的数据同步过去再重新挂载正式目录不要强行挂载。前文场景B已经给出完整流程核心思路就是“先迁移再挂载”。5.2 重启后挂载丢失重启后df -h里看不到新挂载点绝大多数原因是没有配置/etc/fstab。解决方案就是按 4.4 节的步骤补上 fstab 配置。还有一种情况是 fstab 配置了但没生效可以执行journalctl -u systemd-fstab-check查看具体报错。5.3 fstab 写错导致无法开机fstab 写错是严重的运维事故系统启动时会因为无法挂载某个分区而进入紧急模式。常见表现是启动卡在Welcome to emergency mode!这时候有两条路可以走如果有密码能进入救援模式直接编辑 fstab把错误行注释掉mount -o remount,rw / vi /etc/fstab # 注释掉错误配置如果进不了系统需要在引导界面选择“救援模式”或进入单用户模式把根文件系统重新挂载为读写再修改 fstab。避免这类事故最有效的办法是每次改完 fstab 先用mount -a验证确认无误后再重启。这句话值得再强调一遍改 fstab 后一定要验证不要抱着“应该没问题”的心态直接 reboot。5.4 卸载提示 target is busy数据迁移完想卸载临时挂载点系统提示target is busy.说明有进程正在使用这个挂载点目录。用下面命令查看占用进程fuser -vm /mnt/newdisk # 或者 lsof D /mnt/newdisk定位到占用进程后等任务结束或者手动终止进程再执行umount。如果是数据同步刚完成多半是rsync或tar进程还没退出等待即可。5.5 挂载后看不到之前的数据有一种容易让人心慌的情况新盘挂载到/data之后发现/data下全是空的原来数据“丢了”。其实数据没丢只是被新挂载的文件系统覆盖了。原数据还停留在原磁盘分区的/data目录中卸载新盘后数据就会重新出现umount /data ls /data这就是为什么迁移场景不能先把新盘 mount 到正式目录而是要经历“临时挂载 - rsync - 正式挂载”这个流程。真遇到这种情况不要慌也不要立刻重新格式化先把新盘卸载恢复原状再按正常流程走。5.6 挂载后目录权限异常很多时候数据文件拷过去了应用还是报 Permission denied。排查三步走检查目录属主和属组是否一致ls -ld /data/app权限不对就修正chown -R appuser:appgroup /data/app检查 SELinux 是否拦截。CentOS/RHEL 默认开启 SELinux新挂载的目录可能没有正确的安全上下文restorecon -Rv /data/app如果业务本身不依赖 SELinux也可以临时查看getenforce状态但最稳妥的是用restorecon恢复上下文而不是直接关闭 SELinux。根据个人经验最后再分享几个实用习惯第一云硬盘操作前先打快照分区、格式化、迁移都算高危操作有快照等于有后悔药第二fstab 里一律用 UUID别偷懒写设备名第三迁移大数据量之前先跑一次rsync --dry-run确认源和目标、路径没有写错再执行正式同步第四重要目录迁移完成后保留原目录备份至少一周确认线上稳定再清理。这套流程多跑几次就会很顺后续遇到任何“目录空间不足”的告警都能有条不紊地处理。