Skip to content

Commit

Permalink
zdb: show dedup table and log attributes
Browse files Browse the repository at this point in the history
There's interesting info in there that is going to help with
understanding dedup behavior at any given moment.

Since this is a format change, tests that rely on that output have been
modified to match.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Sponsored-by: Klara, Inc.
Sponsored-by: Wasabi Technology, Inc.
Closes openzfs#16755
  • Loading branch information
robn authored Nov 27, 2024
1 parent d2b0ca9 commit 0ffa6f3
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 37 deletions.
109 changes: 85 additions & 24 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1967,17 +1967,53 @@ dump_dedup_ratio(const ddt_stat_t *dds)
static void
dump_ddt_log(ddt_t *ddt)
{
if (ddt->ddt_version != DDT_VERSION_FDT ||
!(ddt->ddt_flags & DDT_FLAG_LOG))
return;

for (int n = 0; n < 2; n++) {
ddt_log_t *ddl = &ddt->ddt_log[n];

uint64_t count = avl_numnodes(&ddl->ddl_tree);
if (count == 0)
continue;
char flagstr[64] = {0};
if (ddl->ddl_flags > 0) {
flagstr[0] = ' ';
int c = 1;
if (ddl->ddl_flags & DDL_FLAG_FLUSHING)
c += strlcpy(&flagstr[c], " FLUSHING",
sizeof (flagstr) - c);
if (ddl->ddl_flags & DDL_FLAG_CHECKPOINT)
c += strlcpy(&flagstr[c], " CHECKPOINT",
sizeof (flagstr) - c);
if (ddl->ddl_flags &
~(DDL_FLAG_FLUSHING|DDL_FLAG_CHECKPOINT))
c += strlcpy(&flagstr[c], " UNKNOWN",
sizeof (flagstr) - c);
flagstr[1] = '[';
flagstr[c++] = ']';
}

printf(DMU_POOL_DDT_LOG ": %lu log entries\n",
zio_checksum_table[ddt->ddt_checksum].ci_name, n, count);
uint64_t count = avl_numnodes(&ddl->ddl_tree);

if (dump_opt['D'] < 4)
printf(DMU_POOL_DDT_LOG ": flags=0x%02x%s; obj=%llu; "
"len=%llu; txg=%llu; entries=%llu\n",
zio_checksum_table[ddt->ddt_checksum].ci_name, n,
ddl->ddl_flags, flagstr,
(u_longlong_t)ddl->ddl_object,
(u_longlong_t)ddl->ddl_length,
(u_longlong_t)ddl->ddl_first_txg, (u_longlong_t)count);

if (ddl->ddl_flags & DDL_FLAG_CHECKPOINT) {
const ddt_key_t *ddk = &ddl->ddl_checkpoint;
printf(" checkpoint: "
"%016llx:%016llx:%016llx:%016llx:%016llx\n",
(u_longlong_t)ddk->ddk_cksum.zc_word[0],
(u_longlong_t)ddk->ddk_cksum.zc_word[1],
(u_longlong_t)ddk->ddk_cksum.zc_word[2],
(u_longlong_t)ddk->ddk_cksum.zc_word[3],
(u_longlong_t)ddk->ddk_prop);
}

if (count == 0 || dump_opt['D'] < 4)
continue;

ddt_lightweight_entry_t ddlwe;
Expand All @@ -1991,7 +2027,7 @@ dump_ddt_log(ddt_t *ddt)
}

static void
dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
dump_ddt_object(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
{
char name[DDT_NAMELEN];
ddt_lightweight_entry_t ddlwe;
Expand All @@ -2016,11 +2052,8 @@ dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)

ddt_object_name(ddt, type, class, name);

(void) printf("%s: %llu entries, size %llu on disk, %llu in core\n",
name,
(u_longlong_t)count,
(u_longlong_t)dspace,
(u_longlong_t)mspace);
(void) printf("%s: dspace=%llu; mspace=%llu; entries=%llu\n", name,
(u_longlong_t)dspace, (u_longlong_t)mspace, (u_longlong_t)count);

if (dump_opt['D'] < 3)
return;
Expand All @@ -2043,24 +2076,52 @@ dump_ddt(ddt_t *ddt, ddt_type_t type, ddt_class_t class)
(void) printf("\n");
}

static void
dump_ddt(ddt_t *ddt)
{
if (!ddt || ddt->ddt_version == DDT_VERSION_UNCONFIGURED)
return;

char flagstr[64] = {0};
if (ddt->ddt_flags > 0) {
flagstr[0] = ' ';
int c = 1;
if (ddt->ddt_flags & DDT_FLAG_FLAT)
c += strlcpy(&flagstr[c], " FLAT",
sizeof (flagstr) - c);
if (ddt->ddt_flags & DDT_FLAG_LOG)
c += strlcpy(&flagstr[c], " LOG",
sizeof (flagstr) - c);
if (ddt->ddt_flags & ~DDT_FLAG_MASK)
c += strlcpy(&flagstr[c], " UNKNOWN",
sizeof (flagstr) - c);
flagstr[1] = '[';
flagstr[c] = ']';
}

printf("DDT-%s: version=%llu [%s]; flags=0x%02llx%s; rootobj=%llu\n",
zio_checksum_table[ddt->ddt_checksum].ci_name,
(u_longlong_t)ddt->ddt_version,
(ddt->ddt_version == 0) ? "LEGACY" :
(ddt->ddt_version == 1) ? "FDT" : "UNKNOWN",
(u_longlong_t)ddt->ddt_flags, flagstr,
(u_longlong_t)ddt->ddt_dir_object);

for (ddt_type_t type = 0; type < DDT_TYPES; type++)
for (ddt_class_t class = 0; class < DDT_CLASSES; class++)
dump_ddt_object(ddt, type, class);

dump_ddt_log(ddt);
}

static void
dump_all_ddts(spa_t *spa)
{
ddt_histogram_t ddh_total = {{{0}}};
ddt_stat_t dds_total = {0};

for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++) {
ddt_t *ddt = spa->spa_ddt[c];
if (!ddt || ddt->ddt_version == DDT_VERSION_UNCONFIGURED)
continue;
for (ddt_type_t type = 0; type < DDT_TYPES; type++) {
for (ddt_class_t class = 0; class < DDT_CLASSES;
class++) {
dump_ddt(ddt, type, class);
}
}
dump_ddt_log(ddt);
}
for (enum zio_checksum c = 0; c < ZIO_CHECKSUM_FUNCTIONS; c++)
dump_ddt(spa->spa_ddt[c]);

ddt_get_dedup_stats(spa, &dds_total);

Expand Down
4 changes: 2 additions & 2 deletions tests/zfs-tests/tests/functional/dedup/dedup_fdt_create.ksh
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "active"

# four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# single containing object in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256 | wc -l) -eq 1
Expand All @@ -84,7 +84,7 @@ log_must cp /$TESTPOOL/file1 /$TESTPOOL/file2
log_must zpool sync

# now four entries in the duplicate table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate:.*entries=4'"

# now two DDT ZAPs in the container object; DDT ZAPs aren't cleaned up until
# the entire logical table is destroyed
Expand Down
4 changes: 2 additions & 2 deletions tests/zfs-tests/tests/functional/dedup/dedup_fdt_import.ksh
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "active"

# four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# single containing object in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256 | wc -l) -eq 1
Expand Down Expand Up @@ -107,7 +107,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "active"

# four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# single containing object in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256 | wc -l) -eq 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "disabled"

# should be four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# should be just one DDT ZAP in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256-zap- | wc -l) -eq 1
Expand All @@ -73,7 +73,7 @@ log_must cp /$TESTPOOL/file1 /$TESTPOOL/file2
log_must zpool sync

# now four entries in the duplicate table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate:.*entries=4'"

# now two DDT ZAPs in the MOS; DDT ZAPs aren't cleaned up until the entire
# logical table is destroyed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ log_must dd if=/dev/urandom of=/$TESTPOOL/ds1/file1 bs=128k count=4
log_must zpool sync

# should be four entries in the skein unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-skein-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-skein-zap-unique:.*entries=4'"

# should be just one DDT ZAP in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-.*-zap- | wc -l) -eq 1
Expand All @@ -90,7 +90,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "active"

# now also four entries in the blake3 unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-blake3-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-blake3-zap-unique:.*entries=4'"

# two entries in the MOS: the legacy skein DDT ZAP, and the containing dir for
# the blake3 FDT table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "disabled"

# should be four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# should be just one DDT ZAP in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256-zap- | wc -l) -eq 1
Expand All @@ -90,7 +90,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "enabled"

# now four entries in the duplicate table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-duplicate:.*entries=4'"

# now two DDT ZAPs in the MOS; DDT ZAPs aren't cleaned up until the entire
# logical table is destroyed
Expand All @@ -117,7 +117,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "active"

# four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# single containing object in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256 | wc -l) -eq 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "disabled"

# should be four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# should be just one DDT ZAP in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256-zap- | wc -l) -eq 1
Expand Down Expand Up @@ -96,7 +96,7 @@ log_must zpool sync
log_must test $(get_pool_prop feature@fast_dedup $TESTPOOL) = "disabled"

# should be four entries in the unique table
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique: 4 entries'"
log_must eval "zdb -D $TESTPOOL | grep -q 'DDT-sha256-zap-unique:.*entries=4'"

# should be just one DDT ZAP in the MOS
log_must test $(zdb -dddd $TESTPOOL 1 | grep DDT-sha256-zap- | wc -l) -eq 1
Expand Down

0 comments on commit 0ffa6f3

Please sign in to comment.