自从2022年把开发环境迁移到linux,目前已经在公司用了4年的·linux了。目前来说,除了企业微信以外,所有应用都有官方或民间的Linux原生解决方案(包括使用electron也算)。但是目前遇到了一个新的问题,随着数据越堆越多,开发机的硬盘开始捉襟见肘。
文件系统 大小 已用 可用 已用% 挂载点
/dev/nvme0n1p2 1.8T 1.2T 523G 70% /
这时开始后悔当时装系统的时候没有把系统装在lvm上,不然再买一块硬盘插上就行了。那么不如干脆把系统迁到lvm上算了。并且同时为了以后更换硬盘方便,还可以将ESP分区使用mdadm创建一个RAID1,以后每块盘上都放一个ESP分区,再更换硬盘也就不需要考虑ESP分区在哪的问题了。倒不是为了硬盘坏了还能继续,毕竟后面数据分区是LVM条带,硬盘坏了还留个ESP也没什么用。
所以大致的计划如下
- 插块足够大的新硬盘
- 先创建一个和原先ESP分区一样大的分区保留
- 再创建一个LVM分区,并且初始化lvm
- 使用livecd将原先的/分区内容,复制进新的lvm分区
- 将原先的ESP分区复制到新的ESP分区,并且修改ESP分区使用lvm引导
- 给ESP分区上RAID1
- 抹掉旧的/分区,纳入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
就可以享受你的新系统了