How to migrate a ZFS filesystem to use compression?

6,345

Solution 1

Even though dump.txt is highly compressible it turns out, that zfs won't compress it for some reason.

Redoing my experiments again with other data, it turns out that send/receive will compress the data. Here I have set the compression on the zpool, so all file systems would inherit this. I also used Linux here, but that shouldn't matter.

# dd if=/dev/zero of=/mnt/dat0/zpool1 bs=1M count=1000
# dd if=/dev/zero of=/mnt/dat0/zpool2 bs=1M count=1000
# service zfs-fuse restart
# zpool create zpool1 /mnt/dat0/zpool1 
# zpool create zpool2 /mnt/dat0/zpool2
# zfs set compression=on zpool1
# zfs create zpool1/fs1
# zfs create zpool2/fs2
# cp -r /etc/ /var/log /zpool2/fs2/
# zfs snapshot zpool2/fs2@snap
# zfs send zpool2/fs2@snap | zfs receive zpool1/fs2
# zfs get compressratio zpool1/fs2
NAME        PROPERTY       VALUE  SOURCE
zpool1/fs2  compressratio  4.75x  -

Solution 2

Copy the data.

That is all.

There's a bunch of missing output in your examples, but it doesn't matter. The only thing you need to do to move data into a compressed filesystem is to rewrite the data either by copying it, moving it or populating a new filesystem.

Avoid the problem in future situations by enabling compression at the pool level so that it's inherited by new filesystems. Also, use lz4 compression flag. It's generally better.

Share:
6,345

Related videos on Youtube

Jasmine Lognnes
Author by

Jasmine Lognnes

Updated on September 18, 2022

Comments

  • Jasmine Lognnes
    Jasmine Lognnes over 1 year

    Question at the bottom.

    I have several ZFS file system I would like to use ZFS compression, but since enabling the compression will only affect new data written to the file system, I would like to write a script that can migrate file systems, so all data is compressed.

    This is my test attempt

    du -h /tmp/dump.txt
    
    zfs create -p tank3/xtest1/fs
    cp /tmp/dump.txt /tank3/xtest1/fs
    zfs list | grep xtest
    
    zfs create tank3/xtest2
    zfs set compression=lzjb tank3/xtest2
    zfs inherit compression tank3/xtest2
    
    zfs snapshot tank3/xtest1/fs@snap
    zfs send tank3/xtest1/fs@snap | zfs receive tank3/xtest2/fs
    zfs get compression tank3/xtest2/fs
    zfs list | grep xtest
    
    zfs destroy -r tank3/xtest1
    zfs destroy -r tank3/xtest2
    
    
    echo "test 2"
    
    zfs create tank3/xtest2
    zfs set compression=lzjb tank3/xtest2
    zfs list | grep xtest
    
    cp /tmp/dump.txt /tank3/xtest2
    zfs list | grep xtest
    zfs get compressratio tank3/xtest2
    
    zfs destroy -r tank3/xtest2
    

    which gives

    344M    /tmp/dump.txt
    tank3/xtest1                          575K  6.38T   288K  /tank3/xtest1
    tank3/xtest1/fs                       288K  6.38T   288K  /tank3/xtest1/fs
    NAME             PROPERTY     VALUE     SOURCE
    tank3/xtest2/fs  compression  off       default
    tank3/xtest1                          344M  6.38T   304K  /tank3/xtest1
    tank3/xtest1/fs                       344M  6.38T   344M  /tank3/xtest1/fs
    tank3/xtest2                          344M  6.38T   288K  /tank3/xtest2
    tank3/xtest2/fs                       344M  6.38T   344M  /tank3/xtest2/fs
    test 2
    tank3/xtest2                          288K  6.38T   288K  /tank3/xtest2
    tank3/xtest2                          288K  6.38T   288K  /tank3/xtest2
    NAME          PROPERTY       VALUE  SOURCE
    tank3/xtest2  compressratio  1.00x  -
    

    In the first test would I have expected the replication would compress the data when creating tank3/xtest2/fs but newly created file systems does not inherit compression when using send/receive it seams.

    In test 2 I can't see the 344MB file takes any space.

    From what I can tell compression doesn't work.

    Question

    Why do I see these weird results?

    And how should I migrate a not compressed file system to be compressed?

    Update

    Added compressratio property which shows that no compression have been done. dump.txt can be compressed to 190MB.

  • Jasmine Lognnes
    Jasmine Lognnes over 9 years
    All the output should be there. I have copy/pasted everything. Can you figure out what I wrong with my test 2? Why doesn't it take up any space?
  • Tero Kilkanen
    Tero Kilkanen over 9 years
    If the dump.txt is a highly compressible file, the results are just what are expected. The file takes only the space it takes in compressed form. So, copying the file compresses it.
  • Jasmine Lognnes
    Jasmine Lognnes over 9 years
    @TeroKilkanen Compressed dump.txt is 190MB and in zfs list before and after the copy, zfs shows 288k. It should have showed at least 190MB after.
  • Jasmine Lognnes
    Jasmine Lognnes over 9 years
    It turns out that send/receive works. Please see any answer.
  • ewwhite
    ewwhite over 9 years
    You're doing a disservice by not using lz4 compression.
  • Jasmine Lognnes
    Jasmine Lognnes over 9 years
    I will use lz4, it is just that it requires irreversible changes to the zpool, so I can't do it on this host.
  • ewwhite
    ewwhite over 9 years
    Compression is not an irreversible change.
  • Jasmine Lognnes
    Jasmine Lognnes over 9 years
    From wiki.illumos.org/display/illumos/LZ4+Compression If you would like to enable LZ4 on a pool which doesn't have feature flags enabled, upgrade the pool first using the "zpool upgrade <poolname>" command. Please note that this will make your pool unimportable on systems which lack support for feature flags (e.g. Solaris 10, Oracle Solaris 11, etc.).
  • Colonel Thirty Two
    Colonel Thirty Two over 3 years
    Link is dead. Can you update it?
  • ewwhite
    ewwhite over 3 years
    @ColonelThirtyTwo The link to what?
  • Colonel Thirty Two
    Colonel Thirty Two over 3 years
    @ewwhite The only link in your answer, but it appeared to be a temporary outage, so whatever.
  • xpac
    xpac about 2 years
    it's outdated either way, today you likely wanna use zstd instead of lz4