diff --git a/src/parser/show_meta.c b/src/parser/show_meta.c index 3b9d8d97d63..cea7d3f1f58 100644 --- a/src/parser/show_meta.c +++ b/src/parser/show_meta.c @@ -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"}, @@ -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[] = { diff --git a/src/storage/btree.c b/src/storage/btree.c index b0835246eee..7e50adc4e55 100644 --- a/src/storage/btree.c +++ b/src/storage/btree.c @@ -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); @@ -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++) { @@ -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; @@ -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++) { @@ -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); @@ -8669,6 +8658,8 @@ 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) @@ -8676,25 +8667,52 @@ btree_get_subtree_capacity (THREAD_ENTRY * thread_p, BTID_INT * btid, PAGE_PTR p 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: @@ -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); @@ -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: @@ -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: diff --git a/src/storage/btree.h b/src/storage/btree.h index ddb5dd9723e..67c903547d5 100644 --- a/src/storage/btree.h +++ b/src/storage/btree.h @@ -351,11 +351,22 @@ struct btree_checkscan BTREE_ISCAN_OID_LIST oid_list; /* Data area to store OIDs */ }; /* B+tree 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 */ @@ -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 */ }; /*