Skip to content

Commit

Permalink
[CBRD-24425] Add overflow page information when showing the index cap…
Browse files Browse the repository at this point in the history
…acity (#3738)

http://jira.cubrid.org/browse/CBRD-24425

affected subjects
* SHOW INDEX CAPACITY OF 
* SHOW ALL INDEXES CAPACITY OF 
* cubrid diagdb -d 4
  • Loading branch information
ctshim authored Jul 27, 2022
1 parent c992e37 commit 490f75a
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 80 deletions.
9 changes: 7 additions & 2 deletions src/parser/show_meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,10 @@ metadata_of_index_capacity (SHOW_ONLY_ALL flag)
{"Index_name", "varchar(256)"},
{"Btid", "varchar(64)"},
{"Num_distinct_key", "int"},
{"Total_value", "int"},
{"Total_value", "bigint"},
{"Avg_num_value_per_key", "int"},
{"Num_leaf_page", "int"},
{"Num_Ovfl_page", "int"},
{"Num_non_leaf_page", "int"},
{"Num_total_page", "int"},
{"Height", "int"},
Expand All @@ -456,7 +457,11 @@ metadata_of_index_capacity (SHOW_ONLY_ALL flag)
{"Total_used_space", "varchar(64)"},
{"Total_free_space", "varchar(64)"},
{"Avg_num_page_key", "int"},
{"Avg_page_free_space", "varchar(64)"}
{"Avg_page_free_space", "varchar(64)"},
{"Percentage_free_space_Ovfl_page", "int"},
{"Average_free_space_per_Ovfl_page", "int"},
{"Average_Ovfl_page_count_per_key", "int"},
{"Max_Ovfl_page_count_in_a_key", "int"}
};

