ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux与Windows磁盘挂载扩容实战:分区表、文件系统与避坑指南

Linux与Windows磁盘挂载扩容实战:分区表、文件系统与避坑指南 1. 磁盘挂载扩容前必须搞清楚的事1.1 系统盘与数据盘先分清再动手用火山引擎云服务器ECS的人应该都有体会刚开好一台实例系统盘默认跟着系统走数据盘则是一张白纸等你自己在操作系统里“激活”。不少新手栽跟头就是没分清楚这两者的区别——以为在控制台买好了数据盘进系统就能直接看到结果fdisk一敲啥也没有心里就开始慌了。先把这个底层逻辑理清楚云盘是附在物理宿主机上的块设备控制台完成“购买”和“挂载”只是把这块盘从资源池里分配给了你的虚拟机实例至于盘上是空的还是有分区、有文件系统操作系统根本不知道。这跟你在电脑城买了一块新硬盘拿回家插上SATA线一个道理主板识别到了但Windows的资源管理器里不会平白无故多出一个盘符你还得去磁盘管理里初始化、分区、格式化。这里有个容易被忽略的细节系统盘在创建实例时由镜像自动完成了分区和格式化数据盘则完全没有。所以整个实操流程的起点是先通过SSH连上Linux服务器或者用VNC/远程桌面连上Windows服务器把这块新盘“认出来”再按需求初始化。1.2 分区表与文件系统选型别等出问题再后悔我在帮别人排查服务器问题时见过太多因为分区表选错导致的惨案。这里直接给结论2020年以后创建的系统盘和数据盘无脑选GPT不要选MBR。原因很简单MBR最大只能识别2TB的容量超过2TB的盘用MBR分区表系统只认到2TB剩下的空间就睡大觉了。GPT没有这个限制而且支持更多分区数量UEFI启动模式下也必须要GPT。文件系统方面Linux下最常见的选择是ext4和xfs。ext4老牌文件系统成熟稳定在线扩容和缩容都支持缩容有风险一般不建议小文件场景表现不错。xfsRHEL/CentOS系默认文件系统处理大文件、高并发写入场景更强但只支持扩容不支持缩容跨版本迁移也稍麻烦一点。怎么选我个人的习惯是如果跑的是数据库、日志类重IO业务优先xfs如果是普通网站、文件存储、中小型应用ext4完全够用。实在拿不准就看你系统盘当初镜像默认用的什么文件系统跟它保持一致最省心。Windows那边则统一用NTFS没有第二种说法。只有老掉牙的场景比如要给某些古董嵌入式设备做移动盘才考虑FAT32/exFAT。1.3 控制台操作与实例内操作的关系整个磁盘挂载扩容流程可以简单拆成两条线云控制台火山引擎网页端创建云盘 - 挂载到实例 - 扩容时先扩容量 操作系统内部Linux/Windows识别盘 - 分区 - 格式化 - 挂载/分配盘符 - 扩容时扩分区和文件系统很多人搞不清这两条线的顺序和依赖关系往往卡在“控制台已经扩容了为什么系统里df -h还是老样子”这一步。其实很简单控制台操作的是云盘的虚拟容量系统内部操作的是分区表和文件系统的逻辑结构。云盘容量在控制台变大了相当于你给一块物理硬盘换了个更大容量的盘体但硬盘上原来的分区边界还在原地文件系统的元数据也还按照旧大小管理着空间。必须手动把分区在线扩展再把文件系统撑大新容量才真正归你系统用。这就像你换了个更大的衣柜但里面的隔板还是按原来大小装的你不动隔板多出来的空间就是摆设。2. Linux 环境下的磁盘挂载与扩容2.1 全新数据盘从识别到挂载的五步法假设你已经在火山引擎控制台创建了一块云盘比如50GB SSD并挂载到了Linux实例上。接下来按我的顺序操作就好。第一步确认盘被系统识别lsblk fdisk -l第一次建议两个命令都跑一遍lsblk看整体拓扑fdisk -l看盘符和容量。新盘通常显示为/dev/vdb、/dev/vdc这样的名字火山引擎大多数实例是虚拟化块设备设备名前带v。如果发现lsblk里看不到新盘先别急着在系统里折腾回控制台确认一下挂载状态和实例所在地域是否一致。第二步分区这步有两种思路。如果你只想把整块盘做成一个区大部分场景都够用直接fdisk /dev/vdb # 依次输入 # n新建分区 # p主分区 # 回车默认分区号 # 回车默认起始扇区 # 回车默认结束扇区 # w保存退出如果盘大于2TBfdisk会有兼容性问题要用parted或gdiskparted /dev/vdb mklabel gpt mkpart primary 0% 100% align-check optimal 1 print quit重要提醒别用fdisk在超大容量盘上做完分区再去改GPTfdisk的MBR模式没法直接转到时数据都没了。第三步格式化mkfs.ext4 /dev/vdb1 # 或者 mkfs.xfs /dev/vdb1格式化的过程一般几秒钟就结束了。注意分区号不是盘符/dev/vdb是整块盘/dev/vdb1才是你刚建的第一个分区格式化一定是对着分区做不是对着整盘做。谁对着整盘格式化过谁懂这个痛。第四步挂载mkdir -p /data mount /dev/vdb1 /data df -h到这里新盘已经可以用了写数据进去就能在 /data 下看到。但这是临时挂载重启一次就没了。第五步写入fstab实现开机自动挂载这一步是最多人偷懒的也是云服务器重启后“丢盘”故障的头号原因。# 先拿到分区的UUID别用/dev/vdb1这种设备名去写fstab blkid /dev/vdb1 # 假设输出是 UUIDxxxx-xxxx-xxxx echo UUIDxxxx-xxxx-xxxx /data ext4 defaults 0 0 /etc/fstab # 验证一下fstab有没有写错这步必须做 mount -a为什么用UUID而不是/dev/vdb1这种设备名因为Linux在开机时对云盘设备名的分配顺序不保证100%稳定特别是有多块数据盘时重启后/dev/vdb和/dev/vdc可能对调你按设备名写fstab系统启动时就会把数据挂错目录甚至直接进不了系统。用UUID是钉死的身份标识不会因为设备名变化而出错。fstab格式的六列分别是设备/UUID、挂载点、文件系统类型、挂载选项、dump备份标志、fsck检查顺序。其中最后两列对数据盘填0 0是常规做法只有根分区才建议填 1 1。2.2 系统盘扩容的在线操作火山引擎的系统盘默认在创建实例后就不太动它但如果当初选的容量小了比如20GB的根分区用光了你也可以在控制台对系统盘做扩容。注意部分实例规格支持在线扩容但为了安全官方一般建议先做快照再扩容而且有些老规格实例需要关机才能扩。具体以控制台的提示为准。控制台扩容完成后比如从20GB扩到50GB进系统你会看到这种情况lsblk # vda 20G # └─vda1 20G # vda2 30G - 但这部分还没被分区利用嗯比较严谨的说法是扩容完成后lsblk会显示vda变成了50G但是vda1分区还停留在20G边界上。接下来你需要在系统里把分区边界扩出去再把文件系统撑大多数云厂商的系统盘默认是GPT分区表用growpart操作# CentOS/RHEL装上 yum install -y cloud-utils-growpart # Ubuntu/Debian装上 apt install -y cloud-guest-utils # 扩展分区/dev/vda 1分区注意中间是空格 growpart /dev/vda 1然后针对文件系统做扩容# ext4 resize2fs /dev/vda1 # xfs xfs_growfs /最后df -h确认一下容量变化。特别留意xfs扩容一定要用xfs_growfs并且要挂载到根目录再执行不认设备名ext4则可以用resize2fs同时处理在线状态。这步做错最常见的报错是“Filesystem has a problem, run fsck”多数情况是文件系统类型指定错了。2.3 数据盘扩容链路以及inode不够的坑数据盘扩容跟系统盘扩容的链路几乎一样但有几个地方容易被坑到。数据盘在控制台扩容后比如50GB扩到100GB系统里同样要做两步先把分区长大再把文件系统变大。# 查看现有分区 lsblk # /dev/vdb 50G # └─vdb1 50G # 扩分区growpart也可以用于数据盘 growpart /dev/vdb 1 # 扩文件系统 # ext4 resize2fs /dev/vdb1 # xfs xfs_growfs /data这里提醒一个我在实际运维中踩过的坑如果你的数据盘当初用了LVM逻辑卷管理那控制台扩容云盘后你实际要操作的是三层物理卷pvresize、逻辑卷lvextend、文件系统resize2fs/xfs_growfs。少一步都不行。很多人以为growpart做完就大功告成结果df一看还是50G。另一个更容易被忽略的问题inode耗尽。数据盘容量明明还有几十G剩余但应用一直报磁盘已满。这种时候用df -i看一下大概率是inode用光了。ext4格式化时可以指定mkfs.ext4 -N 50000000 /dev/vdb1来增加inode数量但这必须在格式化时做后期扩inode很麻烦。换成xfs就没这烦恼毕竟xfs是动态分配inode的。3. Windows 环境下的磁盘挂载与扩容3.1 新数据盘初始化与简单卷创建Windows服务器和Linux逻辑完全一致但是操作入口不一样。火山引擎Windows实例默认开通了远程桌面RDP端口默认3389你可以通过Microsoft Remote Desktop客户端连上去操作。连上之后右键点“此电脑” - 管理 - 磁盘管理。新挂载的云盘会显示为“未初始化”前面有一道黑色斜杠对应Linux里的“裸盘未分区”状态。初始化的时候磁盘会弹窗让你选MBR还是GPT跟Linux篇一样建议选GPT。特别说一下如果这块盘之前是从别的服务器解绑再挂过来的初始化会直接清掉盘上的所有数据务必确认盘中无重要数据再做这步。确认初始化完成后在磁盘的“未分配”区域右键 - 新建简单卷。向导里会依次让你设置卷大小、分配盘符、文件系统选NTFS、卷标。这里有一个小坑Windows默认分配盘符的时候可能会占用一个你原来期望的字母比如你希望这块盘是D盘但系统给了一个F。不用急新建完成后右键该卷 - 更改驱动器号和路径就能直接改成你要的盘符。Windows的磁盘管理界面主打一个图形化对新手比Linux友好得多。但有经验的运维都知道图形界面操作在自动化批量管理场景里就是个累赘。所以下面重点讲怎么用命令行和脚本搞定这件事。3.2 用 diskpart 和 PowerShell 快速分盘规模化场景下手动点“新建简单卷”要点的次数很多效率太低。更稳的操作是用diskpartdiskpart list disk select disk 1 convert gpt create partition primary select partition 1 format fsntfs quick labeldata assign letterD exit每一条都好理解列出磁盘、选定磁盘、转成GPT、建分区、格式化、分配盘符。这个脚本对运维来说可以直接存成文本文件给所有新服务器批量执行。我实测下来diskpart的format命令有个容易翻车的细节指定label时不要用中文也不要在label前后有空格。虽然NTFS支持中文卷标但在某些Windows Server版本的脚本环境下中文卷标会变成乱码对后续基于卷标的自动化运维逻辑产生干扰。PowerShell阵营的对应方案是Initialize-Disk -Number 1 -PartitionStyle GPT New-Partition -DiskNumber 1 -UseMaximumSize -AssignDriveLetter Format-Volume -DriveLetter D -FileSystem NTFS -NewFileSystemLabel data -Confirm:$falsePowerShell的好处是可读性强而且返回错误信息更清晰排障比diskpart的cmd风格输出方便不少。3.3 Windows 数据盘扩容在线扩展与命令行方案火山引擎Windows实例的数据盘扩容控制台操作完以后到Windows的磁盘管理里会看到这块磁盘对应的分区后面多出一块“未分配”的空间。此时只要右键原分区 - 扩展卷跟着向导走完容量就合并进来了。但注意一个前提扩展卷的前提是磁盘上原分区和未分配空间是相邻的且在同一个基本磁盘上。如果你的分区布局不是这样的扩展卷选项就是灰色的点不了。比如你以前在盘上做了两个分区中间用掉了一个分区号那后面的空间就没法跟前面合并。Windows的“扩展卷”在底层就当于Linux里的growpartresize2fs的合体版但有一个非常大的限制它只支持NTFS分区在线扩展不支持FAT32或exFAT也不支持把系统盘C盘跨磁盘扩展。命令行方案仍然是用diskpartdiskpart list volume select volume 3 extend注意extend不带参数时会把该卷相邻且未分区的所有空间都吃掉如果只想扩展指定大小后面可以加size20480这种参数单位MB。跟系统盘扩容相关的还有一个Windows特有的坑如果C盘容量低不是因为C盘本身小而是因为系统恢复WinRE分区或者“保留分区”占掉了空间你要先处理这些分区才能顺利扩容。这属于纯Windows问题跟云厂商没关系但排查起来很费时间。建议直接调出命令行的diskpart把整个磁盘的分区列表打出来看一眼布局一目了然select disk 0 list partition如果看到C盘后面有个小分区挡着你就得考虑用第三方工具或者重点备份数据后重建分区布局了。我个人在Windows上遇到这种布局时会果断选择重做系统后把业务盘和数据盘分开不给WinRE留夹心层空间省得日后每次扩容都提心吊胆。3.4 Windows 存储池与动态磁盘的注意事项如果你在Windows服务器上用了存储池Storage Spaces或者老式的动态磁盘扩容逻辑又有变化。动态磁盘是微软旧技术遇到云环境快照恢复经常出问题能不用就别用。新建数据盘的话选基本磁盘Basic就好。存储池是Windows Server 2012以后主推的软件定义存储方案它有自己的虚拟磁盘Virtual Disk层。你往存储池里添加新物理云盘后还需要进入存储池管理界面把新盘添加到池中再扩展虚拟磁盘的大小最后在卷上做扩展。这三层操作缺一不可跟LVM三层的原理如出一辙。有意思的是火山引擎Windows实例默认不会帮你启用存储池大家基本上都是当基本磁盘用所以只有你自己主动创建了存储池才需要走这条链路。4. 常见问题与避坑经验实录4.1 高频故障排查速查表我把这几年在云服务器磁盘操盘现场攒下来的一线排障经验整理成了表格收藏起来绝对用得上现象可能原因排查/解决路径lsblk看不到新盘控制台没挂载/地域选错/实例已锁定回控制台检查挂载状态确认实例运行中看到盘但挂载报错“wrong fs type”分区没格式化或文件系统类型指定错blkid确认实际类型挂载命令带对-t ext4/xfs挂载后重启又找不到盘fstab没用UUID或fstab写错blkid重新获取UUID修正/etc/fstab后mount -a验证df容量没变化分区/文件系统只做了一半lsblk看分区边界是否已扩展再跑resize2fs/xfs_growfs扩容后文件系统报错需要fsck扩文件系统时分区没先扩展先growpart再扩文件系统顺序不能反Windows的扩展卷是灰色未分配空间与原分区不相邻或不在同一磁盘diskpart list partition看布局清理中间分区Windows 挂盘后无盘符卷未格式化或盘符被系统分配走了磁盘管理里右键更改驱动器路径指定盘符即可应用提示“磁盘无空间”df -h仍有空间inode耗尽df -i查看xfs无此问题ext4需要提前规划inode数扩容后fstab里的UUID变了极少见但GPT表重写时可能发生重新blkid更新fstab并恢复SELinux上下文这里面第4条和第5条是出现频率最高的组合拳。仔细想想根因都是“分区表边界”和“文件系统元数据”两个概念混在一起造成的。分区表管的是“这块盘从哪到哪划分给谁”文件系统管的是“这个区域内怎么存文件”。控制台扩容只是把虚拟磁盘整体变大分区表里的分区边界还按旧值记录文件系统的元数据更不知道外面发生了啥。所以必须两步走。4.2 动手前不备份等于拿生产环境赌博不管你是扩容系统盘还是数据盘扩容本身一般不会丢数据但凡是涉及分区表修改的操作都伴随风险。没有什么操作比先做快照更值得养成的习惯。火山引擎控制台里可以直接对云盘做快照而且支持做一致性快照实例下所有云盘一起拍。给数据盘做快照时如果服务器在跑数据库最稳妥的做法是先停库或触发一次 flush确保缓存数据落盘避免快照把内存中的脏数据丢掉。我见过一个真实的案例有人给MySQL所在的数据盘扩容跳过快照growpart做到一半突然网络波动SSH断了重连后分区表处于不一致状态整个盘变成只读。最后花了几个小时用备份重建环境。这就是典型的“省了小钱赔了时间”。另外数据盘快照和备份不能只存在同一地域同一可用区。你至少应该定期把关键数据用对象存储异地备份一份。不过这是运维策略层面的建议了跟本文的实操主题关系不大点到为止。4.3 几个容易让人抓狂的细节我再说几个自己在实操中被坑过的细节。第一个控制台扩容后控制台显示“已生效”但系统里lsblk显示的大小不变。原因通常是实例没有安装云盘的驱动热插拔支持或者实例规格不支持在线扩容。这种时候把实例重启一下不是关停再开就是普通重启系统重新扫描磁盘总线容量就会更新出来。Linux下也可以试试echo 1 /sys/class/scsi_disk/0\:0\:0\:0/device/rescan这种scan触法但不同虚拟化平台支持情况不一样不行就重启简单有效。第二个用growpart时参数里的盘号和分区号之间必须有个空格。比如/dev/vda 1写成/dev/vda1直接报错。这算growpart的一个设计小别扭但我见过不少新人在这里卡了十分钟。第三个grub引导和历史内核的占用。系统盘扩容有时候不是因为分区边界不够而是根分区所在磁盘上还有grub、boot分区等问题。这些不会导致操作失败但会导致你扩容后重启起不来系统。所以系统盘扩容完成后我一定会做一次grub2-mkconfig -o /boot/grub2/grub.cfgCentOS系或者update-grubUbuntu系再重启顺便把多余旧内核清掉给boot分区腾点空间。很多人觉得没必要但真遇到启动故障时再补救代价高得多。第四个Windows云服务器如果开了BitLocker扩容前记得先暂停保护。因为BitLocker会锁定卷的元数据直接扩展卷往往会报“参数错误”。在“控制面板 - BitLocker驱动器加密”里选择暂停保护扩展完成后再恢复。网上很多“扩展卷按钮灰色”的求助帖其实是BitLocker在作祟跟分区布局半毛钱关系都没有。4.4 一块盘挂多个目录的场景怎么处理现实中还有一种需求一块数据盘买大了业务只想用200GB存数据库剩下300GB留给备份目录。此时你不需要把整块盘都格式化成一个大分区而是可以分两个区或者用两个目录挂载同一个分区下把目录规划好就行。我更推荐分区的做法因为容量隔离和故障隔离会更干净# 建两个分区 parted /dev/vdb mklabel gpt mkpart data1 0% 40% mkpart data2 40% 100% quit # 分别格式化 mkfs.ext4 /dev/vdb1 mkfs.ext4 /dev/vdb2 # 分别挂载 mount /dev/vdb1 /data mount /dev/vdb2 /backup或者用subdirectory的方式只建一个大分区然后在这个分区上创建 /data 和 /backup 两个目录并通过bind mount和fstab实现相同效果。两种各有优劣分区隔离更严格bind mount管理更灵活。一般情况下大分区目录方式就够了真正需要隔离时再上分区。4.5 火山引擎控制台内相关的操作细节最后补一下控制台层面容易踩的几个点。云盘在控制台创建时可用区和实例保持一致是铁律。如果你在可用区A的实例上挂可用区B的云盘那永远挂不上去只能先在同可用区创建新盘再拷贝数据。解挂云盘前一定要先在系统内做umountLinux或脱机Windows否则控制台点解挂会报“磁盘忙”。有些刚入门的朋友在Windows里直接拔盘从控制台卸载结果数据没同步重新挂回去后一堆报错跑一遍chkdsk才能恢复。另外火山引擎控制台里支持批量挂载和批量扩容你在列表页勾选多块盘一起操作就行省得一块块点。但如果跨多台实例挂载需要留意每台实例的操作系统类型、是否需要分区格式化、是否需要更新fstab这个批量脚本在自动化编排系统里实现更有保障纯手工操作还是逐台处理比较稳妥。写在最后磁盘挂载、扩容这事本身不复杂分解开其实就是“控制台扩容量系统内扩分区系统内扩文件系统”的三板斧。真正让运维头疼的从来都不是命令本身而是分区表边界、文件系统类型、UUID持久化、Windows分区布局这些藏在表面之下的逻辑关系。把这层纸捅破了不管换哪家云厂商逻辑都是相通的。我在实际维护中有一个切身的体会无论是Linux还是Windows动手之前先花两分钟画一下“控制台层、分区表层、文件系统层”的关系图胜过一上来敲命令。操作的时候按部就班每敲完一步命令都看一眼输出别批量执行一堆命令然后一次性看结果出了问题根本不知道是哪步的锅。最后再啰嗦一句快照这件事宁可拍了用不上也别到需要的时候才想起来没拍。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进