Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zdb: improvements to block histograms (zdb -bb) #16999

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
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.

Signed-off-by: Ivan Shapovalov <[email protected]>
  • Loading branch information
intelfx committed Jan 28, 2025
commit b9318e873105be749ae5c7928f80f553aa53093d
56 changes: 53 additions & 3 deletions cmd/zdb/zdb.c
Original file line number Diff line number Diff line change
@@ -127,6 +127,14 @@ static spa_t *spa;
static objset_t *os;
static boolean_t kernel_init_done;


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);
@@ -737,6 +745,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 "
@@ -5716,6 +5726,12 @@ dump_size_histograms(zdb_cb_t *zcb)


(void) printf("\nBlock Size Histogram\n");
switch (block_bin_mode) {
case BIN_PSIZE: (void) printf("(note: all categories are binned by %s)\n", "psize"); break;
case BIN_LSIZE: (void) printf("(note: all categories are binned by %s)\n", "lsize"); break;
case BIN_ASIZE: (void) printf("(note: all categories are binned by %s)\n", "asize"); break;
default: (void) printf("(note: all categories are binned separately)\n"); break;
}
/*
* Print the first line titles
*/
@@ -6064,24 +6080,38 @@ zdb_count_block(zdb_cb_t *zcb, zilog_t *zilog, const blkptr_t *bp,
[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);
@@ -9202,6 +9232,11 @@ dummy_get_file_info(dmu_object_type_t bonustype, const void *data,
abort();
}

enum
{
ARG_BLOCK_BIN_MODE = 256,
};

int
main(int argc, char **argv)
{
@@ -9303,6 +9338,7 @@ main(int argc, char **argv)
{"all-reconstruction", no_argument, NULL, 'Y'},
{"livelist", no_argument, NULL, 'y'},
{"zstd-headers", no_argument, NULL, 'Z'},
{"bin", required_argument, NULL, ARG_BLOCK_BIN_MODE},
{0, 0, 0, 0}
};

@@ -9413,6 +9449,20 @@ main(int argc, char **argv)
case 'x':
vn_dumpdir = optarg;
break;
case ARG_BLOCK_BIN_MODE:
if (!strcmp(optarg, "lsize")) {
block_bin_mode = BIN_LSIZE;
} else if (!strcmp(optarg, "psize")) {
block_bin_mode = BIN_PSIZE;
} else if (!strcmp(optarg, "asize")) {
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;