static const SHOWSTMT_COLUMN_ORDERBY orderby[] = {
Expand Down
201 changes: 124 additions & 77 deletions src/storage/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -8542,22 +8542,7 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
btree_init_temp_key_value (&clear_key, &key1);

/* initialize capacity structure */
cpc->dis_key_cnt = 0;
cpc->tot_val_cnt = 0;
cpc->avg_val_per_key = 0;
cpc->leaf_pg_cnt = 0;
cpc->nleaf_pg_cnt = 0;
cpc->tot_pg_cnt = 0;
cpc->height = 0;
cpc->sum_rec_len = 0;
cpc->sum_key_len = 0;
cpc->avg_key_len = 0;
cpc->avg_rec_len = 0;
cpc->tot_free_space = 0;
cpc->tot_space = 0;
cpc->tot_used_space = 0;
cpc->avg_pg_key_cnt = 0;
cpc->avg_pg_free_sp = 0;
memset (cpc, 0x00, sizeof (BTREE_CAPACITY));

free_space = spage_get_free_space (thread_p, pg_ptr);

Expand All @@ -8575,6 +8560,8 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
{ /* a non-leaf page */
BTREE_CAPACITY cpc2;

cpc->nleaf_pg_cnt += 1;

/* traverse all the subtrees of this non_leaf page and accumulate the statistical data in the cpc structure */
for (i = 1; i <= key_cnt; i++)
{
Expand All @@ -8595,6 +8582,7 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
#endif /* !NDEBUG */

ret = btree_get_subtree_capacity (thread_p, btid, page, &cpc2);
pgbuf_unfix_and_init (thread_p, page);
if (ret != NO_ERROR)
{
goto exit_on_error;
Expand All @@ -8612,27 +8600,23 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
cpc->tot_free_space += cpc2.tot_free_space;
cpc->tot_space += cpc2.tot_space;
cpc->tot_used_space += cpc2.tot_used_space;
pgbuf_unfix_and_init (thread_p, page);

cpc->ovfl_oid_pg.tot_free_space += cpc2.ovfl_oid_pg.tot_free_space;
cpc->ovfl_oid_pg.tot_pg_cnt += cpc2.ovfl_oid_pg.tot_pg_cnt;
cpc->ovfl_oid_pg.tot_space += cpc2.ovfl_oid_pg.tot_space;
cpc->ovfl_oid_pg.dis_key_cnt += cpc2.ovfl_oid_pg.dis_key_cnt;
cpc->ovfl_oid_pg.tot_val_cnt += cpc2.ovfl_oid_pg.tot_val_cnt;
if (cpc->ovfl_oid_pg.max_pg_cnt_per_key < cpc2.ovfl_oid_pg.max_pg_cnt_per_key)
{
cpc->ovfl_oid_pg.max_pg_cnt_per_key = cpc2.ovfl_oid_pg.max_pg_cnt_per_key;
}
} /* for */
cpc->avg_val_per_key = ((cpc->dis_key_cnt > 0) ? (cpc->tot_val_cnt / cpc->dis_key_cnt) : 0);
cpc->nleaf_pg_cnt += 1;
cpc->tot_pg_cnt += 1;
cpc->tot_free_space += free_space;
cpc->tot_space += DB_PAGESIZE;
cpc->tot_used_space += (DB_PAGESIZE - free_space);
cpc->avg_key_len = ((cpc->dis_key_cnt > 0) ? ((int) (cpc->sum_key_len / cpc->dis_key_cnt)) : 0);
cpc->avg_rec_len = ((cpc->dis_key_cnt > 0) ? ((int) (cpc->sum_rec_len / cpc->dis_key_cnt)) : 0);
cpc->avg_pg_key_cnt = ((cpc->leaf_pg_cnt > 0) ? ((int) (cpc->dis_key_cnt / cpc->leaf_pg_cnt)) : 0);
cpc->avg_pg_free_sp = ((cpc->tot_pg_cnt > 0) ? (cpc->tot_free_space / cpc->tot_pg_cnt) : 0);
}
else
{ /* a leaf page */

/* form the cpc structure for a leaf node page */
cpc->dis_key_cnt = key_cnt;
cpc->leaf_pg_cnt = 1;
cpc->nleaf_pg_cnt = 0;
cpc->tot_pg_cnt = 1;
cpc->height = 1;
for (i = 1; i <= cpc->dis_key_cnt; i++)
{
Expand All @@ -8657,6 +8641,11 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
ovfl_vpid = leaf_pnt.ovfl;
if (!VPID_ISNULL (&ovfl_vpid))
{ /* overflow pages exist */
int free_space_ovfl, oid_cnt_ovfl, pg_cnt_per_key;

oid_cnt_ovfl = 0;
pg_cnt_per_key = 0;
cpc->ovfl_oid_pg.dis_key_cnt += 1;
do
{
ovfp = pgbuf_fix (thread_p, &ovfl_vpid, OLD_PAGE, PGBUF_LATCH_READ, PGBUF_UNCONDITIONAL_LATCH);
Expand All @@ -8669,32 +8658,61 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p
(void) pgbuf_check_page_ptype (thread_p, ovfp, PAGE_BTREE);
#endif /* !NDEBUG */

free_space_ovfl = spage_get_free_space (thread_p, ovfp);

btree_get_next_overflow_vpid (thread_p, ovfp, &ovfl_vpid);

if (spage_get_record (thread_p, ovfp, 1, &orec, PEEK) != S_SUCCESS)
{
goto exit_on_error;
}

oid_cnt += btree_record_get_num_oids (thread_p, btid, &orec, 0, BTREE_OVERFLOW_NODE);
oid_cnt_ovfl += btree_record_get_num_oids (thread_p, btid, &orec, 0, BTREE_OVERFLOW_NODE);
pgbuf_unfix_and_init (thread_p, ovfp);

cpc->ovfl_oid_pg.tot_free_space += free_space_ovfl;
cpc->ovfl_oid_pg.tot_space += DB_PAGESIZE;

cpc->ovfl_oid_pg.tot_pg_cnt += 1;
pg_cnt_per_key++;
}
while (!VPID_ISNULL (&ovfl_vpid));

if (cpc->ovfl_oid_pg.max_pg_cnt_per_key < pg_cnt_per_key)
{
cpc->ovfl_oid_pg.max_pg_cnt_per_key = pg_cnt_per_key;
}

cpc->ovfl_oid_pg.tot_val_cnt += oid_cnt_ovfl;
oid_cnt += oid_cnt_ovfl;
} /* if */
cpc->tot_val_cnt += oid_cnt;

cpc->tot_val_cnt += oid_cnt;
} /* for */
cpc->avg_val_per_key = ((cpc->dis_key_cnt > 0) ? (cpc->tot_val_cnt / cpc->dis_key_cnt) : 0);
cpc->avg_key_len = ((cpc->dis_key_cnt > 0) ? ((int) (cpc->sum_key_len / cpc->dis_key_cnt)) : 0);
cpc->avg_rec_len = ((cpc->dis_key_cnt > 0) ? ((int) (cpc->sum_rec_len / cpc->dis_key_cnt)) : 0);
cpc->tot_free_space = (float) free_space;
cpc->tot_space = DB_PAGESIZE;
cpc->tot_used_space = (cpc->tot_space - cpc->tot_free_space);
cpc->avg_pg_key_cnt = ((cpc->leaf_pg_cnt > 0) ? (cpc->dis_key_cnt / cpc->leaf_pg_cnt) : 0);
cpc->avg_pg_free_sp = ((cpc->tot_pg_cnt > 0) ? (cpc->tot_free_space / cpc->tot_pg_cnt) : 0);

} /* if-else */

cpc->tot_pg_cnt += 1;
cpc->tot_free_space += (float) free_space;
cpc->tot_space += DB_PAGESIZE;
cpc->tot_used_space = (cpc->tot_space - cpc->tot_free_space);

if (cpc->dis_key_cnt > 0)
{
cpc->avg_val_per_key = (int) (cpc->tot_val_cnt / cpc->dis_key_cnt);
cpc->avg_key_len = (int) (cpc->sum_key_len / cpc->dis_key_cnt);
cpc->avg_rec_len = (int) (cpc->sum_rec_len / cpc->dis_key_cnt);
}
if (cpc->leaf_pg_cnt > 0)
{
cpc->avg_pg_key_cnt = (int) (cpc->dis_key_cnt / cpc->leaf_pg_cnt);
}

cpc->avg_pg_free_sp = cpc->tot_free_space / cpc->tot_pg_cnt;
if (cpc->ovfl_oid_pg.tot_pg_cnt > 0)
{
cpc->ovfl_oid_pg.avg_pg_free_sp = cpc->ovfl_oid_pg.tot_free_space / cpc->ovfl_oid_pg.tot_pg_cnt;
}

return ret;

exit_on_error:
Expand Down Expand Up @@ -8831,11 +8849,12 @@ btree_dump_capacity (THREAD_ENTRY * thread_p, FILE * fp, BTID * btid)

/* dump the capacity information */
fprintf (fp, "\nDistinct Key Count: %d\n", cpc.dis_key_cnt);
fprintf (fp, "Total Value Count: %d\n", cpc.tot_val_cnt);
fprintf (fp, "Total Value Count: %lld\n", cpc.tot_val_cnt);
fprintf (fp, "Average Value Count Per Key: %d\n", cpc.avg_val_per_key);
fprintf (fp, "Total Page Count: %d\n", cpc.tot_pg_cnt);
fprintf (fp, "Total Page Count: %d\n", cpc.tot_pg_cnt + cpc.ovfl_oid_pg.tot_pg_cnt);
fprintf (fp, "Leaf Page Count: %d\n", cpc.leaf_pg_cnt);
fprintf (fp, "NonLeaf Page Count: %d\n", cpc.nleaf_pg_cnt);
fprintf (fp, "Overflow Page Count: %d\n", cpc.ovfl_oid_pg.tot_pg_cnt);
fprintf (fp, "Height: %d\n", cpc.height);
fprintf (fp, "Average Key Length: %d\n", cpc.avg_key_len);
fprintf (fp, "Average Record Length: %d\n", cpc.avg_rec_len);
Expand All @@ -8844,6 +8863,13 @@ btree_dump_capacity (THREAD_ENTRY * thread_p, FILE * fp, BTID * btid)
fprintf (fp, "Free Index Space: %.0f bytes\n", cpc.tot_free_space);
fprintf (fp, "Average Page Free Space: %.0f bytes\n", cpc.avg_pg_free_sp);
fprintf (fp, "Average Page Key Count: %d\n", cpc.avg_pg_key_cnt);
fprintf (fp, "Percentage of Free Space on Overflow Page: %d \n",
(cpc.ovfl_oid_pg.tot_space > 0) ?
(int) ((cpc.ovfl_oid_pg.tot_free_space / cpc.ovfl_oid_pg.tot_space) * 100) : 0);
fprintf (fp, "Average Overflow Free Space per Page: %d bytes\n", (int) cpc.ovfl_oid_pg.avg_pg_free_sp);
fprintf (fp, "Average Overflow Page Count Per Key: %d\n",
(cpc.ovfl_oid_pg.dis_key_cnt > 0) ? (int) (cpc.ovfl_oid_pg.tot_pg_cnt / cpc.ovfl_oid_pg.dis_key_cnt) : 0);
fprintf (fp, "Max Overflow Page Count in a Key: %d\n", cpc.ovfl_oid_pg.max_pg_cnt_per_key);
fprintf (fp, "-------------------------------------------------------------\n");

exit:
Expand Down Expand Up @@ -22259,90 +22285,111 @@ btree_scan_for_show_index_capacity (THREAD_ENTRY * thread_p, DB_VALUE ** out_val
}

/* scan index capacity into out_values */
error = db_make_string_copy (out_values[idx], class_name);
idx++;
/* Refer to metadata_of_index_capacity for the order of out_values */

// {"Table_name", "varchar(256)"}
error = db_make_string_copy (out_values[idx++], class_name);
if (error != NO_ERROR)
{
goto cleanup;
}

error = db_make_string_copy (out_values[idx], index_p->btname);
idx++;
// {"Index_name", "varchar(256)"}
error = db_make_string_copy (out_values[idx++], index_p->btname);
if (error != NO_ERROR)
{
goto cleanup;
}

// {"Btid", "varchar(64)"}
(void) btid_to_string (buf, sizeof (buf), btid_p);
error = db_make_string_copy (out_values[idx], buf);
idx++;
error = db_make_string_copy (out_values[idx++], buf);
if (error != NO_ERROR)
{
goto cleanup;
}

db_make_int (out_values[idx], cpc.dis_key_cnt);
idx++;
// {"Num_distinct_key", "int"}
db_make_int (out_values[idx++], cpc.dis_key_cnt);

db_make_int (out_values[idx], cpc.tot_val_cnt);
idx++;
// {"Total_value", "bigint"}
db_make_bigint (out_values[idx++], cpc.tot_val_cnt);

db_make_int (out_values[idx], cpc.avg_val_per_key);
idx++;
// {"Avg_num_value_per_key", "int"}
db_make_int (out_values[idx++], cpc.avg_val_per_key);

db_make_int (out_values[idx], cpc.leaf_pg_cnt);
idx++;
// {"Num_leaf_page", "int"}
db_make_int (out_values[idx++], cpc.leaf_pg_cnt);

db_make_int (out_values[idx], cpc.nleaf_pg_cnt);
idx++;
// {"Num_Ovfl_page", "int"}
db_make_int (out_values[idx++], cpc.ovfl_oid_pg.tot_pg_cnt);

db_make_int (out_values[idx], cpc.tot_pg_cnt);
idx++;
// {"Num_non_leaf_page", "int"}
db_make_int (out_values[idx++], cpc.nleaf_pg_cnt);

db_make_int (out_values[idx], cpc.height);
idx++;
// {"Num_total_page", "int"}
db_make_int (out_values[idx++], cpc.tot_pg_cnt + cpc.ovfl_oid_pg.tot_pg_cnt);

db_make_int (out_values[idx], cpc.avg_key_len);
idx++;
// {"Height", "int"}
db_make_int (out_values[idx++], cpc.height);

db_make_int (out_values[idx], cpc.avg_rec_len);
idx++;
// {"Avg_key_len", "int"}
db_make_int (out_values[idx++], cpc.avg_key_len);

// {"Avg_rec_len", "int"}
db_make_int (out_values[idx++], cpc.avg_rec_len);

// {"Total_space", "varchar(64)"}
(void) util_byte_to_size_string (buf, 64, (UINT64) (cpc.tot_space));
error = db_make_string_copy (out_values[idx], buf);
idx++;
error = db_make_string_copy (out_values[idx++], buf);
if (error != NO_ERROR)
{
goto cleanup;
}

// {"Total_used_space", "varchar(64)"}
(void) util_byte_to_size_string (buf, 64, (UINT64) (cpc.tot_used_space));
error = db_make_string_copy (out_values[idx], buf);
idx++;
error = db_make_string_copy (out_values[idx++], buf);
if (error != NO_ERROR)
{
goto cleanup;
}

// {"Total_free_space", "varchar(64)"}
(void) util_byte_to_size_string (buf, 64, (UINT64) (cpc.tot_free_space));
error = db_make_string_copy (out_values[idx], buf);
idx++;
error = db_make_string_copy (out_values[idx++], buf);
if (error != NO_ERROR)
{
goto cleanup;
}

db_make_int (out_values[idx], cpc.avg_pg_key_cnt);
idx++;
// {"Avg_num_page_key", "int"}
db_make_int (out_values[idx++], cpc.avg_pg_key_cnt);

// {"Avg_page_free_space", "varchar(64)"}
(void) util_byte_to_size_string (buf, 64, (UINT64) (cpc.avg_pg_free_sp));
error = db_make_string_copy (out_values[idx], buf);
idx++;
error = db_make_string_copy (out_values[idx++], buf);
if (error != NO_ERROR)
{
goto cleanup;
}

// {"Percentage_free_space_Ovfl_page", "int"}
db_make_int (out_values[idx++],
(cpc.ovfl_oid_pg.tot_space > 0) ?
(int) ((cpc.ovfl_oid_pg.tot_free_space / cpc.ovfl_oid_pg.tot_space) * 100) : 0);

// {"Average_free_space_per_Ovfl_page", "int"}
db_make_int (out_values[idx++], (int) cpc.ovfl_oid_pg.avg_pg_free_sp);

// {"Average_Ovfl_page_count_per_key", "int"}
db_make_int (out_values[idx++],
(cpc.ovfl_oid_pg.dis_key_cnt > 0) ?
(int) (cpc.ovfl_oid_pg.tot_pg_cnt / cpc.ovfl_oid_pg.dis_key_cnt) : 0);

// {"Max_Ovfl_page_count_in_a_key", "int"}
db_make_int (out_values[idx++], cpc.ovfl_oid_pg.max_pg_cnt_per_key);

assert (idx == out_cnt);

cleanup:
Expand Down
14 changes: 13 additions & 1 deletion src/storage/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,22 @@ struct btree_checkscan
BTREE_ISCAN_OID_LIST oid_list; /* Data area to store OIDs */
}; /* B+tree <key-oid> check scan structure */

struct btree_ovfl_oid_capacity
{
int max_pg_cnt_per_key; /* Distinct key count with overflow oid page) */
int dis_key_cnt; /* Distinct key count (with ovfl pages) */
int64_t tot_val_cnt; /* Total number of values stored in overflow oid pages */
int tot_pg_cnt; /* Total overflow oid page count */
float tot_free_space; /* Total free space in overflow oid pages */
float tot_space; /* Total space occupied by overflow oid pages */
float avg_pg_free_sp; /* Average free space on the occupied overflowoid page */
};

typedef struct btree_capacity BTREE_CAPACITY;
struct btree_capacity
{
int dis_key_cnt; /* Distinct key count (in leaf pages) */
int tot_val_cnt; /* Total number of values stored in tree */
int64_t tot_val_cnt; /* Total number of values stored in tree */
int avg_val_per_key; /* Average number of values (OIDs) per key */
int leaf_pg_cnt; /* Leaf page count */
int nleaf_pg_cnt; /* NonLeaf page count */
Expand All @@ -370,6 +381,7 @@ struct btree_capacity
float tot_used_space; /* Total used space in index */
int avg_pg_key_cnt; /* Average page key count (in leaf pages) */
float avg_pg_free_sp; /* Average page free space */
struct btree_ovfl_oid_capacity ovfl_oid_pg; /* For overflow OID page */
};

/*
Expand Down

0 comments on commit 490f75a

Please sign in to comment.