使用dd进行系统备份,关联 分区,os,diskgenius, 7za, bzip2, bunzip2, xz, nvme, lba

系统迁移实战

  1. 备份各个系统分区
    使用dd对系统分区进行备份,包括win10,linux的分区
    使用 diskgenius 对 windows 分区进行下备份,生成 pmf 文件

    注意

    1. 备份的时候将分区信息一定记录一下:分区的精确大小、原来磁盘的扇区大小(sector size),总扇区数目
    2. 将 EFS,MSR分区大小也记录下
    1
    2
     # 备份分区到镜像文件,并用 7za 压缩
     dd if=/dev/sda1 bs=1M conv=sync,noerror status=progress | 7za a -si -t7z -mx=1 -m0=LZMA2 -mmt=8  /path/to/backup.img.7z
    
  2. 使用 diskgenius 在新的硬盘上
    1. 使用GUID磁盘引导区格式
    2. 先创建一样大小的 EFS,MSR分区
    3. 检查 扇区大小 是否和原来磁盘一样,一般2种(512字节、4K字节)
  3. 如果扇区大小 和原来磁盘 不一样,进入linux系统修改下
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     # manjaro 为例
     sudo pacman -S nvme-cli
    
     # 查看 目标硬盘的特性,关注其中 LBA Format 有几种模式
     nvme id-ns -H /dev/nvmeXnY
     # 上述命令,以pm983a为例,支持2中LBA
     ... ...
     LBA Format 0: Metadata Size: 0 bytes - Data Size: 4096 bytes (in use)
     LBA Format 1: Metadata Size: 0 bytes - Data Size: 512 bytes 
    
     # 我要将 sector size 从 4K 改成 512
     nvme format --lbaf=1 /dev/nvmeXnY
    

    题外话,从 4K 改成 512,没觉得速度有下降,可能pm983a的写速度 1.1G/s 本来就弱鸡

  4. 恢复数据到系统分区
    使用 dd,如果不行也可以用 diskgenius 把之前备份 pmf 拿来试试
    1
    2
     # 从镜像文件恢复
     7za x /path/to/backup.img.7z -so | dd of=/dev/sda1 status=progress
    
  5. 然后,开始重建系统的启动引导啦,就是弄那个 EFS 分区

  6. 首先搞 Windows
    1. Windows 10 系统安装盘引导进入系统 ,语言选择界面,点“下一步”
      使用MBR的系统安装盘才能正确引导,rufus做的UEFI的引导盘进不去,启动蓝屏报错。
    2. 选择“修复计算机” 》疑难解答 》命令提示符
    3. 命令行修复引导记录
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
       Diskpart   【启动Diskpart工具】
       list disk 【找出启动磁盘的序号】
       sel disk 0 【选择启动磁盘,按各个机器情况写数字】
       list vol 【找出EFI分区序号,FAT32格式,一二百兆大小都正常】
       sel vol 3【选择EFI分区,按各个机器情况写数字】
       assign letter=v:【把EFI分区设定为v盘】
       exit【退出disk part命令集】
      
       format v: /FS:FAT32 【以FAT32格式化v盘,即EFI分区】
       bcdboot c:\windows /s v: /f UEFI 【修复bcd引导记录】 
      

      至此重启,顺利回到原来的系统
      最后一条命令只适用于1709以后版本win10的ISO启动盘

  7. 然后恢复linux系统启动
    1. lsblk -f 找到 linux 的分区
      例如,我的 linux 分区是 /dev/nvme0n1p9 efi 分区是 /dev/nvme0n1p2
    2. 手动chroot
      1
      2
      3
      4
      5
      6
      7
      8
       sudo mount /dev/nvme0n1p9 /mnt
       sudo mount /dev/nvme0n1p2 /mnt/boot/efi
       cd /mnt
       sudo mount -t proc proc /mnt/proc
       sudo mount -t sysfs sys /mnt/sys
       sudo mount -o bind /dev /mnt/dev
       sudo mount -t devpts pts /mnt/dev/pts/
       sudo chroot /mnt
      
    3. 执行grub命令修复
      • manjaro恢复
        1
        2
          grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=manjaro --recheck -v
          update-grub
        
      • ubuntu 系列distro 恢复
        1
        2
        3
          grub-install /dev/sdX
          grub-install --recheck /dev/sdX
          update-grub
        
    4. 最后记得修改下 fstab 里面 EFI 分区UUID,因为EFI分区是新建的,和原来的UUID不一样

