zdb: add --bin=(lsize|psize|asize) arg to control histogram binning

When counting blocks to generate block size histograms (`-bb`), accept a
`--bin=` argument to force placing blocks into all three bins based on
*this* size.

E.g. with `--bin=lsize`, a block with lsize=512K, psize=128K, asize=256K
will be placed into the "512K" bin in all three output columns. This
way, by looking at the "512K" row the user will be able to determine
how well was ZFS able to compress blocks of this logical size.

Conversely, with `--bin=psize`, by looking at the "128K" row the user
will be able to determine how much overhead was incurred for storage
of blocks of this physical size.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ivan Shapovalov <intelfx@intelfx.name>
Closes #16999
This commit is contained in:
Ivan Shapovalov 2024-12-10 04:44:19 +04:00 committed by Tony Hutter
parent 6809137db5
commit 627b530059
2 changed files with 67 additions and 3 deletions

View File

@ -108,6 +108,7 @@ extern uint_t zfs_btree_verify_intensity;
enum {
ARG_ALLOCATED = 256,
ARG_BLOCK_BIN_MODE,
};
static const char cmdname[] = "zdb";
@ -133,6 +134,13 @@ static objset_t *os;
static boolean_t kernel_init_done;
static boolean_t corruption_found = B_FALSE;
static enum {
BIN_AUTO = 0,
BIN_PSIZE,
BIN_LSIZE,
BIN_ASIZE,
} block_bin_mode = BIN_AUTO;
static void snprintf_blkptr_compact(char *, size_t, const blkptr_t *,
boolean_t);
static void mos_obj_refd(uint64_t);
@ -751,6 +759,8 @@ usage(void)
(void) fprintf(stderr, " Options to control amount of output:\n");
(void) fprintf(stderr, " -b --block-stats "
"block statistics\n");
(void) fprintf(stderr, " --bin=(lsize|psize|asize) "
"bin blocks based on this size in all three columns\n");
(void) fprintf(stderr, " -B --backup "
"backup stream\n");
(void) fprintf(stderr, " -c --checksum "
@ -5816,6 +5826,20 @@ dump_size_histograms(zdb_cb_t *zcb)
(void) printf("\nBlock Size Histogram\n");
switch (block_bin_mode) {
case BIN_PSIZE:
printf("(note: all categories are binned by %s)\n", "psize");
break;
case BIN_LSIZE:
printf("(note: all categories are binned by %s)\n", "lsize");
break;
case BIN_ASIZE:
printf("(note: all categories are binned by %s)\n", "asize");
break;
default:
printf("(note: all categories are binned separately)\n");
break;
}
/*
* Print the first line titles
*/
@ -6164,24 +6188,38 @@ skipped:
[BPE_GET_PSIZE(bp)]++;
return;
}
/*
* The binning histogram bins by powers of two up to
* SPA_MAXBLOCKSIZE rather than creating bins for
* every possible blocksize found in the pool.
*/
int bin = highbit64(BP_GET_PSIZE(bp)) - 1;
int bin;
switch (block_bin_mode) {
case BIN_PSIZE: bin = highbit64(BP_GET_PSIZE(bp)) - 1; break;
case BIN_LSIZE: bin = highbit64(BP_GET_LSIZE(bp)) - 1; break;
case BIN_ASIZE: bin = highbit64(BP_GET_ASIZE(bp)) - 1; break;
case BIN_AUTO: break;
default: PANIC("bad block_bin_mode"); abort();
}
if (block_bin_mode == BIN_AUTO)
bin = highbit64(BP_GET_PSIZE(bp)) - 1;
zcb->zcb_psize_count[bin]++;
zcb->zcb_psize_len[bin] += BP_GET_PSIZE(bp);
zcb->zcb_psize_total += BP_GET_PSIZE(bp);
bin = highbit64(BP_GET_LSIZE(bp)) - 1;
if (block_bin_mode == BIN_AUTO)
bin = highbit64(BP_GET_LSIZE(bp)) - 1;
zcb->zcb_lsize_count[bin]++;
zcb->zcb_lsize_len[bin] += BP_GET_LSIZE(bp);
zcb->zcb_lsize_total += BP_GET_LSIZE(bp);
bin = highbit64(BP_GET_ASIZE(bp)) - 1;
if (block_bin_mode == BIN_AUTO)
bin = highbit64(BP_GET_ASIZE(bp)) - 1;
zcb->zcb_asize_count[bin]++;
zcb->zcb_asize_len[bin] += BP_GET_ASIZE(bp);
@ -9429,6 +9467,8 @@ main(int argc, char **argv)
{"zstd-headers", no_argument, NULL, 'Z'},
{"allocated-map", no_argument, NULL,
ARG_ALLOCATED},
{"bin", required_argument, NULL,
ARG_BLOCK_BIN_MODE},
{0, 0, 0, 0}
};
@ -9542,6 +9582,20 @@ main(int argc, char **argv)
case 'x':
vn_dumpdir = optarg;
break;
case ARG_BLOCK_BIN_MODE:
if (strcmp(optarg, "lsize") == 0) {
block_bin_mode = BIN_LSIZE;
} else if (strcmp(optarg, "psize") == 0) {
block_bin_mode = BIN_PSIZE;
} else if (strcmp(optarg, "asize") == 0) {
block_bin_mode = BIN_ASIZE;
} else {
(void) fprintf(stderr,
"--bin=\"%s\" must be one of \"lsize\", "
"\"psize\" or \"asize\"\n", optarg);
usage();
}
break;
default:
usage();
break;

View File

@ -144,6 +144,16 @@ subcommand.
Display statistics regarding the number, size
.Pq logical, physical and allocated
and deduplication of blocks.
.It Fl -bin Ns = Ns ( Li lsize Ns | Ns Li psize Ns | Ns Li asize )
When used with
.Fl bb ,
sort blocks into all three bins according to the given size (instead of binning
a block for each size separately).
.Pp
For instance, with
.Fl -bin Ns = Ns Li lsize ,
a block with lsize of 16K and psize of 4K will be added to the 16K bin
in all three columns.
.It Fl B , -backup
Generate a backup stream, similar to
.Nm zfs Cm send ,