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

备份 Ext4 分区的正确姿势

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

    如题,有一个 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 iPhon
    @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
    < href="/member/bthulu" class="dark">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     Solana     2213 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 16:07 PVG 00:07 LAX 09:07 JFK 12:07
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86