ZFS is a COW (Copy On Write) file system. Which means that instead of overwriting dirty blocks the driver writes it somewhere else. COW's file systems has many advantages and some disadvantages. Among the main disadvantages is the fragmentation caused by busy applications like databases. Other COW file systems like BTFRS let you prevent to use COW in some files, but that is not the case of ZFS. There is no direct way of calculating fragmentation on ZFS, despite being a very important performance issue. There is a very useful tool called zdb (ZFS debugger) that provides tones of information about zpools and zfs. This tool can give you the exact location and size of all the blocks in the file system. With that, and a little awk program to summarize that info, we get an approximation of the fragmentation in a zpool:
# zdb -ddddd data/aplicacions | gawk --non-decimal-data -f fragments.awk
There are 25853 files.
There are 46245 blocks and 20443 fragment blocks.
There are 6376 fragmented blocks (31.19%).
There are 14067 contiguous blocks (68.81%).
Fragment blocks are blocks that follow other blocks, which means that there are file system objects that occupy less or equal than a block that don't count for fragmentation.
The awk program is this:
/Indirect blocks/{
file_number++;
next_block = 0;
}
/L0/{
split($3,fields,":");
this_block = ("0x"fields[2])+0;
this_block_size = ("0x"fields[3])+0;
total_blocks++;
if( next_block != 0 ) {
if( next_block == this_block )
not_fragmented++;
else
fragmented++;
}
next_block = this_block + this_block_size;
}
END{
printf("There are %d files.\n", file_number );
total_fragment_blocks = fragmented + not_fragmented;
printf("There are %d blocks and %d fragment blocks.\n", total_blocks, total_fragment_blocks );
printf("There are %d fragmented blocks (%2.2f%%).\n", fragmented, fragmented*100.0/total_fragment_blocks );
printf("There are %d contiguous blocks (%2.2f%%).\n", not_fragmented, not_fragmented*100.0/total_fragment_blocks );
}