summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-06-09 10:44:42 -0400
committerKeith Bostic <keith.bostic@mongodb.com>2016-06-09 10:44:42 -0400
commit3ed78d64fa38162bfe7a8e294403460e848db48d (patch)
treeeabf1533524206aee2146b118ee07fbd8cc9a47b
parentb2ea0663f767604dc4fd409aa9fcd1ef90268b11 (diff)
downloadmongo-3ed78d64fa38162bfe7a8e294403460e848db48d.tar.gz
WT-2671 dump more information about the file layout in verify debug mode (#2755)
* WT-2671: dump more information about the file layout in verify debug mode Dump the checkpoint final and correct sizes when loading checkpoints in verify dump_XXX mode. Dump the checkpoint alloc, discard and avail lists when loading checkpoints in verify dump_XXX mode. Fix a bug, convert the count of tree pages from uint32_t to uint64_t, there's no reason pages counts can't overflow 4B. Fix a bug, reset the internal/leaf page counts at the end of every checkpoint, we were doing cumulative counts. Fix a bug, where we were using "%03zu" for a size_t type, fix the dist/s_style script to catch that case. Add a divider line between checkpoints to make it easier to read the output. Add a new __wt_buf_set_size() function that displays byte values in human-readable format. Move __wt_buf_set_printable() from btree/bt_misc.c to support/scratch.c, it's a general-purpose function. Rename verify debug option from "dump_shape" to "dump_layout", we're dumping more than the tree shape now. * Merge the two versions of the "dump extent list" functions, and stop dumping all of the elements, they're far too many for that to ever be useful again. Instead, display a list by power-of-two bucket size. * Minor changes to make bucket sizes human readable. * block_ext.c:1477:3: error: format '%s' expects argument of type 'char *', but argument 3 has type 'const void *' [-Werror=format]
-rw-r--r--dist/api_data.py9
-rw-r--r--dist/s_define.list1
-rw-r--r--dist/s_string.ok1
-rwxr-xr-xdist/s_style2
-rw-r--r--src/block/block_ext.c84
-rw-r--r--src/block/block_vrfy.c30
-rw-r--r--src/btree/bt_misc.c16
-rw-r--r--src/btree/bt_vrfy.c47
-rw-r--r--src/config/config_def.c6
-rw-r--r--src/include/block.h1
-rw-r--r--src/include/extern.h3
-rw-r--r--src/include/misc.h2
-rw-r--r--src/include/wiredtiger.in7
-rw-r--r--src/support/scratch.c58
-rw-r--r--src/utilities/util_verify.c20
15 files changed, 192 insertions, 95 deletions
diff --git a/dist/api_data.py b/dist/api_data.py
index 6854890a477..90b1c8378a2 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -959,6 +959,11 @@ methods = {
Display the contents of on-disk blocks as they are verified,
using the application's message handler, intended for debugging''',
type='boolean'),
+ Config('dump_layout', 'false', r'''
+ Display the layout of the files as they are verified, using the
+ application's message handler, intended for debugging; requires
+ optional support from the block manager''',
+ type='boolean'),
Config('dump_offsets', '', r'''
Display the contents of specific on-disk blocks,
using the application's message handler, intended for debugging''',
@@ -967,10 +972,6 @@ methods = {
Display the contents of in-memory pages as they are verified,
using the application's message handler, intended for debugging''',
type='boolean'),
- Config('dump_shape', 'false', r'''
- Display the shape of the tree after verification,
- using the application's message handler, intended for debugging''',
- type='boolean'),
Config('strict', 'false', r'''
Treat any verification problem as an error; by default, verify will
warn, but not fail, in the case of errors that won't affect future
diff --git a/dist/s_define.list b/dist/s_define.list
index c9777c86675..e1843a811c2 100644
--- a/dist/s_define.list
+++ b/dist/s_define.list
@@ -23,6 +23,7 @@ WT_CONN_CHECK_PANIC
WT_DEADLOCK
WT_DEBUG_BYTE
WT_ERR_ERROR_OK
+WT_EXT_FOREACH_OFF
WT_HANDLE_CLOSED
WT_HANDLE_NULLABLE
WT_LOG_SLOT_ACTIVE
diff --git a/dist/s_string.ok b/dist/s_string.ok
index 61bb246c59b..48290ad1675 100644
--- a/dist/s_string.ok
+++ b/dist/s_string.ok
@@ -87,6 +87,7 @@ Decrement
Decrypt
DeleteFileA
EAGAIN
+EB
EBUSY
EEXIST
EINTR
diff --git a/dist/s_style b/dist/s_style
index 85220124971..33ff718e0c6 100755
--- a/dist/s_style
+++ b/dist/s_style
@@ -73,7 +73,7 @@ else
if ! expr "$f" : 'examples/c/.*' > /dev/null &&
! expr "$f" : 'ext/datasources/helium/helium.c' > /dev/null &&
! expr "$f" : 'src/include/os.h' > /dev/null &&
- grep "%zu" $f | grep -v 'SIZET_FMT' > $t; then
+ egrep "%[0-9]*zu" $f | grep -v 'SIZET_FMT' > $t; then
echo "$f: %zu needs to be fixed for Windows"
cat $t
fi
diff --git a/src/block/block_ext.c b/src/block/block_ext.c
index 6d67a66be5f..0d3e7b54f17 100644
--- a/src/block/block_ext.c
+++ b/src/block/block_ext.c
@@ -24,7 +24,7 @@ static int __block_append(WT_SESSION_IMPL *,
static int __block_ext_overlap(WT_SESSION_IMPL *,
WT_BLOCK *, WT_EXTLIST *, WT_EXT **, WT_EXTLIST *, WT_EXT **);
static int __block_extlist_dump(
- WT_SESSION_IMPL *, const char *, WT_EXTLIST *, bool);
+ WT_SESSION_IMPL *, WT_BLOCK *, WT_EXTLIST *, const char *);
static int __block_merge(WT_SESSION_IMPL *,
WT_BLOCK *, WT_EXTLIST *, wt_off_t, wt_off_t);
@@ -1227,8 +1227,7 @@ corrupted: __wt_scr_free(session, &tmp);
WT_ERR(func(session, block, el, off, size));
}
- if (WT_VERBOSE_ISSET(session, WT_VERB_BLOCK))
- WT_ERR(__block_extlist_dump(session, "read extlist", el, 0));
+ WT_ERR(__block_extlist_dump(session, block, el, "read"));
err: __wt_scr_free(session, &tmp);
return (ret);
@@ -1250,8 +1249,7 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session,
uint32_t entries;
uint8_t *p;
- if (WT_VERBOSE_ISSET(session, WT_VERB_BLOCK))
- WT_RET(__block_extlist_dump(session, "write extlist", el, 0));
+ WT_RET(__block_extlist_dump(session, block, el, "write"));
/*
* Figure out how many entries we're writing -- if there aren't any
@@ -1427,38 +1425,62 @@ __wt_block_extlist_free(WT_SESSION_IMPL *session, WT_EXTLIST *el)
*/
static int
__block_extlist_dump(
- WT_SESSION_IMPL *session, const char *tag, WT_EXTLIST *el, bool show_size)
+ WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, const char *tag)
{
+ WT_DECL_ITEM(t1);
+ WT_DECL_ITEM(t2);
+ WT_DECL_RET;
WT_EXT *ext;
- WT_SIZE *szp;
+ uint64_t pow, sizes[64];
+ u_int i;
+ const char *sep;
- WT_RET(__wt_verbose(session, WT_VERB_BLOCK,
- "%s: %s: %" PRIu64 " bytes, by offset:%s",
- tag, el->name, el->bytes, el->entries == 0 ? " [Empty]" : ""));
- if (el->entries == 0)
+ if (!block->verify_layout && !WT_VERBOSE_ISSET(session, WT_VERB_BLOCK))
return (0);
- WT_EXT_FOREACH(ext, el->off)
- WT_RET(__wt_verbose(session, WT_VERB_BLOCK,
- "\t{%" PRIuMAX "/%" PRIuMAX "}",
- (uintmax_t)ext->off, (uintmax_t)ext->size));
+ WT_ERR(__wt_scr_alloc(session, 0, &t1));
+ if (block->verify_layout)
+ WT_ERR(__wt_msg(session,
+ "%s extent list %s, %" PRIu32 " entries, %s bytes",
+ tag, el->name, el->entries,
+ __wt_buf_set_size(session, el->bytes, true, t1)));
+ else
+ WT_ERR(__wt_verbose(session, WT_VERB_BLOCK,
+ "%s extent list %s, %" PRIu32 " entries, %s bytes",
+ tag, el->name, el->entries,
+ __wt_buf_set_size(session, el->bytes, true, t1)));
- if (!show_size)
- return (0);
+ if (ret != 0 || el->entries == 0)
+ goto done;
- WT_RET(__wt_verbose(session, WT_VERB_BLOCK,
- "%s: %s: by size:%s",
- tag, el->name, el->entries == 0 ? " [Empty]" : ""));
- if (el->entries == 0)
- return (0);
+ memset(sizes, 0, sizeof(sizes));
+ WT_EXT_FOREACH(ext, el->off)
+ for (i = 9, pow = 512;; ++i, pow *= 2)
+ if (ext->size <= (wt_off_t)pow) {
+ ++sizes[i];
+ break;
+ }
+ sep = "extents by bucket:";
+ t1->size = 0;
+ WT_ERR(__wt_scr_alloc(session, 0, &t2));
+ for (i = 9, pow = 512; i < WT_ELEMENTS(sizes); ++i, pow *= 2)
+ if (sizes[i] != 0) {
+ WT_ERR(__wt_buf_catfmt(session, t1,
+ "%s {%s: %" PRIu64 "}",
+ sep,
+ __wt_buf_set_size(session, pow, false, t2),
+ sizes[i]));
+ sep = ",";
+ }
- WT_EXT_FOREACH(szp, el->sz) {
- WT_RET(__wt_verbose(session, WT_VERB_BLOCK,
- "\t{%" PRIuMAX "}", (uintmax_t)szp->size));
- WT_EXT_FOREACH_OFF(ext, szp->off)
- WT_RET(__wt_verbose(session, WT_VERB_BLOCK,
- "\t\t{%" PRIuMAX "/%" PRIuMAX "}",
- (uintmax_t)ext->off, (uintmax_t)ext->size));
- }
- return (0);
+ if (block->verify_layout)
+ WT_ERR(__wt_msg(session, "%s", (char *)t1->data));
+ else
+ WT_ERR(__wt_verbose(
+ session, WT_VERB_BLOCK, "%s", (char *)t1->data));
+
+done: err:
+ __wt_scr_free(session, &t1);
+ __wt_scr_free(session, &t2);
+ return (ret);
}
diff --git a/src/block/block_vrfy.c b/src/block/block_vrfy.c
index 36a73fac761..af58864b9dc 100644
--- a/src/block/block_vrfy.c
+++ b/src/block/block_vrfy.c
@@ -37,6 +37,14 @@ __wt_block_verify_start(WT_SESSION_IMPL *session,
WT_CONFIG_ITEM cval;
wt_off_t size;
+ /* Configuration: strict behavior on any error. */
+ WT_RET(__wt_config_gets(session, cfg, "strict", &cval));
+ block->verify_strict = cval.val != 0;
+
+ /* Configuration: dump the file's layout. */
+ WT_RET(__wt_config_gets(session, cfg, "dump_layout", &cval));
+ block->verify_layout = cval.val != 0;
+
/*
* Find the last checkpoint in the list: if there are none, or the only
* checkpoint we have is fake, there's no work to do. Don't complain,
@@ -107,9 +115,6 @@ __wt_block_verify_start(WT_SESSION_IMPL *session,
*/
WT_RET(__verify_last_avail(session, block, ckpt));
- /* Configuration: strict behavior on any error. */
- WT_RET(__wt_config_gets(session, cfg, "strict", &cval));
- block->verify_strict = cval.val != 0;
return (0);
}
@@ -154,11 +159,23 @@ __verify_set_file_size(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckpt)
{
WT_BLOCK_CKPT *ci, _ci;
WT_DECL_RET;
+ WT_DECL_ITEM(tmp);
ci = &_ci;
WT_RET(__wt_block_ckpt_init(session, ci, ckpt->name));
WT_ERR(__wt_block_buffer_to_ckpt(session, block, ckpt->raw.data, ci));
+ if (block->verify_layout) {
+ WT_ERR(__wt_scr_alloc(session, 0, &tmp));
+ WT_ERR(__wt_msg(session, "%s: physical size %s", block->name,
+ __wt_buf_set_size(
+ session, (uint64_t)block->size, true, tmp)));
+ WT_ERR(
+ __wt_msg(session, "%s: correcting to %s checkpoint size %s",
+ block->name, ckpt->name, __wt_buf_set_size(
+ session, (uint64_t)ci->file_size, true, tmp)));
+ }
+
/*
* Verify is read-only. Set the block's file size information as if we
* truncated the file during checkpoint load, so references to blocks
@@ -167,6 +184,7 @@ __verify_set_file_size(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckpt)
block->size = block->extend_size = ci->file_size;
err: __wt_block_ckpt_destroy(session, ci);
+ __wt_scr_free(session, &tmp);
return (ret);
}
@@ -255,9 +273,9 @@ __wt_verify_ckpt_load(
}
/*
- * We don't need to list of blocks on a checkpoint's avail list, but we
- * read it to ensure it wasn't corrupted. We could confirm correctness
- * of intermediate avail lists (that is, if they're logically the result
+ * We don't need the blocks on a checkpoint's avail list, but we read it
+ * to ensure it wasn't corrupted. We could confirm correctness of the
+ * intermediate avail lists (that is, if they're logically the result
* of the allocations and discards to this point). We don't because the
* only avail list ever used is the one for the last checkpoint, which
* is separately verified by checking it against all of the blocks found
diff --git a/src/btree/bt_misc.c b/src/btree/bt_misc.c
index 7f188502a0a..b6e2cc07f5a 100644
--- a/src/btree/bt_misc.c
+++ b/src/btree/bt_misc.c
@@ -129,19 +129,3 @@ __wt_addr_string(WT_SESSION_IMPL *session,
}
return (buf->data);
}
-
-/*
- * __wt_buf_set_printable --
- * Set the contents of the buffer to a printable representation of a
- * byte string.
- */
-const char *
-__wt_buf_set_printable(
- WT_SESSION_IMPL *session, const void *p, size_t size, WT_ITEM *buf)
-{
- if (__wt_raw_to_esc_hex(session, p, size, buf)) {
- buf->data = "[Error]";
- buf->size = strlen("[Error]");
- }
- return (buf->data);
-}
diff --git a/src/btree/bt_vrfy.c b/src/btree/bt_vrfy.c
index 531a0dc125a..0a04c387a0f 100644
--- a/src/btree/bt_vrfy.c
+++ b/src/btree/bt_vrfy.c
@@ -22,13 +22,13 @@ typedef struct {
#define WT_VRFY_DUMP(vs) \
((vs)->dump_address || \
- (vs)->dump_blocks || (vs)->dump_pages || (vs)->dump_shape)
+ (vs)->dump_blocks || (vs)->dump_layout || (vs)->dump_pages)
bool dump_address; /* Configure: dump special */
bool dump_blocks;
+ bool dump_layout;
bool dump_pages;
- bool dump_shape;
-
- u_int depth, depth_internal[100], depth_leaf[100];
+ /* Page layout information */
+ uint64_t depth, depth_internal[100], depth_leaf[100];
WT_ITEM *tmp1, *tmp2, *tmp3, *tmp4; /* Temporary buffers */
} WT_VSTUFF;
@@ -59,12 +59,12 @@ __verify_config(WT_SESSION_IMPL *session, const char *cfg[], WT_VSTUFF *vs)
WT_RET(__wt_config_gets(session, cfg, "dump_blocks", &cval));
vs->dump_blocks = cval.val != 0;
+ WT_RET(__wt_config_gets(session, cfg, "dump_layout", &cval));
+ vs->dump_layout = cval.val != 0;
+
WT_RET(__wt_config_gets(session, cfg, "dump_pages", &cval));
vs->dump_pages = cval.val != 0;
- WT_RET(__wt_config_gets(session, cfg, "dump_shape", &cval));
- vs->dump_shape = cval.val != 0;
-
#if !defined(HAVE_DIAGNOSTIC)
if (vs->dump_blocks || vs->dump_pages)
WT_RET_MSG(session, ENOTSUP,
@@ -112,33 +112,38 @@ __verify_config_offsets(
}
/*
- * __verify_tree_shape --
+ * __verify_layout --
* Dump the tree shape.
*/
static int
-__verify_tree_shape(WT_SESSION_IMPL *session, WT_VSTUFF *vs)
+__verify_layout(WT_SESSION_IMPL *session, WT_VSTUFF *vs)
{
- uint32_t total;
+ uint64_t total;
size_t i;
for (i = 0, total = 0; i < WT_ELEMENTS(vs->depth_internal); ++i)
total += vs->depth_internal[i];
WT_RET(__wt_msg(
- session, "Internal page tree-depth (total %" PRIu32 "):", total));
+ session, "Internal page tree-depth (total %" PRIu64 "):", total));
for (i = 0; i < WT_ELEMENTS(vs->depth_internal); ++i)
- if (vs->depth_internal[i] != 0)
+ if (vs->depth_internal[i] != 0) {
WT_RET(__wt_msg(session,
- "\t%03zu: %u", i, vs->depth_internal[i]));
+ "\t%03" WT_SIZET_FMT ": %" PRIu64,
+ i, vs->depth_internal[i]));
+ vs->depth_internal[i] = 0;
+ }
for (i = 0, total = 0; i < WT_ELEMENTS(vs->depth_leaf); ++i)
total += vs->depth_leaf[i];
WT_RET(__wt_msg(
- session, "Leaf page tree-depth (total %" PRIu32 "):", total));
+ session, "Leaf page tree-depth (total %" PRIu64 "):", total));
for (i = 0; i < WT_ELEMENTS(vs->depth_leaf); ++i)
- if (vs->depth_leaf[i] != 0)
+ if (vs->depth_leaf[i] != 0) {
WT_RET(__wt_msg(session,
- "\t%03zu: %u", i, vs->depth_leaf[i]));
-
+ "\t%03" WT_SIZET_FMT ": %" PRIu64,
+ i, vs->depth_leaf[i]));
+ vs->depth_leaf[i] = 0;
+ }
return (0);
}
@@ -200,9 +205,11 @@ __wt_verify(WT_SESSION_IMPL *session, const char *cfg[])
/* House-keeping between checkpoints. */
__verify_checkpoint_reset(vs);
- if (WT_VRFY_DUMP(vs))
+ if (WT_VRFY_DUMP(vs)) {
+ WT_ERR(__wt_msg(session, "%s", WT_DIVIDER));
WT_ERR(__wt_msg(session, "%s: checkpoint %s",
btree->dhandle->name, ckpt->name));
+ }
/* Load the checkpoint. */
WT_ERR(bm->checkpoint_load(bm, session,
@@ -234,8 +241,8 @@ __wt_verify(WT_SESSION_IMPL *session, const char *cfg[])
WT_ERR(ret);
/* Display the tree shape. */
- if (vs->dump_shape)
- WT_ERR(__verify_tree_shape(session, vs));
+ if (vs->dump_layout)
+ WT_ERR(__verify_layout(session, vs));
}
done:
diff --git a/src/config/config_def.c b/src/config/config_def.c
index 0d8308b48cc..1b656c5a0aa 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -380,9 +380,9 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_transaction_sync[] = {
static const WT_CONFIG_CHECK confchk_WT_SESSION_verify[] = {
{ "dump_address", "boolean", NULL, NULL, NULL, 0 },
{ "dump_blocks", "boolean", NULL, NULL, NULL, 0 },
+ { "dump_layout", "boolean", NULL, NULL, NULL, 0 },
{ "dump_offsets", "list", NULL, NULL, NULL, 0 },
{ "dump_pages", "boolean", NULL, NULL, NULL, 0 },
- { "dump_shape", "boolean", NULL, NULL, NULL, 0 },
{ "strict", "boolean", NULL, NULL, NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
};
@@ -1102,8 +1102,8 @@ static const WT_CONFIG_ENTRY config_entries[] = {
NULL, 0
},
{ "WT_SESSION.verify",
- "dump_address=0,dump_blocks=0,dump_offsets=,dump_pages=0,"
- "dump_shape=0,strict=0",
+ "dump_address=0,dump_blocks=0,dump_layout=0,dump_offsets=,"
+ "dump_pages=0,strict=0",
confchk_WT_SESSION_verify, 6
},
{ "colgroup.meta",
diff --git a/src/include/block.h b/src/include/block.h
index 9f652ceddb9..a8080c1651c 100644
--- a/src/include/block.h
+++ b/src/include/block.h
@@ -261,6 +261,7 @@ struct __wt_block {
/* Verification support */
bool verify; /* If performing verification */
+ bool verify_layout; /* Print out file layout information */
bool verify_strict; /* Fail hard on any error */
wt_off_t verify_size; /* Checkpoint's file size */
WT_EXTLIST verify_alloc; /* Verification allocation list */
diff --git a/src/include/extern.h b/src/include/extern.h
index 5bc36454c09..0033d9e9646 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -144,7 +144,6 @@ extern const char *__wt_page_type_string(u_int type);
extern const char *__wt_cell_type_string(uint8_t type);
extern const char *__wt_page_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf);
extern const char *__wt_addr_string(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size, WT_ITEM *buf);
-extern const char *__wt_buf_set_printable( WT_SESSION_IMPL *session, const void *p, size_t size, WT_ITEM *buf);
extern int __wt_ovfl_read(WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL_UNPACK *unpack, WT_ITEM *store);
extern int __wt_ovfl_cache(WT_SESSION_IMPL *session, WT_PAGE *page, void *cookie, WT_CELL_UNPACK *vpack);
extern int __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell);
@@ -654,6 +653,8 @@ extern uint32_t __wt_random(WT_RAND_STATE volatile *rnd_state);
extern int __wt_buf_grow_worker(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size);
extern int __wt_buf_fmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4)));
extern int __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4)));
+extern const char *__wt_buf_set_printable( WT_SESSION_IMPL *session, const void *p, size_t size, WT_ITEM *buf);
+extern const char *__wt_buf_set_size( WT_SESSION_IMPL *session, uint64_t size, bool exact, WT_ITEM *buf);
extern int
__wt_scr_alloc_func(WT_SESSION_IMPL *session, size_t size, WT_ITEM **scratchp
#ifdef HAVE_DIAGNOSTIC
diff --git a/src/include/misc.h b/src/include/misc.h
index e33139387cf..1121b7dfa75 100644
--- a/src/include/misc.h
+++ b/src/include/misc.h
@@ -12,6 +12,8 @@
*/
#define WT_UNUSED(var) (void)(var)
+#define WT_DIVIDER "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="
+
/* Basic constants. */
#define WT_THOUSAND (1000)
#define WT_MILLION (1000000)
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index e488812477e..4168b3d070a 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1466,15 +1466,16 @@ struct __wt_session {
* @config{dump_blocks, Display the contents of on-disk blocks as they
* are verified\, using the application's message handler\, intended for
* debugging., a boolean flag; default \c false.}
+ * @config{dump_layout, Display the layout of the files as they are
+ * verified\, using the application's message handler\, intended for
+ * debugging; requires optional support from the block manager., a
+ * boolean flag; default \c false.}
* @config{dump_offsets, Display the contents of specific on-disk
* blocks\, using the application's message handler\, intended for
* debugging., a list of strings; default empty.}
* @config{dump_pages, Display the contents of in-memory pages as they
* are verified\, using the application's message handler\, intended for
* debugging., a boolean flag; default \c false.}
- * @config{dump_shape, Display the shape of the tree after
- * verification\, using the application's message handler\, intended for
- * debugging., a boolean flag; default \c false.}
* @config{strict, Treat any verification problem as an error; by
* default\, verify will warn\, but not fail\, in the case of errors
* that won't affect future behavior (for example\, a leaked block)., a
diff --git a/src/support/scratch.c b/src/support/scratch.c
index 1881f8ad5a5..69987ebc852 100644
--- a/src/support/scratch.c
+++ b/src/support/scratch.c
@@ -135,6 +135,64 @@ __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...)
}
/*
+ * __wt_buf_set_printable --
+ * Set the contents of the buffer to a printable representation of a
+ * byte string.
+ */
+const char *
+__wt_buf_set_printable(
+ WT_SESSION_IMPL *session, const void *p, size_t size, WT_ITEM *buf)
+{
+ if (__wt_raw_to_esc_hex(session, p, size, buf)) {
+ buf->data = "[Error]";
+ buf->size = strlen("[Error]");
+ }
+ return (buf->data);
+}
+
+/*
+ * __wt_buf_set_size --
+ * Set the contents of the buffer to a printable representation of a
+ * byte size.
+ */
+const char *
+__wt_buf_set_size(
+ WT_SESSION_IMPL *session, uint64_t size, bool exact, WT_ITEM *buf)
+{
+ WT_DECL_RET;
+
+ if (size >= WT_EXABYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "EB", size / WT_EXABYTE);
+ else if (size >= WT_PETABYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "PB", size / WT_PETABYTE);
+ else if (size >= WT_TERABYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "TB", size / WT_TERABYTE);
+ else if (size >= WT_GIGABYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "GB", size / WT_GIGABYTE);
+ else if (size >= WT_MEGABYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "MB", size / WT_MEGABYTE);
+ else if (size >= WT_KILOBYTE)
+ ret = __wt_buf_fmt(session, buf,
+ "%" PRIu64 "KB", size / WT_KILOBYTE);
+ else
+ ret = __wt_buf_fmt(session, buf, "%" PRIu64 "B", size);
+
+ if (ret == 0 && exact && size >= WT_KILOBYTE)
+ ret = __wt_buf_catfmt(session, buf, " (%" PRIu64 ")", size);
+
+ if (ret != 0) {
+ buf->data = "[Error]";
+ buf->size = strlen("[Error]");
+ }
+ return (buf->data);
+}
+
+/*
* __wt_scr_alloc_func --
* Scratch buffer allocation function.
*/
diff --git a/src/utilities/util_verify.c b/src/utilities/util_verify.c
index 2df4fa65f43..82bdd780cd3 100644
--- a/src/utilities/util_verify.c
+++ b/src/utilities/util_verify.c
@@ -16,10 +16,10 @@ util_verify(WT_SESSION *session, int argc, char *argv[])
WT_DECL_RET;
size_t size;
int ch;
- bool dump_address, dump_blocks, dump_pages, dump_shape;
+ bool dump_address, dump_blocks, dump_layout, dump_pages;
char *config, *dump_offsets, *name;
- dump_address = dump_blocks = dump_pages = dump_shape = false;
+ dump_address = dump_blocks = dump_layout = dump_pages = false;
config = dump_offsets = name = NULL;
while ((ch = __wt_getopt(progname, argc, argv, "d:")) != EOF)
switch (ch) {
@@ -28,6 +28,8 @@ util_verify(WT_SESSION *session, int argc, char *argv[])
dump_address = true;
else if (strcmp(__wt_optarg, "dump_blocks") == 0)
dump_blocks = true;
+ else if (strcmp(__wt_optarg, "dump_layout") == 0)
+ dump_layout = true;
else if (
WT_PREFIX_MATCH(__wt_optarg, "dump_offsets=")) {
if (dump_offsets != NULL) {
@@ -40,8 +42,6 @@ util_verify(WT_SESSION *session, int argc, char *argv[])
__wt_optarg + strlen("dump_offsets=");
} else if (strcmp(__wt_optarg, "dump_pages") == 0)
dump_pages = true;
- else if (strcmp(__wt_optarg, "dump_shape") == 0)
- dump_shape = true;
else
return (usage());
break;
@@ -60,12 +60,12 @@ util_verify(WT_SESSION *session, int argc, char *argv[])
/* Build the configuration string as necessary. */
if (dump_address ||
- dump_blocks || dump_offsets != NULL || dump_pages || dump_shape) {
+ dump_blocks || dump_layout || dump_offsets != NULL || dump_pages) {
size =
strlen("dump_address,") +
strlen("dump_blocks,") +
+ strlen("dump_layout,") +
strlen("dump_pages,") +
- strlen("dump_shape,") +
strlen("dump_offsets[],") +
(dump_offsets == NULL ? 0 : strlen(dump_offsets)) + 20;
if ((config = malloc(size)) == NULL) {
@@ -76,11 +76,11 @@ util_verify(WT_SESSION *session, int argc, char *argv[])
"%s%s%s%s%s%s%s",
dump_address ? "dump_address," : "",
dump_blocks ? "dump_blocks," : "",
+ dump_layout ? "dump_layout," : "",
dump_offsets != NULL ? "dump_offsets=[" : "",
dump_offsets != NULL ? dump_offsets : "",
dump_offsets != NULL ? "]," : "",
- dump_pages ? "dump_pages," : "",
- dump_shape ? "dump_shape," : "");
+ dump_pages ? "dump_pages," : "");
}
if ((ret = session->verify(session, name, config)) != 0) {
fprintf(stderr, "%s: verify(%s): %s\n",
@@ -109,7 +109,7 @@ usage(void)
"usage: %s %s "
"verify %s\n",
progname, usage_prefix,
- "[-d dump_address | dump_blocks | "
- "dump_offsets=#,# | dump_pages | dump_shape] uri");
+ "[-d dump_address | dump_blocks | dump_layout | "
+ "dump_offsets=#,# | dump_pages] uri");
return (1);
}