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

gstat: Print detailed blob statistics and table size #8394

Merged
merged 2 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions src/include/firebird/impl/msg/gstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ FB_IMPL_MSG_NO_SYMBOL(GSTAT, 59, "Gstat execution time @1")
FB_IMPL_MSG_NO_SYMBOL(GSTAT, 60, "Gstat completion time @1")
FB_IMPL_MSG_NO_SYMBOL(GSTAT, 61, " Expected page inventory page @1")
FB_IMPL_MSG_NO_SYMBOL(GSTAT, 62, "Generator pages: total @1, encrypted @2, non-crypted @3")
FB_IMPL_MSG_NO_SYMBOL(GSTAT, 63, " Table size: @1 bytes")
FB_IMPL_MSG_NO_SYMBOL(GSTAT, 64, " Level @1: @2, total length: @3, blob pages: @4")
98 changes: 70 additions & 28 deletions src/utilities/gstat/dba.epp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,22 @@ struct dba_fmt
bool fmt_used;
};

inline constexpr ULONG MAX_BLOB_LEVELS = 3;
struct dba_blob_statistics
{
FB_UINT64 blob_count = 0;
FB_UINT64 blob_space = 0;
hvlad marked this conversation as resolved.
Show resolved Hide resolved
FB_UINT64 blob_pages = 0;

dba_blob_statistics& operator+=(const dba_blob_statistics& rhs)
{
blob_count += rhs.blob_count;
blob_space += rhs.blob_space;
blob_pages += rhs.blob_pages;
return *this;
}
};

struct dba_rel
{
dba_rel* rel_next;
Expand All @@ -147,10 +163,7 @@ struct dba_rel
FB_UINT64 rel_fragments;
FB_UINT64 rel_fragment_space;
FB_UINT64 rel_max_fragments;
FB_UINT64 rel_blobs_level_0;
FB_UINT64 rel_blobs_level_1;
FB_UINT64 rel_blobs_level_2;
FB_UINT64 rel_blob_space;
dba_blob_statistics rel_blob_statistics[MAX_BLOB_LEVELS];
ULONG rel_fill_distribution[BUCKETS];
FB_UINT64 rel_format_space;
FB_UINT64 rel_total_space;
Expand Down Expand Up @@ -1024,16 +1037,46 @@ int gstat(Firebird::UtilSvc* uSvc)
// msg 47: " Big record pages: @1
}

if (relation->rel_blobs_level_0 || relation->rel_blobs_level_1 || relation->rel_blobs_level_2)
// Blobs are analyzing only when the record option is set
if (sw_record)
{
dba_print(false, 48, SafeArg() << (relation->rel_blobs_level_0 + relation->rel_blobs_level_1 +
relation->rel_blobs_level_2) << relation->rel_blob_space <<
relation->rel_blob_pages);
// msg 48: " Blobs: @1, total length: @2, blob pages: @3

dba_print(false, 49, SafeArg() << relation->rel_blobs_level_0 << relation->rel_blobs_level_1 <<
relation->rel_blobs_level_2);
// msg 49: " Level 0: @1, Level 1: @2, Level 2: @3
dba_blob_statistics blobsTotal;
for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
{
blobsTotal += relation->rel_blob_statistics[i];
}

if (blobsTotal.blob_count)
{
dba_print(false, 48, SafeArg()
<< blobsTotal.blob_count
<< blobsTotal.blob_space
<< blobsTotal.blob_pages);
// msg 48: " Blobs: @1, total length: @2, blob pages: @3

for (ULONG i = 0; i < MAX_BLOB_LEVELS; ++i)
{
const dba_blob_statistics& blob_level = relation->rel_blob_statistics[i];

if (blob_level.blob_count > 0)
{
dba_print(false, 49, SafeArg()
<< i
<< blob_level.blob_count
<< blob_level.blob_space
<< blob_level.blob_pages);
// msg 64: " Level @1: @2, total length: @3, blob pages: @4
}
}
}


const FB_SIZE_T tableSize = tddba->page_size * (
relation->rel_pointer_pages +
relation->rel_data_pages +
blobsTotal.blob_pages);

dba_print(false, 63, SafeArg() << tableSize); // msg 63: "Table size: @1 bytes
}

dba_print(false, 13); // msg 13: " Fill distribution:"
Expand Down Expand Up @@ -1401,32 +1444,31 @@ static bool analyze_data_page( dba_rel* relation, const data_page* page, bool sw

static void analyze_blob(dba_rel* relation, const blh* blob, int length)
{
relation->rel_blob_space += blob->blh_length;
if (!blob->blh_level)
{
relation->rel_blobs_level_0++;
}
else
fb_assert(blob->blh_level < MAX_BLOB_LEVELS);
dba_blob_statistics& blob_level = relation->rel_blob_statistics[blob->blh_level];

++blob_level.blob_count;
blob_level.blob_space += blob->blh_length;

if (blob->blh_level != 0)
{
const int slots = (length - BLH_SIZE) / static_cast<int>(sizeof(SLONG));
relation->rel_blob_pages += slots;
if (blob->blh_level == 1)
{
relation->rel_blobs_level_1++;
}
else
{
relation->rel_blobs_level_2++;
ULONG blobPages = slots;

if (blob->blh_level == 2)
{
SLONG pages[MAX_PAGE_SIZE / sizeof(SLONG)];
memcpy(pages, blob->blh_page, slots * sizeof(SLONG));

for (int i = 0; i < slots; i++)
{
const blob_page* bpage = (const blob_page*) db_read(pages[i]);
relation->rel_blob_pages += bpage->blp_length / sizeof(SLONG);
blobPages += bpage->blp_length / sizeof(SLONG);
}
}

relation->rel_blob_pages += blobPages;
blob_level.blob_pages += blobPages;
}
}

Expand Down
Loading