mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	zdb: show dedup table and log attributes
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 #16755
This commit is contained in:
		
							parent
							
								
									d2b0ca953f
								
							
						
					
					
						commit
						0ffa6f3464
					
				
							
								
								
									
										107
									
								
								cmd/zdb/zdb.c
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								cmd/zdb/zdb.c
									
									
									
									
									
								
							@ -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];
 | 
			
		||||
 | 
			
		||||
		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++] = ']';
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		uint64_t count = avl_numnodes(&ddl->ddl_tree);
 | 
			
		||||
		if (count == 0)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		printf(DMU_POOL_DDT_LOG ": %lu log entries\n",
 | 
			
		||||
		    zio_checksum_table[ddt->ddt_checksum].ci_name, n, count);
 | 
			
		||||
		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 (dump_opt['D'] < 4)
 | 
			
		||||
		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;
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -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;
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user