Playing around with zdb

Just some playing around with zdb to get if there are differences between a filesystem or volume and a snapshot.

Okay, the most important thing here is something which is written in the man page. Without that, you might have a hard time finding on how to select the data of the pool (you’ll most likely understand me later) for now just note the following:

If the dataset argument does not contain any / or @ characters, it is interpreted as a pool name. The root dataset can be specified as pool/ (pool name followed by a slash).

Now let’s continue: zdb -d dataset should return all datasets. Somewhere I read that it would display all children/descended datasets as well, but that is not the case here (zfs on linux).

root@nyota:~# zdb -d storage/
Dataset storage [ZPL], ID 21, cr_txg 1, 96.0K, 6 objects
 
root@nyota:~# zdb -d storage/virtual/
Dataset storage/virtual [ZPL], ID 222, cr_txg 9141777, 96.0K, 6 objects
 
root@nyota:~# zdb -d storage/virtual/kvm100/root
Dataset storage/virtual/kvm100/root [ZVOL], ID 208, cr_txg 9277708, 1.04G, 2 objects

A dataset can be a filesystem (in zdb I think it is referred to both as ZPL and „ZFS directory“ at different places) and a volume (in zdb you’ll see ZVOL and „zvol object“). You can see in the above examples that storage/virtual/kvm100/root is a volume while the previous two datasets are filesystems.

Every dataset consists of object (well, at least thats what I see using zdb). Lets take a look:

# pool-filesystem
root@nyota:~# zdb -dd storage/
Dataset storage [ZPL], ID 21, cr_txg 1, 96.0K, 6 objects
 
    ZIL header: claim_txg 0, claim_blk_seq 0, claim_lr_seq 0 replay_seq 0, flags 0x0
 
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         0    7    16K    16K  56.0K    16K   18.75  DMU dnode
        -1    1    16K    512      0    512  100.00  ZFS user/group used
        -2    1    16K    512      0    512  100.00  ZFS user/group used
         1    1    16K    512     8K    512  100.00  ZFS master node
         2    1    16K    512      0    512  100.00  SA master node
         3    1    16K    512      0    512  100.00  ZFS delete queue
         4    1    16K    512      0    512  100.00  ZFS directory
         5    1    16K  1.50K     8K  1.50K  100.00  SA attr registration
         6    1    16K    16K    16K    32K  100.00  SA attr layouts
 
# filesystem
root@nyota:~# zdb -dd storage/virtual
Dataset storage/virtual [ZPL], ID 222, cr_txg 9141777, 96.0K, 6 objects
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         0    7    16K    16K  56.0K    16K   18.75  DMU dnode
        -1    1    16K    512      0    512  100.00  ZFS user/group used
        -2    1    16K    512      0    512  100.00  ZFS user/group used
         1    1    16K    512     8K    512  100.00  ZFS master node
         2    1    16K    512      0    512  100.00  SA master node
         3    1    16K    512      0    512  100.00  ZFS delete queue
         4    1    16K    512      0    512  100.00  ZFS directory
         5    1    16K  1.50K     8K  1.50K  100.00  SA attr registration
         6    1    16K    16K    16K    32K  100.00  SA attr layouts
 
# volume
root@nyota:~# zdb -dd storage/virtual/kvm100/root
Dataset storage/virtual/kvm100/root [ZVOL], ID 208, cr_txg 9277708, 1.04G, 2 objects
 
    ZIL header: claim_txg 0, claim_blk_seq 0, claim_lr_seq 0 replay_seq 0, flags 0x0
 
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         0    7    16K    16K  56.0K    16K    6.25  DMU dnode
         1    4    16K     4K  1.04G  5.00G   21.79  zvol object
         2    1    16K    512      0    512  100.00  zvol prop

You can see that the filesystems have an object with ID 4 called „ZFS directory“ which is what I am interested in. The volume has an object with ID 1 called „zvol object“ which is what I am interested in as well. You can grab those by adding the ID to your zdb command:

# pool-filesystem
root@nyota:~# zdb -dd storage/ 4
Dataset storage [ZPL], ID 21, cr_txg 1, 96.0K, 6 objects
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         4    1    16K    512      0    512  100.00  ZFS directory
 
# filesystem
root@nyota:~# zdb -dd storage/virtual 4
Dataset storage/virtual [ZPL], ID 222, cr_txg 9141777, 96.0K, 6 objects
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         4    1    16K    512      0    512  100.00  ZFS directory
 
# volume
root@nyota:~# zdb -dd storage/virtual/kvm100/root 1
Dataset storage/virtual/kvm100/root [ZVOL], ID 208, cr_txg 9277708, 1.04G, 2 objects
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         1    4    16K     4K  1.04G  5.00G   21.79  zvol object

And we can dive deeper into those by adding another few -d’s:

# pool filesystem
root@nyota:~# zdb -dddd storage/ 4
Dataset storage [ZPL], ID 21, cr_txg 1, 96.0K, 6 objects, rootbp 
  DVA[0]=<0:347f50d000:1000> DVA[1]=<0:16fe406000:1000> [L0 DMU objset] 
  fletcher4 uncompressed LE contiguous unique double size=800L/800P 
  birth=9413843L/9413843P fill=6 cksum=b2438a130:cdd394e29ad:9464f6151fa0a:4fe853c88b03c1b
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         4    1    16K    512      0    512  100.00  ZFS directory
                                        168   bonus  System attributes
        dnode flags: USED_BYTES USERUSED_ACCOUNTED 
        dnode maxblkid: 0
        path    /
        uid     0
        gid     0
        atime   Sun Jan 17 22:27:54 2016
        mtime   Fri Apr  7 21:05:43 2017
        ctime   Fri Apr  7 21:05:43 2017
        crtime  Sun Jan 17 22:27:25 2016
        gen     4
        mode    40755
        size    2
        parent  4
        links   2
        pflags  40800000144
        microzap: 512 bytes, 0 entries
 