dd 备份

dd 备份分区

  • 备份整个分区
    这个简单,直接执行
    1
    2
    # 1048576 个字节 = 1M
    sudo dd if=/dev/sda of=/where-your-store/target-os.img bs=1048576 conv=sync,noerror status=progress
    
  • 备份分区中有数据的部分

    • 注意 count=?M 参数使用 df -BM 显示出来的值是不对的,偏小,比如:
      在nvme的硬盘 /dev/nvme0n1 上一个 100G 的分区:
      • sudo fdisk -l /dev/nvme0n1 分区大小 209715200 个sector(一个sector 512字节,也就是 100G)
      • df -B512 查看分区,数据是 205376064,也即 205376064 / 2 / 1024 = 100281.28125M
      • 相差将近 2118M
  1. 加载这个分区,df -BM 查看数据使用

    例如: 一个100G的分区,/dev/nvme0n1p8

    1
    2
    3
    4
     $ df -BM /dev/nvme0n1p8
    
     Filesystem     1M-blocks   Used Available Use% Mounted on
     /dev/nvme0n1p8   100282M 15650M    79497M  17% /
    
  2. COUNT-VAL = 分区大小 - 1M-blocks + Used + 几个G的旷量
    例如,上面 100G分区,COUNT-VAL = 102400M - 100282M + 15650M + 2000M旷量 = 19768M
  3. 备份: sudo dd if=/dev/sda of=/where-your-store/target-os.img bs=1048576 count=19768 conv=sync,noerror status=progress

dd 配合压缩工具备份

直接 dd 出来 image 文件进行压缩节约的空间还是很客观的,15G能压缩到7G。 所以一般配合压缩工具一起进行备份。

manjaro 默认有7zip 和 bzip2 。 推荐使用7zip,速度快很多,100+M/s,而bzip2只有 20-30M/s。

7zip + dd

1
2
3
4
5
# 备份分区到镜像文件,并用 7za 压缩
dd if=/dev/sda1 bs=1048576 conv=sync,noerror status=progress | 7za a -si -t7z -mx=1 -m0=LZMA2 -mmt=8  /path/to/backup.img.7z

# 从镜像文件恢复
7za x /path/to/backup.img.7z -so | dd of=/dev/sda1 status=progress

bzip2 + dd

1
2
3
4
5
# backup
dd if=/dev/nvme0n1p8 bs=1M conv=sync,noerror status=progress | bzip2 -9f > /Volumes/silo/_backups/os.dd/manjaro.img.bz2

# restore
bunzip2 -dc /path/to/backup.img.bz2 | dd of=/dev/sda1 status=progress

xz + dd

1
2
3
4
5
# backup
dd if=/dev/disk2s1 bs=1048576 conv=sync,noerror | pv -s 30271m |  xz -z -3ve --threads=0 > /Volumes/Lexar/t5w10_1803.img_30271m.xz

# restore
xz -dc --threads=0 /Volumes/Lexar/t5w10_1803.img.xz | pv | dd of=/dev/disk2s1

gzip + dd

1
2
3
4
5
# 备份分区到镜像文件,并用 gzip 压缩
dd if=/dev/sdb1 bs=64M conv=sync,noerror status=progress | gzip -c > /path/to/backup.img.gz

# 从镜像文件恢复
gunzip -c /path/to/backup.img.gz | sudo dd of=/dev/sdb1 status=progress