V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
monetto
V2EX  ›  Linux

备份 Ext4 分区的正确姿势

  •  
  •   monetto · 2022-07-27 15:13:01 +08:00 · 6444 次点击
    这是一个创建于 880 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,有一个 Ubuntu 系统的 U 盘,想要做全盘备份,但是看了下 Diskgenius 全盘备份功能必须 付费版才能使用。

    由于 U 盘比较大( 256G ),无法使用 dd 命令进行备份(也需要 256G 空间以供备份)

    求大佬,大容量 Ext4 分区备份的正确姿势是什么

    第 1 条附言  ·  2022-09-06 10:45:00 +08:00
    最后结论吧,如果不是全盘备份,推荐直接用 Diskgenius ,免费版就可以使用 单分区备份 ... 主要是可见,踏实 ...
    72 条回复    2023-08-21 10:23:50 +08:00
    wzhpro
        1
    wzhpro  
       2022-07-27 15:17:11 +08:00
    rsync ?
    tril
        2
    tril  
       2022-07-27 15:20:01 +08:00
    dd 的同时压缩? dd if=xxx | gzip > /aaa/bbb/xxx.gz
    ashong
        3
    ashong  
       2022-07-27 15:21:13 +08:00 via iPhone
    clonezilla disk-image 方式
    yfugibr
        4
    yfugibr  
       2022-07-27 15:22:03 +08:00
    `dd if=/dev/sda | gzip > sda.img` ?
    liyafe1997
        5
    liyafe1997  
       2022-07-27 15:29:53 +08:00 via Android
    dd 加 gzip 是个不错的选择
    zx900930
        6
    zx900930  
       2022-07-27 15:45:23 +08:00
    这时候就要提虚拟化的好处了, 直接备份.qcow2 虚拟磁盘+zstd 压缩
    codehz
        7
    codehz  
       2022-07-27 15:58:06 +08:00   ❤️ 2
    所以为啥楼上非得加 dd ,直接 gzip -c /dev/sda1 > xxx.tar.gz 不就好了(
    此外 ext4 并没有奇怪的特性导致需要真的全盘备份才能保持,所以可以按文件备份,直接 tar gz 的形式就不错
    但是 tar 格式本身其实不太友好——特别是没法随机访问文件,所以可以换个文件系统,例如 squashfs (但是这个压缩比较慢),或者比较新且性能不错的 https://github.com/mhx/dwarfs 这类
    seers
        8
    seers  
       2022-07-27 15:58:32 +08:00 via Android
    自己找偏移然后 dd (
    HarveyLiu
        9
    HarveyLiu  
       2022-07-27 16:14:28 +08:00
    台湾:Clonezilla(再生龙)
    shijingshijing
        10
    shijingshijing  
       2022-07-27 16:21:40 +08:00
    @codehz 7# gzip 可能会碰到权限的问题吧,dd 我不知道,上面说的 clonezilla 以 Live 启动盘的方式挂载 /dev/sda1 是绝对可以实现楼主想要的。
    codehz
        11
    codehz  
       2022-07-27 16:26:51 +08:00
    @shijingshijing dd 又不会自动提权,gzip 也不会自己降低权限( dd 的这个用法根本毫无价值)
    hahasong
        12
    hahasong  
       2022-07-27 16:41:51 +08:00
    进 PE ghost
    pagxir
        13
    pagxir  
       2022-07-27 16:46:53 +08:00 via Android   ❤️ 2
    @codehz 你觉得毫无价值,那是因为你对 IO 理解的不够。磁盘是低速设备,而 gzip 是 CPU 密集操作,直接操作块设备就会直接绕过文件系统的预读功能,所以在 gzip 跟磁盘之间引入 dd 可以间接引入预读,减少 gzip 读盘的等待时间。
    codehz
        14
    codehz  
       2022-07-27 17:06:53 +08:00
    @pagxir 谁和你说 dd 会增加缓存的??相反,你必须在 dd 中指定 iflag=direct 才可以“绕过”页面缓存(同时 bypass 预读),而多数程序实现的读取都不会用 direct io (因为很多文件系统根本不支持,加上通常只会减速,只有数据库这种特殊用例才会主动开选项去用 direct io ,普通程序自然也不会无故增加这种无聊的选项)
    而且,如果你不加任何选项,dd 会使用非常小的块作为单位( 512 字节)进行读取,这显然多数情况都不是最优解(虽然影响也不是很大,只是会增加系统调用频率)
    pagxir
        15
    pagxir  
       2022-07-27 17:11:18 +08:00 via Android
    @codehz 谁跟你说 dd 啥参数都不戴了。这场景下,你操作的是裸设备不存在预读一说。这就是 bs=16k 跟 bs=16M 速度可以差很远的原因。
    codehz
        16
    codehz  
       2022-07-27 17:20:08 +08:00
    @pagxir 楼上不是都没参数的吗?我说 “这个用法” 有错吗?
    此外块设备怎么就没预读了,你是不是自己运行了 blockdev --setra 0 /dev/sda 然后忘记了?
    codehz
        17
    codehz  
       2022-07-27 17:26:58 +08:00
    @pagxir 哦,想起来了,你是在混淆裸设备和块设备,但是这里备份的是块设备,特别考虑的分区的话肯定不能是裸的)
    neutrinos
        18
    neutrinos  
       2022-07-27 17:27:27 +08:00 via iPhone
    @zx900930 sudo -Q /dev/sda1 - | gzip -c sda1.qcow2.gz
    pagxir
        19
    pagxir  
       2022-07-27 17:29:01 +08:00 via Android
    你说他们这个没有参数的用法等价于直接直接 gzip -c /dev/block ,确实是这样。但是你说引入 dd 没有意义我不赞同,基本上很少有人不带参数的直接使用 dd 。印象中,不是所有的硬件都支持硬件预取的,一般也不会去调整它。
    neutrinos
        20
    neutrinos  
       2022-07-27 17:29:14 +08:00 via iPhone
    @neutrinos 好像不包含 data block ,没试过
    pagxir
        21
    pagxir  
       2022-07-27 17:36:16 +08:00 via Android
    @codehz 预取是文件系统提供的功能,甚至 page cache 都是跟文件系统挂钩的。没有 mount 文件系统的磁盘就是裸设备。没人会在 mount 分区可写下去做这种全盘备份吧,内核可没有义务保证这种情况下的一致性。
    ToughGuy
        22
    ToughGuy  
       2022-07-27 17:51:22 +08:00
    tar -czvpf /full-backup.tar.gz --exclude=/full-backup.tar.gz --exclude=/dev --exclude=/sys --exclude=/proc --exclude=/run /
    codehz
        23
    codehz  
       2022-07-27 17:54:33 +08:00 via iPhone
    @pagxir (建议复习 linux 基本知识,块设备和裸设备不是一个概念,而且磁盘必然是块设备,裸设备(实际属于字符设备)要手动绑定到块设备上才可以使用(裸设备和分区与否没有任何关系,如果有,一定是有人把 raw disk 翻译成裸设备了)可以参考部分发行版提供的 raw 命令的相关说明
    预读显然也是块设备提供的基本功能(不妨看下 blockdev 命令),还有 page cache 也是,你甚至可以直接对块设备进行 mmap 操作
    codehz
        24
    codehz  
       2022-07-27 18:00:49 +08:00 via iPhone   ❤️ 2
    codehz
        25
    codehz  
       2022-07-27 18:04:08 +08:00 via iPhone
    @pagxir 此外 5.14 内核已经彻底移除裸设备功能,有需要的只能通过 O_DIRECT 参数打开块设备
    https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git/commit/?h=char-misc-next&id=603e4922f1c81fc2ed3a87b4f91a8d3aafc7e093
    autoxbc
        26
    autoxbc  
       2022-07-27 18:49:03 +08:00
    Clonezilla 是个完整的备份解决方案,不过大多数情况可能只需要其核心 Partclone
    pagxir
        27
    pagxir  
       2022-07-27 19:31:38 +08:00 via Android
    @codehz 没有挂着的磁盘就是没有预读功能。你不信我也没办法
    pagxir
        28
    pagxir  
       2022-07-27 19:36:49 +08:00 via Android
    这里的裸本来就是特指裸,而你得把它变成专用名词
    duke807
        29
    duke807  
       2022-07-27 19:46:05 +08:00 via Android   ❤️ 1
    resize2fs 缩小后再 dd
    dd 时还可配合 gzip
    documentzhangx66
        30
    documentzhangx66  
       2022-07-27 19:52:20 +08:00
    @codehz

    1.gzip 是文件级别,而且还忽略了很多东西,比如磁盘格式、分区、权限,等等。

    2.使用 dd 也是无奈的选择,因为它会对所有 block 做备份与恢复,即使这些 block 并没有数据。

    3.目前最好的选择是 Symantec Ghost ,但它只支持 Windows ,而且早就停止更新了。它之所以好,是因为它把所有的东西都处理了,并且在备份、还原时,不会去处理没有数据的 block 。
    pagxir
        31
    pagxir  
       2022-07-27 20:06:57 +08:00 via Android
    @duke807 其实 fstrim 之后再压缩大小也差不多,就是有些磁盘不支持 trim
    codehz
        32
    codehz  
       2022-07-27 21:06:28 +08:00
    @documentzhangx66 很抱歉,dd 也只是单纯的用 open + read + seek + write 这四个 api 在做文件操作,除了 iflag 可以多指定一些打开参数之外,没有任何魔法 https://github.com/coreutils/coreutils/blob/master/src/dd.c 除了成片的参数解析代码之外,根本没有你所说的磁盘格式,分区,权限的处理(当然,还是有别的操作的,比如可以做编码转换,但是我相信你不会在备份的时候考虑这个吧),
    我相信你肯定会读代码的吧
    但是如果不会,可以考虑挂一个 strace 跟踪下到底运行了哪些系统调用,我这帮你列出来好了(除去周围 glibc 的调用,命令是 dd if=/dev/sda of=/tmp/x bs=512 count=1

    openat(AT_FDCWD, "/dev/sda", O_RDONLY) = 3
    dup2(3, 0) = 0
    close(3) = 0
    lseek(0, 0, SEEK_CUR) = 0
    openat(AT_FDCWD, "/tmp/x", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
    dup2(3, 1) = 1
    close(3) = 0
    read(0, "3\300\216\320\274\0|\216\300\216\330\276\0|\277\0\6\271\0\2\374\363\244Ph\34\6\313\373\271\4\0"..., 512) = 512
    write(1, "3\300\216\320\274\0|\216\300\216\330\276\0|\277\0\6\271\0\2\374\363\244Ph\34\6\313\373\271\4\0"..., 512) = 512
    close(0) = 0
    close(1) = 0

    你总不能说 dd 用了神奇的魔法,它既能在源代码中隐藏,也能在 strace 跟踪的时候消失,然后做你所说的那些操作吧)
    codehz
        33
    codehz  
       2022-07-27 21:58:50 +08:00
    @pagxir 要不你解释下 /sys/block/<块设备名字>/queue/read_ahead_kb 这个是放着干啥的(
    另外这有一份解释 VFS 和块设备的 ppt
    http://devarea.com/wp-content/uploads/2017/10/Linux-VFS-and-Block.pdf
    这是 linux readahead 实现的相关代码
    https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/readahead.c
    以及 backing-dev.c filemap.c 等文件里( filemap 和 filesystem 毫无关联),搜索 ra_pages 就可以找到不少相关实现
    除了同名系统调用的实现是在通知 vfs 之外(总不能让用户程序自己算文件在磁盘上的位置吧,所以这部分计算得委托给 vfs 实现),其他部分均与 vfs 无关,readahead 操作就是在块设备层面实现的
    你定义里的裸磁盘也就是块设备,当然也会用到这里的 readahead 能力
    zyq2280539
        34
    zyq2280539  
       2022-07-27 22:31:23 +08:00
    dd 备份不就完事儿了,备份完在压缩一下 img 文件就可以了,我就是这么用的,需要的时候找个大硬盘解压了重新写进去就完事儿了
    neutrinos
        35
    neutrinos  
       2022-07-27 23:43:22 +08:00 via iPhone
    @duke807 是 dd 后再 resize2fs 吧?
    fox0001
        36
    fox0001  
       2022-07-27 23:48:55 +08:00 via Android
    个人比较喜欢用 rsync ,生成镜像盘
    lirunext
        37
    lirunext  
       2022-07-27 23:55:49 +08:00
    如果只是想简单省事,用成熟的商业软件可能会是一个比较好的选择。Acronis True Image 这款软件操作简单,我试过可以备份 NTFS 的 Windows 和 APFS 的 macOS ,官方宣传支持的文件系统中也含有 Ext4 ,http://www.tieten.cn/acronis/personal/ATI2021/index.html
    wtks1
        38
    wtks1  
       2022-07-28 00:04:23 +08:00 via Android
    用再生龙试试,这个备份 linux 设备还是很好用的
    pagxir
        39
    pagxir  
       2022-07-28 00:29:01 +08:00 via Android
    @codehz 请你认真看文档说明
    read_ahead_kb (RW)
    Maximum number of kilobytes to read-ahead for filesystems on this block device.
    pagxir
        40
    pagxir  
       2022-07-28 00:35:40 +08:00 via Android
    预读是依赖于 page cache ,而没挂文件系统的 block device 压根就没有 page cache 。
    yjd
        41
    yjd  
       2022-07-28 00:51:09 +08:00
    专业软件 UFS Explorer Professional 备份成 VHD 是免费的。
    codehz
        42
    codehz  
       2022-07-28 01:58:27 +08:00   ❤️ 1
    @pagxir 我建议直接看源码
    https://github.com/torvalds/linux/blob/master/block/fops.c#L410-L422 给出了块设备的 readahead 的实现
    https://github.com/torvalds/linux/blob/master/mm/readahead.c#L157-L176 这个位置下断点,然后开 gdb 调试引导,执行命令 cat /dev/sda > /dev/null ,就可以发现确实用到了这里的 readahead
    调用栈是 blkdev_readahead | read_pages | page_cache_ra_unbounded | do_page_cache_ra | page_cache_async_ra | filemap_readahead | filemap_get_pages | filemap_read | blkdev_read_iter | call_read_iter | new_sync_read | vfs_read | ksys_read | do_syscall_x64 | do_syscall_64 | entry_SYSCALL_64
    每个函数的含义都可以自己查看,linux 没有魔法,不可能说源码里写了 page cache 还能不用的
    tril
        43
    tril  
       2022-07-28 04:52:46 +08:00
    @codehz 因为搜到的方法都是 dd+gzip ,说明用的人不少。没见过谁指出这方法有什么缺陷,说明它确实管用。既然能用而且又没问题,那就这样啦 XD
    mingl0280
        44
    mingl0280  
       2022-07-28 05:33:02 +08:00
    clonezilla 啊,clonezilla
    pagxir
        45
    pagxir  
       2022-07-28 07:50:00 +08:00 via Android
    @codehz 大概率你的盘已经挂了文件系统。不可能有 readahead 的。你可以试试看,第二次对 sda 读会变成对内存读了。
    bthulu
        46
    bthulu  
       2022-07-28 08:16:53 +08:00
    装一个百度云盘, 开会员, 打开自动备份文件夹就行了
    pagxir
        47
    pagxir  
       2022-07-28 08:31:50 +08:00
    $ time dd if=/dev/sdb bs=80M status=progress|dd ibs=8M obs=80M|lz4 -c | dd of=/dev/null bs=2M
    31611420672 字节 (32 GB, 29 GiB) 已复制,391 s ,80.9 MB/s
    输入了 376+1 块记录
    输出了 376+1 块记录
    31611420672 字节 (32 GB, 29 GiB) 已复制,391.608 s ,80.7 MB/s
    输入了 0+482352 块记录
    输出了 376+1 块记录
    31611420672 字节 (32 GB, 29 GiB) 已复制,391.695 s ,80.7 MB/s
    输入了 0+424343 块记录
    输出了 0+424343 块记录
    27642280069 字节 (28 GB, 26 GiB) 已复制,391.697 s ,70.6 MB/s

    real 6m31.704s
    user 0m27.970s
    sys 1m28.536s
    $ lz4 -c < /dev/sdb | dd of=/dev/null bs=2M status=progress
    27642280069 字节 (28 GB, 26 GiB) 已复制,465 s ,59.4 MB/s
    输入了 0+424180 块记录
    输出了 0+424180 块记录
    27642280069 字节 (28 GB, 26 GiB) 已复制,465.335 s ,59.4 MB/s

    没挂文件系统下的二次读:

    $ dd if=/dev/sdb of=/dev/null bs=2M count=1024
    输入了 1024+0 块记录
    输出了 1024+0 块记录
    2147483648 字节 (2.1 GB, 2.0 GiB) 已复制,27.1303 s ,79.2 MB/s
    $ dd if=/dev/sdb of=/dev/null bs=2M count=1024
    输入了 1024+0 块记录
    输出了 1024+0 块记录
    2147483648 字节 (2.1 GB, 2.0 GiB) 已复制,26.6422 s ,80.6 MB/s
    $ dd if=/dev/sdb of=/dev/null bs=2M count=100
    输入了 100+0 块记录
    输出了 100+0 块记录
    209715200 字节 (210 MB, 200 MiB) 已复制,2.85232 s ,73.5 MB/s

    挂文件系统下的二次读:
    $ dd if=/dev/sdb of=/dev/null bs=2M count=100
    输入了 100+0 块记录
    输出了 100+0 块记录
    209715200 字节 (210 MB, 200 MiB) 已复制,2.77269 s ,75.6 MB/s
    $ dd if=/dev/sdb of=/dev/null bs=2M count=100
    输入了 100+0 块记录
    输出了 100+0 块记录
    209715200 字节 (210 MB, 200 MiB) 已复制,0.0475682 s ,4.4 GB/s

    之前一直想搞某个功能,结果就是在这个地方搞不下去了。从这个数据结果看,我不认为 readahead 跟 page cache 生效了。至于你说的代码,我没看过。
    codehz
        48
    codehz  
       2022-07-28 09:23:10 +08:00 via iPhone
    @pagxir 完全没有文件系统,是临时创建全 0 的磁盘镜像,然后 shell 是从 initrd 里来的,也就是从头到尾就没有磁盘被挂载
    damenlysu
        49
    damenlysu  
       2022-07-28 09:29:57 +08:00
    read without dirctIO flag 没挂文件系统的 block device 也是会经过 page cahe 的,block 层那边提交 bio 的时候会过 page cahe ,所以应该也有 readahead 。
    godev2021
        50
    godev2021  
       2022-07-28 09:38:19 +08:00
    www.fsarchiver.org 可以在备份的时候压缩
    junyee
        51
    junyee  
       2022-07-28 09:53:50 +08:00
    看大佬们互怼真能学到很多知识,
    请继续!
    raptor
        52
    raptor  
       2022-07-28 10:04:51 +08:00
    dd 加 gzip 不是常规操作么?
    PTLin
        53
    PTLin  
       2022-07-28 10:51:12 +08:00
    partclone
    codehz
        54
    codehz  
       2022-07-28 10:57:08 +08:00
    @pagxir 有一个非常简单的方法能测试 readahead 有没有生效(
    就是把它关闭了
    echo 0 > /sys/block/sda/queue/read_ahead_kb
    然后再运行 dd if=/dev/sda of=/dev/null bs=1M
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 1.039096 seconds, 15.4MB/s
    而设置成默认 128 是这个效果
    / # echo 128 > /sys/block/sda/queue/read_ahead_kb
    / # dd if=/dev/sda of=/dev/null bs=1M
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 0.127543 seconds, 125.4MB/s
    而用极为夸张的 1048576 则是这个效果(可见不是越大越好)
    / # echo 1048576 > /sys/block/sda/queue/read_ahead_kb
    / # dd if=/dev/sda of=/dev/null bs=1M
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 0.121848 seconds, 131.3MB/s

    (测试中的磁盘是 qemu 参数 -drive file=/tmp/test.img,format=raw 挂载的,qemu 本身没有启用 kvm 模式,因此性能较低但是比较稳定)

    此外关于 gzip 管道的问题,我也做了一个测试,当磁盘速度不是瓶颈(且 readahead 没被禁用的情况下)
    / # time dd if=/dev/sda of=/dev/null bs=1048576
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 0.129122 seconds, 123.9MB/s
    real 0m 0.14s
    user 0m 0.00s
    sys 0m 0.13s
    直接用 gzip
    / # time sh -c 'gzip -c /dev/sda > /dev/null'
    real 0m 0.87s
    user 0m 0.76s
    sys 0m 0.10s
    加个 dd 管道
    / # time sh -c 'dd if=/dev/sda bs=1048576 | gzip > /dev/null'
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 1.008238 seconds, 15.9MB/s
    real 0m 1.03s
    user 0m 0.79s
    sys 0m 0.23s
    可见速度反而还下降了(我也测试过其他 bs 值,几乎不对结果产生影响,始终大于 1 秒,这个模拟下 1048576 已经是接近最优的值了)
    有趣的是,如果这时候用 dd 的 direct 模式手动绕过缓存
    / # time sh -c 'dd if=/dev/sda bs=1048576 iflag=direct | gzip > /dev/null'
    16+0 records in
    16+0 records out
    16777216 bytes (16.0MB) copied, 0.959065 seconds, 16.7MB/s
    real 0m 0.98s
    user 0m 0.78s
    sys 0m 0.18s
    就小于 1 秒了,可惜还是没有 gzip 直接压缩快(
    yanqiyu
        55
    yanqiyu  
       2022-07-28 12:35:58 +08:00 via Android   ❤️ 1
    虽然大家都在讨论 ra 的问题,但是纯粹的 dd/gzip 最大的问题难道不是把没使用的 block 也给备份了?浪费时间和空间?
    monetto
        56
    monetto  
    OP
       2022-07-28 12:50:28 +08:00
    @yanqiyu 是的,所以最后用了 DiskGenius 单分区备份... ORZ
    YSMAN
        57
    YSMAN  
       2022-07-28 14:11:10 +08:00
    @junyee 同意
    pagxir
        58
    pagxir  
       2022-07-28 15:36:26 +08:00 via Android
    @codehz 如果不加 dd 就直接 gzip 更快,那是因为瓶颈在 CPU ,没有 dd 意味更少的进程调度开销自然更快。并且加 dd 一般是要加两个 dd 才会起到缓冲预读的效果。
    pagxir
        59
    pagxir  
       2022-07-28 15:40:01 +08:00 via Android
    @codehz 你在 qemu 中还不开 kvm ,数据基本上没啥意义,因为瓶颈在 CPU ,连 IO 速度也被 CPU 给限制了
    codehz
        60
    codehz  
       2022-07-28 16:11:30 +08:00
    @pagxir 加两个不是更慢???
    dd 也没开啥边读边写的操作啊,从上面 strace 的结果也可以看到,只是单纯的 read 固定长度然后 write ,这些全都是阻塞操作,没有使用 aio/io_uring ,多线程读写等的操作(源代码里也没有引用线程有关的东西),而 linux pipe 的默认缓冲区只有 64kb ,也就是读取端没有读完的话,写入端写入最多 64k 就会阻塞,即便你把缓冲区选择较小的范围,那也只是凭空增加系统调用数量,因为 gzip 仍然是一次性请求至少 64k (来自源代码,或者你也可以自己 strace 查看),因此 dd 开的越多只会越慢,不知道你怎么弄出“缓冲预读”的功能的
    开 kvm 会让数据波动范围变大,除此之外不能改变结论,我特意选择小文件以缩小差距
    pagxir
        61
    pagxir  
       2022-07-28 16:22:26 +08:00 via Android
    @codehz 在你这场景下,加 dd 那必须更慢,瓶颈在 CPU 就得减少 CPU 的开销才会快。两个 dd 的好处,一个 dd 去取数据到内存,一个 dd 负责吐数据给压缩器,取数据的 dd 不用等压缩器,压缩器不用等磁盘。当然了,你这测试环境肯定是加了比不加还慢
    codehz
        62
    codehz  
       2022-07-28 16:37:32 +08:00
    @pagxir 如果你想达到所谓的缓冲效果,dd 是没有的,有个第三方软件 https://linux.die.net/man/1/buffer 可以实现你想要的结果,它内部实现了一个环形缓冲区,然后可以实现所谓的一边读取,一边写入——但是实际测试可以发现,它的效果比想象中的差很多,内核提供的 128k 的预读已经可以完成足够多的加速,如上所述,gzip 请求大小是 64k ,所以本来就可以在压缩的过程中请求 io
    codehz
        63
    codehz  
       2022-07-28 16:55:32 +08:00
    @pagxir 模拟瓶颈在 io 也很好模拟,qemu 贴心的提供了限制 io 速度的方法,用 throttling.bps-total 限制就可以
    限速到 10MB 的时候
    / # time sh -c 'dd if=/dev/sda bs=2M | gzip > /dev/null'
    8+0 records in
    8+0 records out
    16777216 bytes (16.0MB) copied, 1.579849 seconds, 10.1MB/s
    real 0m 1.59s
    user 0m 0.92s
    sys 0m 0.27s
    / # time sh -c 'gzip -c /dev/sda > /dev/null'
    real 0m 1.53s
    user 0m 0.97s
    sys 0m 0.11s
    作为对比,如果管道前面是 cat
    / # time sh -c 'cat /dev/sda | gzip > /dev/null'
    real 0m 1.53s
    user 0m 0.88s
    sys 0m 0.24s
    具体用时可能略有浮动( gzip 这边就很稳定在 1.53 ,dd 组有时候有异常数据到两秒以上),但是差距还是在这的
    dd 的问题是:write 它也会阻塞,阻塞了之后 read 自然也不会被调用,压缩用的 cpu 太少了,以至于 io 是瓶颈的时候性能并没有啥太大区别)
    关于 dd 作为缓冲的作用,有好多文章写了这个问题
    https://unix.stackexchange.com/questions/345072/can-dd-be-used-to-add-a-buffer-to-a-pipe
    https://unix.stackexchange.com/questions/21918/utility-to-buffer-an-unbounded-amount-of-data-in-a-pipeline
    pagxir
        64
    pagxir  
       2022-07-28 16:59:40 +08:00 via Android
    level@qcloud:~$ cat cloud.txt
    $ echo 128 | sudo tee /sys/block/sdb/bdi/read_ahead_kb
    128
    $ time lz4 -c < /dev/sdb2 > /dev/null
    real 0m25.977s
    user 0m2.104s
    sys 0m1.220s
    $ time lz4 -c < /dev/sdb2 > /dev/null
    real 0m26.217s
    user 0m2.221s
    sys 0m1.126s
    $ echo 20480 | sudo tee /sys/block/sdb/bdi/read_ahead_kb
    20480
    $ time lz4 -c < /dev/sdb2 > /dev/null
    real 0m22.859s
    user 0m0.654s
    sys 0m0.491s
    $ time lz4 -c < /dev/sdb2 > /dev/null
    real 0m22.808s
    user 0m0.695s
    sys 0m0.428s
    $ echo 128 | sudo tee /sys/block/sdb/bdi/read_ahead_kb
    128
    $ time lz4 -c < /dev/sdb2 > /dev/null
    real 0m25.532s
    user 0m1.629s
    sys 0m1.142s
    $ dd if=/dev/sdb2 bs=16M iflag=direct|lz4 -c > /dev/null
    记 录 了 32+0 的 读 入
    记 录 了 32+0 的 写 出
    536870912 字 节 ( 537 MB ,512 MiB ) 已 复 制 ,22.9 s ,23.4 MB/s
    level@qcloud:~$
    level@qcloud:~$

    从这个数据看,这个 read ahead 是有效的。只能说是 page cache 的行为有些奇怪。
    pagxir
        65
    pagxir  
       2022-07-28 17:00:46 +08:00 via Android
    @codehz dd 用做缓冲在 shell 里本来就很常见
    codehz
        66
    codehz  
       2022-07-28 17:33:10 +08:00 via iPhone
    @pagxir 常见的是用 pv ,它的 buffer 是实打实的(和前面说的 buffer 命令类似机制),还能顺带显示进度条
    standin000
        67
    standin000  
       2022-08-02 22:00:36 +08:00   ❤️ 1
    linux 标准的命令是 dump ,我使用过 e2image ,蛮好用。另外除了前面提到的 clonezilla ,还可以用 fsarchiver ,
    windows 可以使用 Macrium Reflect Free Edition
    huangsijun17
        68
    huangsijun17  
       2023-02-06 10:08:00 +08:00
    @documentzhangx66 Symantec 早就把 Ghost 卖给诺顿了。而且,Ghost 停止技术支持都快 10 年了。能不能别拉出来鞭尸了?
    documentzhangx66
        69
    documentzhangx66  
       2023-02-06 10:53:04 +08:00
    @huangsijun17

    建议把我上一条评论,再仔细地、认真地,阅读。别急着抬杠。
    huangsijun17
        70
    huangsijun17  
       2023-02-06 11:48:28 +08:00
    @documentzhangx66 为什么不用“Clonezilla(再生龙)”?为什么不用“DiskGenius”或其套壳备份软件“易数一键还原”?为什么不用“傲梅分区助手”或其套壳备份软件“轻松备份”?有的是 Ghost 的替代品。
    documentzhangx66
        71
    documentzhangx66  
       2023-02-06 19:56:16 +08:00
    @huangsijun17

    建议你,先认真学习了解一下 Ghost 的全部功能,别急着抬杠。

    这不是傲梅这些玩具能比的。
    2NUT
        72
    2NUT  
       2023-08-21 10:23:50 +08:00
    @codehz 一个是磁盘备份,一个是文件系统备份 能一样么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1338 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 23:47 · PVG 07:47 · LAX 15:47 · JFK 18:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.