# filesystem
root@nyota:~# zdb -dddd storage/virtual 4
Dataset storage/virtual [ZPL], ID 222, cr_txg 9141777, 96.0K, 6 objects, rootbp 
  DVA[0]=<0:400261000:1000> DVA[1]=<0:2c00269000:1000> [L0 DMU objset] 
  fletcher4 uncompressed LE contiguous unique double size=800L/800P 
  birth=9141777L/9141777P fill=6 cksum=956ec83c9:a52cd15549b:781fb2b606811:42af3149aeb6191
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         4    1    16K    512      0    512  100.00  ZFS directory
                                        168   bonus  System attributes
        dnode flags: USED_BYTES USERUSED_ACCOUNTED 
        dnode maxblkid: 0
        path    /
        uid     0
        gid     0
        atime   Wed Mar 22 19:24:11 2017
        mtime   Wed Mar 22 19:24:11 2017
        ctime   Wed Mar 22 19:24:11 2017
        crtime  Wed Mar 22 19:24:11 2017
        gen     9141777
        mode    40755
        size    2
        parent  4
        links   2
        pflags  40800000144
        microzap: 512 bytes, 0 entries
 
# volume
root@nyota:~# zdb -dddd storage/virtual/kvm100/root 1
Dataset storage/virtual/kvm100/root [ZVOL], ID 208, cr_txg 9277708, 1.04G, 2 objects, rootbp 
  DVA[0]=<0:355b833000:1000> DVA[1]=<0:178661d000:1000> [L0 DMU objset] 
  fletcher4 uncompressed LE contiguous unique double size=800L/800P 
  birth=9470863L/9470863P fill=2 cksum=6fd95604b:b812ca15a05:9a99ae0ec32fe:58354b70bb87039
 
    Object  lvl   iblk   dblk  dsize  lsize   %full  type
         1    4    16K     4K  1.04G  5.00G   21.79  zvol object
        dnode flags: USED_BYTES 
        dnode maxblkid: 1310719

I’m mostly interested into the cksum value. Because that one will allow me to check for differences later. If you dive deeper, you can see the segments and compare them against a snapshot (you may also just compare the cksum, no need to dive deeper):

root@nyota:~# zdb -ddddd storage/virtual/kvm100/root 1 > vol
root@nyota:~# zdb -ddddd storage/virtual/kvm100/root@test 1 > volsnap
root@nyota:~# zfs snapshot storage@test
root@nyota:~# touch /storage/foobar
root@nyota:~# zdb -ddddd storage/ 4 > pool-filesys
root@nyota:~# zdb -ddddd storage@test 4 > pool-filesyssnap
root@nyota:~# du -sh pool-filesys*
4,0K    pool-filesys
4,0K    pool-filesyssnap
root@nyota:~# du -sh vol*
21M     vol
21M     volsnap
root@nyota:~# diff pool-filesys pool-filesyssnap 
1c1
< Dataset storage [ZPL], ID 21, cr_txg 1, 96.0K, 7 objects, rootbp 
  DVA[0]=<0:355b9d2000:1000> DVA[1]=<0:178679f000:1000> [L0 DMU objset] 
  fletcher4 uncompressed LE contiguous unique double size=800L/800P 
  birth=9470919L/9470919P fill=7 cksum=b0482d149:ca3c2144c5b:9122a12721e3b:4deec4627e20677
---
> Dataset storage@test [ZPL], ID 1837, cr_txg 9470917, 96.0K, 6 objects, rootbp 
  DVA[0]=<0:347f50d000:1000> DVA[1]=<0:16fe406000:1000> [L0 DMU objset] 
  fletcher4 uncompressed LE contiguous unique double size=800L/800P 
  birth=9413843L/9413843P fill=6 cksum=b2438a130:cdd394e29ad:9464f6151fa0a:4fe853c88b03c1b
12,13c12,13
<       mtime   Mon Apr 10 22:50:19 2017
<       ctime   Mon Apr 10 22:50:19 2017
---
>       mtime   Fri Apr  7 21:05:43 2017
>       ctime   Fri Apr  7 21:05:43 2017
17c17
<       size    3
---
>       size    2
21c21
<       microzap: 512 bytes, 1 entries
---
>       microzap: 512 bytes, 0 entries
23d22
<               foobar = 10 (type: Regular File)
25c24
<                0 L0 EMBEDDED et=0 200L/31P B=9470919
---
>                0 L0 EMBEDDED et=0 200L/1cP B=9413843

a diff on volsnap and vol would be too long here; You could simplify that by just grepping for „segment“:

root@nyota:~# zdb -ddddd storage/virtual/kvm100/root@test 1 | grep segment > volsnap
root@nyota:~# zdb -ddddd storage/virtual/kvm100/root 1 | grep segment > vol
root@nyota:~# diff vol volsnap
128c128
<               segment [0000000023300000, 00000000238cd000) size 5.80M
---
>               segment [0000000023300000, 00000000238c0000) size 5.75M

So it is pretty simple to use zdb. I really like how you can dive deeper and deeper into your data. Wondering about the why? Oh, that is simple: I’ve written a script which creates snapshots if data has changed between the filesystem and the last snapshot. While that is not required because ZFS snapshots are cheap, I don’t want a list of empty snapshots. I make heavy use of zfs diff for that and zfs diff currently does only work with filesystems and not with volumes. The above approach will allow me to get the same for both.

Obviously, the checksum (cksum) should be enough to detect if there has been changes.

No Comments

Post a Comment