avatar
@bangbang93

将裸硬盘安装的linux迁移到lvm,并且给ESP分区上一个RAID1

2/8/2026, 10:52:25 AM

自从2022年把开发环境迁移到linux,目前已经在公司用了4年的·linux了。目前来说,除了企业微信以外,所有应用都有官方或民间的Linux原生解决方案(包括使用electron也算)。但是目前遇到了一个新的问题,随着数据越堆越多,开发机的硬盘开始捉襟见肘。

文件系统        大小  已用  可用 已用% 挂载点
/dev/nvme0n1p2  1.8T  1.2T  523G   70% /

这时开始后悔当时装系统的时候没有把系统装在lvm上,不然再买一块硬盘插上就行了。那么不如干脆把系统迁到lvm上算了。并且同时为了以后更换硬盘方便,还可以将ESP分区使用mdadm创建一个RAID1,以后每块盘上都放一个ESP分区,再更换硬盘也就不需要考虑ESP分区在哪的问题了。倒不是为了硬盘坏了还能继续,毕竟后面数据分区是LVM条带,硬盘坏了还留个ESP也没什么用。
所以大致的计划如下

  1. 插块足够大的新硬盘
  2. 先创建一个和原先ESP分区一样大的分区保留
  3. 再创建一个LVM分区,并且初始化lvm
  4. 使用livecd将原先的/分区内容,复制进新的lvm分区
  5. 将原先的ESP分区复制到新的ESP分区,并且修改ESP分区使用lvm引导
  6. 给ESP分区上RAID1
  7. 抹掉旧的/分区,纳入LVM

大致就是这样,在第6步之前对原硬盘都是只读的,如果挂了很方便回退。

0x01 插硬盘

0x02,0x03 创建新的分区表

此步骤可以在原系统内操作,也可以先进到livecd内操作

首先fdisk -l /dev/nvme0n1确认一下efi分区大小,照着原来的分区表创出EFI分区和LVM分区。

  • 创建GPT分区表:g。
  • 创建EFI分区(复制原结构):n,分区号1,大小照着抄,类型EFI System(命令t后选择1)。
  • 创建剩余分区用于LVM:n,使用剩余空间,类型Linux。
  • 写入:w。

注意EFI分区需要使用FAT32,即mkfs.fat /dev/nvme1n1p1
然后对着第二个分区创建lvm

pvcreate /dev/nvme1n1p2
vgcreate vg0 /dev/nvmen1p2
lvcreate vg0 root

此时lvs应该就有新的分区信息了

0x04 迁移数据

从这里开始,就必须在livecd下操作了。

挂载新旧分区

mkdir -p /mnt/old/boot/efi
mkdir -p /mnt/new/boot/efi
mount /dev/nvme0n1p2 /mnt/old
mount /dev/vg0/root /mnt/new
mount /dev/nvme0n1p1 /mnt/old/root/efi
mount /dev/nvme1n1p1 /mnt/new/root/efi

此时/mnt/old/mnt/new就分别是旧的和新的root了
然后复制所有文件

rsync -aAXP /mnt/old /mnt/new

复制完成后,所有文件以及对应权限应该都会被保留复制

0x05 迁移引导

首先查看一下新分区的UUID

lsblk -fs

修改新的fstab,即/mnt/new/etc/fstab,将其根分区和ESP分区的挂载信息,替换为新的UUID

给新的root分区挂载一些硬件设备

mount --bind /dev /mnt/new/dev
mount --bind /sys /mnt/new/sys
mount --bind /proc /mnt/new/proc

然后chroot进新的根

chroot /mnt/new

此时根据系统的不同,后续操作会有些不一样,比如debian使用的是update-initramfs -u -k all,来更新initramfs。而Arch系使用的是mkinitcpio命令,就需要先去/etc/mkinitcpio.conf,给HOOKS增加lvm2,然后使用mkinitcpio -P才能更新initramfs,并且添加lvm的支持。
最后殊途同归,大家肯定都是grub

update-grub
grub-install

此时新的硬盘应该就可以准备引导了,可以重启试试,记得手动选择一下引导设备,不然有可能引导进旧的环境。

0x06 ESP RAID

重启后,使用各种手段确保引导的是新系统(其实只要看一下根分区是不是lvm就行了)。
从这里开始,会对旧硬盘产生写操作,就没有回头路了,所以一定要确认清楚

首先使用旧硬盘的ESP分区创建一个降级的raid1

mdadm --create /dev/md100 --level 1 --raid-disks 2 --metadata 1.0 /dev/nvme0n1p1 missing

注意使用metadata 1.0很重要,因为metadata 1.0是将superblock放到卷末尾的,ESP分区本身是要被UEFI读取的,如果superblock在前面的话UEFI就不认了。
然后给这个新的分区创建文件系统

mkfs.fat /dev/md100

复制目前ESP分区的内容

mkdir /mnt/esp
mount /dev/md100 /mnt/esp
rsync -avP /boot/efi/ /mnt/esp

因为ESP分区是个fat32,所以不存在各种权限问题
然后临时卸载现在的esp分区,并且将其加入md100

umount /dev/nvme1n1p1
mdadm --manage /dev/md100 --add /dev/nvme1n1p1

查看一下新ESP分区的UUID

lsblk -fs

编辑/etc/fstab,更新/boot/efi挂载分区的UUID
更新initramfs

update-initramfs -u -k all

或者

mkinitcpio -P

确认一下RAID已经同步完成

cat /proc/mdstat

ESP分区不会很大,理论上应该早就同步完成了

md100 : active raid1 nvme0n1p1[2] nvme1n1p1[0]
      614400 blocks super 1.0 [2/2] [UU]

然后重启试试,看看还能不能进系统。如果进不了,就要用急救模式或者live cd重建ESP和initramfs了

0x07 将旧硬盘加入LVM

剩下的就简单了,按照LVM正常扩容一把梭

pvcreate /dev/nvme0n1p2
vgextend vg0 /dev/nvme0n1p2
lvextend -r -l +100%FREE /dev/vg0/root

就可以享受你的新系统了


参考资料:
https://std.rocks/gnulinux_mdadm_uefi.html