资讯动态

Ubuntu 20.04系统迁移实战:从小容量NVMe硬盘升级至大容量硬盘的完整指南

发布时间:2026/8/13 2:26:01 来源:尧图企业网站定制
1. 项目缘起当硬盘空间告急是时候“搬家”了作为一名长期在Linux环境下工作的开发者我手头这台运行Ubuntu 20.04 LTS的开发机已经服役了三年。当初为了追求极致的读写速度系统盘选了一块256GB的NVMe固态硬盘。三年下来随着项目代码、Docker镜像、虚拟机快照以及各种开发工具的不断累积df -h命令的红色警告已经成了家常便饭。清理临时文件、卸载不常用软件只能解一时之渴核心问题在于物理空间的捉襟见肘。是时候给系统“换个大房子”了——将整个系统从这块256GB的硬盘迁移到一块全新的1TB NVMe固态硬盘上。这听起来像是个大工程但本质上它是一次对系统底层结构的精确复制与重构。不同于Windows下常见的“重装系统再恢复数据”Linux系统迁移的核心在于完整复制文件系统、引导信息以及分区表结构确保新硬盘能无缝启动所有配置、环境变量、用户数据、甚至正在运行的服务状态理论上都能得以保留。这个过程我们通常称之为“系统克隆”或“磁盘对拷”。网络上相关的教程很多但大多只给出命令缺少对背后原理和潜在风险的深度剖析。今天我就结合自己这次从规划到验证的完整迁移经历把每一步的思考、操作和踩过的坑都摊开来为你呈现一份详尽的Ubuntu 20.04系统迁移实战指南。2. 迁移前的战略规划与工具选型在动手之前盲目执行dd命令是极其危险的。一次成功的迁移70%的功夫在于事前的规划和准备。我们需要明确目标、评估风险并选择合适的工具。2.1 明确迁移目标与约束条件我的目标是将当前256GB硬盘记为sda上的整个Ubuntu 20.04系统包括EFI系统分区、/根分区、swap交换分区如果有原封不动地“搬运”到新的1TB硬盘记为sdb上。搬运完成后新硬盘能独立引导进入系统且系统内所有数据、配置、用户账户、已安装软件均与迁移前一模一样。这里有几个关键约束引导方式现代电脑基本都是UEFI启动这意味着硬盘是GPT分区表并且有一个独立的EFI系统分区通常是FAT32格式几百MB大小。迁移时必须正确处理这个分区。分区表复制不能只复制文件系统内容分区表GPT也必须复制或在新盘上重建否则系统无法识别分区结构。文件系统处理我使用的是ext4文件系统迁移工具需要能正确处理其特性如journal日志。目标盘更大这是利好。我们可以在新盘上保持原分区结构不变直接按原大小复制也可以在复制后利用多出的空间进行扩容。后者更实用但步骤稍复杂。2.2 主流迁移工具深度对比基于以上目标我评估了三种主流方案方案一dd命令磁盘对拷这是最“原始”也最彻底的方法。dd if/dev/sda of/dev/sdb bs4M statusprogress。它按扇区逐个复制包括分区表、所有分区、甚至空白区域。优点绝对完整连硬盘的UUID都会改变因为完全一样对于引导复杂的系统有时反而更省心。操作简单粗暴。缺点致命缺点它会将目标盘sdb完全覆盖成和源盘sda一模一样的大小。也就是说1TB的新盘复制完后只有前256GB有数据后面约768GB的空间是“未分配”状态需要后续手动扩容分区才能使用。这造成了空间浪费。速度较慢因为它复制每一个扇区包括空白处。风险极高一旦if输入文件和of输出文件参数写反数据将万劫不复。方案二rsync命令文件同步这是一种“智能复制”。先在新盘上创建类似的分区结构EFI、/、swap然后分别格式化注意新分区会有新的UUID最后用rsync同步文件。优点灵活。可以自由调整新盘的分区大小例如直接把/分区扩大到800GB。可以排除某些临时目录如/tmp,/proc,/sys提高效率。因为是文件级操作可以断点续传。缺点步骤繁琐。需要手动创建分区、格式化、更新/etc/fstab因为分区UUID变了和引导配置grub。对操作者的Linux知识要求较高。方案三专业分区工具如GParted Live, Clonezilla这些是图形化或向导式的工具通常运行在Live CD/USB环境中。优点相对安全有图形界面有些工具如Clonezilla能自动处理引导修复。GParted可以方便地拖拽调整分区大小。缺点需要准备额外的启动介质。Clonezilla在默认设置下其“磁盘到磁盘”克隆模式底层也是调用dd同样存在“目标盘容量浪费”的问题除非使用其“分区到分区”的专家模式并手动调整。我的选择与理由经过权衡我选择了方案二rsync。原因如下空间利用率我可以一步到位在创建新盘分区时就将/分区设置为理想的容量例如800GB避免后续再扩容的麻烦。可控性与学习价值每一步操作我都清晰明了能深入理解Linux启动的各个环节分区、文件系统、fstab、grub。即使中途出错也更容易定位和回退。安全性rsync是增量同步我可以先做一次干运行--dry-run检查确认无误后再执行真实操作。而且在同步过程中源盘系统始终保持原样是完美的备份。注意如果你的系统非常简单或者源盘和目标盘容量相同且你追求极致的简单和“一模一样”那么dd也是一个可选项但务必、务必、务必三思而后行并做好数据备份。对于本次“小盘换大盘”的场景rsync的灵活性优势明显。3. 实战迁移步步为营的完整操作流程确定了rsync方案后我们进入实战环节。请准备一个Ubuntu 20.04的Live USB启动盘即安装U盘因为我们需要在一个“干净”的环境下操作避免正在运行的系统文件被锁定。3.1 第一步从Live USB启动并识别硬盘关机插入Ubuntu Live USB和新的1TB硬盘。开机进入BIOS/UEFI设置选择从USB设备启动进入Ubuntu Live桌面环境。打开终端CtrlAltT使用lsblk或sudo fdisk -l命令查看磁盘情况。sudo fdisk -l输出会类似这样Disk /dev/nvme0n1: 238.5 GiB, 256060514304 bytes ...这是你的旧盘假设为 /dev/nvme0n1 Disk /dev/nvme1n1: 931.5 GiB, 1000204886016 bytes ...这是你的新盘假设为 /dev/nvme1n1记下你的源盘和目标盘的设备标识符。非常重要接下来的所有操作都基于此切勿搞混。3.2 第二步在目标盘上创建分区结构我们需要在新盘上“复刻”旧盘的分区结构但可以调整大小。再次使用sudo fdisk -l /dev/nvme0n1仔细查看旧盘的分区布局。通常Ubuntu 20.04 UEFI安装会有/dev/nvme0n1p1: EFI系统分区 FAT32 大小约512MB。/dev/nvme0n1p2: 可能是/根分区 ext4 占用剩余大部分空间。可能有/dev/nvme0n1p3: 交换分区swap。现在我们对新盘/dev/nvme1n1进行分区。这里使用parted工具因为它对GPT分区表更友好。sudo parted /dev/nvme1n1在parted交互命令行中输入mklabel gpt创建GPT分区表。创建EFI分区mkpart ESP fat32 1MiB 513MiB set 1 esp on从1MiB开始是为了对齐513MiB结束得到一个约512MB的分区esp on标记其为EFI系统分区创建根分区mkpart primary ext4 513MiB 800GiB这里我直接将根分区设置为约800GB充分利用新盘空间如果需要创建交换分区假设分配16GBmkpart primary linux-swap 800GiB 816GiB输入print检查分区布局确认无误后输入quit退出。接下来格式化这些分区# 格式化EFI分区为FAT32 sudo mkfs.fat -F 32 /dev/nvme1n1p1 # 格式化根分区为ext4并添加一个标签可选方便识别 sudo mkfs.ext4 -L ubuntu-root /dev/nvme1n1p2 # 如果需要格式化交换分区并启用 sudo mkswap /dev/nvme1n1p3 sudo swapon /dev/nvme1n1p33.3 第三步挂载分区并使用rsync同步数据现在我们将新旧盘的分区分别挂载到Live系统的一个临时目录下。# 创建挂载点 sudo mkdir -p /mnt/oldroot /mnt/newroot sudo mkdir -p /mnt/newroot/boot/efi # 为新盘的EFI分区创建挂载点 # 挂载旧盘的根分区和新盘的根分区 sudo mount /dev/nvme0n1p2 /mnt/oldroot sudo mount /dev/nvme1n1p2 /mnt/newroot # 挂载旧盘的EFI分区通常挂载在/boot/efi下 sudo mount /dev/nvme0n1p1 /mnt/oldroot/boot/efi # 挂载新盘的EFI分区 sudo mount /dev/nvme1n1p1 /mnt/newroot/boot/efi关键步骤使用rsync同步数据。-aAXv参数组合是黄金标准-a: 归档模式保留权限、所有权、时间戳等所有属性。-A: 保留ACL访问控制列表。-X: 保留扩展属性。-v: 显示详细过程。加上--delete可以在目标端删除源端不存在的文件首次同步建议不加确保安全。强烈建议先进行干运行sudo rsync -aAXv --dry-run /mnt/oldroot/ /mnt/newroot/仔细检查输出列表确认同步内容符合预期没有奇怪的排除或包含。确认无误后开始真实同步sudo rsync -aAXv /mnt/oldroot/ /mnt/newroot/这个过程取决于数据量大小可能需要几十分钟到数小时。期间可以另开一个终端用df -h查看进度。3.4 第四步修复新系统的引导与配置数据复制完了但新硬盘现在还不能启动。因为系统内的配置文件主要是/etc/fstab和/boot/grub/grub.cfg仍然记录着旧硬盘分区的UUID。找出新分区的UUIDsudo blkid找到/dev/nvme1n1p1EFI和/dev/nvme1n1p2根分区对应的UUID并记录下来。更新新系统的/etc/fstab文件# 首先chroot到新系统环境这样我们修改的配置才会在重启后生效 sudo mount --bind /dev /mnt/newroot/dev sudo mount --bind /proc /mnt/newroot/proc sudo mount --bind /sys /mnt/newroot/sys sudo chroot /mnt/newroot # 现在我们在新系统的根环境下了更新fstab nano /etc/fstab将文件中旧的EFI分区和根分区的UUID替换为刚才用blkid查到的新分区的UUID。保存退出。重新安装并配置GRUB引导 仍在chroot环境下执行# 安装grub到新硬盘的EFI分区 grub-install --targetx86_64-efi --efi-directory/boot/efi --bootloader-idubuntu # 更新grub配置使其能识别新环境下的内核 update-grub如果一切顺利你会看到grub-install报告安装成功update-grub会扫描到你的内核。退出chroot并卸载所有分区exit # 退出chroot环境 sudo umount -R /mnt/newroot # 递归卸载新盘挂载点 sudo umount -R /mnt/oldroot # 卸载旧盘现在可以关机了。4. 首次启动验证与常见问题排错最激动人心也最紧张的时刻到了拔掉旧硬盘和Live USB只连接新硬盘开机。理想情况系统顺利进入GRUB菜单选择Ubuntu后正常启动登录桌面。使用df -h查看根分区已经是你设定的大小如800GB。恭喜迁移成功但现实往往骨感以下是可能遇到的问题及排查思路4.1 问题一黑屏直接进入BIOS/UEFI设置界面这表示主板没有找到可启动的设备。排查进入BIOS/UEFI检查启动顺序确认新硬盘显示为“ubuntu”或你设置的Bootloader ID在启动列表中。如果没有说明GRUB安装可能失败。解决重新进入Live USB挂载新盘的分区再次chroot进去仔细检查grub-install命令的参数是否正确特别是--efi-directory是否指向了正确的EFI分区挂载点/boot/efi。可以尝试使用efibootmgr命令手动在UEFI中创建启动项。4.2 问题二进入GRUB救援模式grub rescue这通常意味着GRUB找不到它的核心模块或配置文件。排查GRUB的安装位置可能有问题或者/boot/grub目录下的文件不完整。解决同样需要从Live USB启动chroot后重新执行grub-install和update-grub。确保在chroot前已经正确绑定了/dev,/proc,/sys并且/boot/efi已挂载。4.3 问题三系统启动后卡在某个服务如A start job is running for /dev/disk/by-uuid/...这几乎可以肯定是/etc/fstab文件中的UUID配置错误。系统在根据fstab挂载必要的分区时找不到对应的设备。排查在启动时在GRUB菜单按e键编辑启动参数在linux那一行的末尾添加rw init/bin/bash然后按CtrlX启动。这会让你进入一个单用户的bash shell且根文件系统以读写方式挂载。解决在这个shell里用blkid再次确认新硬盘分区的UUID然后用nano /etc/fstab修正错误的UUID。保存后执行exec /sbin/init继续正常启动或者reboot重启。4.4 问题四启动后根分区容量没变还是旧盘的大小这说明你虽然复制了数据但系统可能仍然从旧盘启动了如果旧盘还在的话或者你忘记更新/etc/fstab中根分区的UUID导致系统实际挂载的仍然是旧分区如果UUID巧合相同或你用了/dev/sdX设备路径而设备名在拔掉旧盘后发生了变化。排查在终端执行lsblk和df -h查看根文件系统实际挂载的是哪个设备。再检查/etc/fstab中的配置。解决确保/etc/fstab中使用的是新根分区的UUID。如果旧盘还在建议在BIOS中调整启动顺序或者物理上断开旧盘避免混淆。5. 迁移后的收尾工作与性能调优当新系统稳定运行后还有一些收尾和优化工作可以做更新initramfs虽然update-grub通常会处理但为了确保所有内核模块都针对新环境更新可以手动运行sudo update-initramfs -u -k all检查并安装硬件驱动如果新旧硬盘型号品牌差异大特别是从SATA SSD换到NVMe SSD可以检查一下NVMe驱动是否是最优的。sudo apt update sudo apt install --reinstall linux-generic-hwe-20.04针对NVMe硬盘的优化如果迁移到了NVMe硬盘启用TRIM对于固态硬盘定期TRIM有助于维持性能。ext4文件系统默认在discard挂载选项下支持在线TRIM但更推荐使用fstrim定期执行。# 检查是否支持discard sudo tune2fs -l /dev/nvme1n1p2 | grep discard # 启用周期性trim每周一次 sudo systemctl enable fstrim.timer调整I/O调度器对于NVMe这类高速设备将I/O调度器设置为none即noop可以减少内核层面的调度开销。# 临时生效 echo none | sudo tee /sys/block/nvme1n1/queue/scheduler # 永久生效编辑/etc/default/grub在GRUB_CMDLINE_LINUX_DEFAULT中添加 # elevatornone sudo nano /etc/default/grub sudo update-grub重新生成SSH主机密钥可选但推荐如果你的机器提供SSH服务迁移后主机指纹没变但从安全角度为新系统生成新的密钥是个好习惯。sudo rm /etc/ssh/ssh_host_* sudo dpkg-reconfigure openssh-server验证关键服务逐一检查你的开发环境如Docker, MySQL, Nginx, Redis等是否都正常运行配置文件路径是否因分区变化而需要调整通常不会因为文件路径没变。6. 关于“dd”方案的补充说明与风险管控尽管我选择了rsync方案但dd因其“简单彻底”的特性依然有很多拥趸。如果你坚持使用dd请务必遵循以下安全准则三重确认设备标识符使用lsblk、fdisk -l甚至通过硬盘型号、容量反复确认/dev/sda和/dev/sdb哪个是源哪个是目标。一个有用的技巧是先拔掉目标盘启动系统看哪个盘不见了那就是目标盘。使用convnoerror,sync参数sudo dd if/dev/nvme0n1 of/dev/nvme1n1 bs4M statusprogress convnoerror,sync。noerror表示遇到读错误继续sync用NULL填充错误块防止数据错位。务必先处理目标盘容量dd完成后目标盘只有源盘大小的有效空间。你需要用gparted工具启动手动将最后一个分区通常是根分区向右拖拽以占用后面未分配的空间。扩展分区后必须扩展文件系统# 假设扩展的是 /dev/nvme1n1p2 分区 sudo resize2fs /dev/nvme1n1p2dd后的引导修复因为UUID完全一样/etc/fstab通常不用改。但有时GRUB可能仍需重新安装到新硬盘的MBR或EFI分区。建议在dd完成后还是用Live USB启动chroot到新盘运行一遍grub-install和update-grub确保万无一失。最后也是最重要的忠告无论选择哪种方案在开始之前请务必、务必、务必对源硬盘上的重要数据进行完整的、可验证的备份。最好备份到另一块物理硬盘或网络存储上。迁移操作是对磁盘底层的直接操作任何误操作都可能导致数据丢失。当你反复核对命令按下回车键的那一刻你应该对即将发生的一切了如指掌。我的这次迁移花了大约4个小时其中3个半小时是在规划、验证和准备真正的数据复制和配置只用了不到半小时。这种时间分配恰恰是这类系统级操作能够平稳成功的关键。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价