一个计算机技术爱好者与学习者

0%

好好学Linux:Linux中拷贝硬盘

1. 需求描述

Linux主机中原本有一块数据盘 /dev/sdb,挂载到了 /data 目录,存储了大量数据。
现在新增了一块数据盘 /dev/sdc,想要把sdb的数据完全拷贝到sdc,然后用sdb替换sdc,这个需求该怎样处理?

2. 实现思路

1、把sdb的数据拷贝到sdc
2、检查sdc数据
3、修改挂载配置,sdc替换sdb,重启主机

3. 拷贝硬盘全部数据

3.1. 拷贝硬盘全部数据概述

拷贝硬盘全部数据,有三种方法:

  • 使用cp命令。不推荐,因为cp不能断点续传,所以拷贝大量文件时如果出错会浪费时间重传。
  • 使用rsync命令。备选,支持断点续传,但是如果存在大量小文件时拷贝速度会很慢。
  • 使用dd命令。首选,拷贝整个磁盘的数据,速度非常快且数据完整。

因此,这里选择使用dd命令来拷贝磁盘数据。

3.2. dd命令拷贝数据

1
dd if=/dev/sdb of=/dev/sdc bs=64K conv=noerror,sync

参数说明:

  • if:input file,输入文件,这里就是要复制的源盘/dev/sdb。
  • of:output file,输出文件,这里就是要复制的目标盘/dev/sdc。
  • bs:block size,块大小,这里我们设置为64K。
  • conv:convert,转换选项,这里我们设置为noerror(读写出错不停止)和sync(输入输出不足块大小时,会用空字符补足)。

dd命令默认的块大小是512字节,这意味着默认情况下,dd命令每次读取和写入的数据大小是512字节。如果我们的磁盘支持更大的块大小,那么增加块大小可以帮助提高数据复制的速度。在这个例子中,我们设定块大小为64K,这意味着dd命令每次读取和写入的数据大小是64K字节。

注意:在执行这个命令之前,确保/dev/sdc 没有被挂载并且没有其他程序正在使用。此外,这个操作可能会需要一些时间,需要耐心等待。

3.3. 查看dd进度

dd命令在复制数据完成后会自动结束。有时候,dd命令可能会运行非常长的时间,此时可以通过向dd命令发送SIGUSR1信号来查看它当前的进度。

1
kill -USR1 $(pgrep ^dd)

这条命令会找到dd命令的进程ID并向其发送SIGUSR1信号,这将导致dd命令打印出其当前的复制进度。

输出内容类似于:

1
2
3
6525616+0 records in
6525616+0 records out
427662770176 bytes (428 GB) copied, 3034.84 s, 141 MB/s

这个输出中,6525616 指的是已经复制的块数量,块大小为64K(默认512),6525616*64*1024 = 427662770176

3.4. dd断点续传

dd命令本身并不支持断点续传。如果执行 dd 命令过程中出现了中断,那么重新执行dd命令会从头开始复制,比较浪费时间。
但是,我们可以使用一些参数来模拟断点续传的功能。
skip 参数可以让 dd 在复制数据前跳过源文件/设备的一定数量的块,seek 参数可以让 dd 在开始写入数据前跳过目标文件/设备的一定数量的块。

假设我们确认已知的dd进度为:

1
2
3
6525616+0 records in
6525616+0 records out
427662770176 bytes (428 GB) copied, 3034.84 s, 141 MB/s

那么,断点续传可以使用如下命令:

1
dd if=/dev/sdb of=/dev/sdc bs=64K skip=6525616 seek=6525616 conv=noerror,sync

3.5. 修改UUID

使用dd拷贝一个设备到另一个设备,那么设备的UUID也被同时复制过去。这将导致两个设备拥有相同的UUID,这样在一些情况下可能会引发问题,比如在/boot/grub/grub.cfg文件或者/etc/fstab里面用UUID来标识设备。

要修改一个文件系统的UUID,需要使用对应文件系统的工具。

查看UUID命令:

1
blkid /dev/sdc

对于ext2,ext3,ext4文件系统,可以使用tune2fs命令,例如:

1
tune2fs -U random /dev/sdc

对于xfs文件系统,可以使用xfs_admin命令,例如:

1
xfs_admin -U generate /dev/sdc

对于btrfs文件系统,可以使用btrfstune命令,例如:

1
btrfstune -f -u /dev/sdc

注意:上述所有命令在执行之前,需要先确保该设备已经被卸载。

3.6. 修改UUID报错问题

1、执行修改UUID的命令:

1
xfs_admin -U generate /dev/sdc

报错:

1
2
3
4
5
6
ERROR: The filesystem has valuable metadata changes in a log which needs to
be replayed. Mount the filesystem to replay the log, and unmount it before
re-running xfs_admin. If you are unable to mount the filesystem, then use
the xfs_repair -L option to destroy the log and attempt a repair.
Note that destroying the log may cause corruption -- please attempt a mount
of the filesystem before doing this.

2、根据报错提示挂载磁盘,然后卸载磁盘。

1
2
mkdir /sdc
mount /dev/sdc /sdc

报错:

1
2
3
4
5
mount: wrong fs type, bad option, bad superblock on /dev/sdc,
missing codepage or helper program, or other error

In some cases useful info is found in syslog - try
dmesg | tail or so.

3、尝试修复磁盘问题

1
xfs_repair -L /dev/sdc

输出:

1
2
3
4
5
6
7
8
Phase 1 - find and verify superblock...
Phase 2 - using internal log
- zero log...
...
Phase 7 - verify and correct link counts...
Maximum metadata LSN (12:673358) is ahead of log (1:2).
Format log to cycle 15.
done

4、再次尝试修改UUID

1
xfs_admin -U generate /dev/sdc

输出:

1
2
3
Clearing log and setting UUID
writing all SBs
new UUID = 25b43fed-781f-419e-b5a9-273042c7f1e1

5、尝试挂载和卸载

1
2
3
mount /dev/sdc /sdc
ls -l /sdc
umount /sdc

4. 检查sdc数据(可选)

1、挂载 sdc

1
2
mkdir /sdc
mount /dev/sdc /sdc

2、比较数据

1
rsync -P -avz /data/ /sdc

5. 修改挂载配置

1、查看 sdc UUID

1
blkid /dev/sdc

2、修改 /etc/fstab 配置

1
UUID=xxx /data xfs  defaults 0 0

其中 xxx 修改为 sdc 的 UUID

3、重启主机

1
reboot
  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-linux-copy-disk/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~