|
|
|
@ -59,19 +59,19 @@ PG_FUNCTION_INFO_V1(pg_relpages); |
|
|
|
|
typedef struct BTIndexStat |
|
|
|
|
{ |
|
|
|
|
uint32 version; |
|
|
|
|
BlockNumber root_blkno; |
|
|
|
|
uint32 level; |
|
|
|
|
BlockNumber root_blkno; |
|
|
|
|
|
|
|
|
|
uint32 root_pages; |
|
|
|
|
uint32 internal_pages; |
|
|
|
|
uint32 leaf_pages; |
|
|
|
|
uint32 empty_pages; |
|
|
|
|
uint32 deleted_pages; |
|
|
|
|
uint64 root_pages; |
|
|
|
|
uint64 internal_pages; |
|
|
|
|
uint64 leaf_pages; |
|
|
|
|
uint64 empty_pages; |
|
|
|
|
uint64 deleted_pages; |
|
|
|
|
|
|
|
|
|
uint32 max_avail; |
|
|
|
|
uint32 free_space; |
|
|
|
|
uint64 max_avail; |
|
|
|
|
uint64 free_space; |
|
|
|
|
|
|
|
|
|
uint32 fragments; |
|
|
|
|
uint64 fragments; |
|
|
|
|
} BTIndexStat; |
|
|
|
|
|
|
|
|
|
/* ------------------------------------------------------
|
|
|
|
@ -87,8 +87,8 @@ pgstatindex(PG_FUNCTION_ARGS) |
|
|
|
|
Relation rel; |
|
|
|
|
RangeVar *relrv; |
|
|
|
|
Datum result; |
|
|
|
|
uint32 nblocks; |
|
|
|
|
uint32 blkno; |
|
|
|
|
BlockNumber nblocks; |
|
|
|
|
BlockNumber blkno; |
|
|
|
|
BTIndexStat indexStat; |
|
|
|
|
|
|
|
|
|
if (!superuser()) |
|
|
|
@ -112,30 +112,29 @@ pgstatindex(PG_FUNCTION_ARGS) |
|
|
|
|
BTMetaPageData *metad = BTPageGetMeta(page); |
|
|
|
|
|
|
|
|
|
indexStat.version = metad->btm_version; |
|
|
|
|
indexStat.root_blkno = metad->btm_root; |
|
|
|
|
indexStat.level = metad->btm_level; |
|
|
|
|
indexStat.root_blkno = metad->btm_root; |
|
|
|
|
|
|
|
|
|
ReleaseBuffer(buffer); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
nblocks = RelationGetNumberOfBlocks(rel); |
|
|
|
|
|
|
|
|
|
/* -- init stat -- */ |
|
|
|
|
indexStat.fragments = 0; |
|
|
|
|
|
|
|
|
|
/* -- init counters -- */ |
|
|
|
|
indexStat.root_pages = 0; |
|
|
|
|
indexStat.leaf_pages = 0; |
|
|
|
|
indexStat.internal_pages = 0; |
|
|
|
|
indexStat.leaf_pages = 0; |
|
|
|
|
indexStat.empty_pages = 0; |
|
|
|
|
indexStat.deleted_pages = 0; |
|
|
|
|
|
|
|
|
|
indexStat.max_avail = 0; |
|
|
|
|
indexStat.free_space = 0; |
|
|
|
|
|
|
|
|
|
/*-----------------------
|
|
|
|
|
* Scan all blocks |
|
|
|
|
*----------------------- |
|
|
|
|
indexStat.fragments = 0; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Scan all blocks except the metapage |
|
|
|
|
*/ |
|
|
|
|
nblocks = RelationGetNumberOfBlocks(rel); |
|
|
|
|
|
|
|
|
|
for (blkno = 1; blkno < nblocks; blkno++) |
|
|
|
|
{ |
|
|
|
|
Buffer buffer; |
|
|
|
@ -151,13 +150,7 @@ pgstatindex(PG_FUNCTION_ARGS) |
|
|
|
|
|
|
|
|
|
/* Determine page type, and update totals */ |
|
|
|
|
|
|
|
|
|
if (P_ISDELETED(opaque)) |
|
|
|
|
indexStat.deleted_pages++; |
|
|
|
|
|
|
|
|
|
else if (P_IGNORE(opaque)) |
|
|
|
|
indexStat.empty_pages++; |
|
|
|
|
|
|
|
|
|
else if (P_ISLEAF(opaque)) |
|
|
|
|
if (P_ISLEAF(opaque)) |
|
|
|
|
{ |
|
|
|
|
int max_avail; |
|
|
|
|
|
|
|
|
@ -174,9 +167,12 @@ pgstatindex(PG_FUNCTION_ARGS) |
|
|
|
|
if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno) |
|
|
|
|
indexStat.fragments++; |
|
|
|
|
} |
|
|
|
|
else if (P_ISDELETED(opaque)) |
|
|
|
|
indexStat.deleted_pages++; |
|
|
|
|
else if (P_IGNORE(opaque)) |
|
|
|
|
indexStat.empty_pages++; |
|
|
|
|
else if (P_ISROOT(opaque)) |
|
|
|
|
indexStat.root_pages++; |
|
|
|
|
|
|
|
|
|
else |
|
|
|
|
indexStat.internal_pages++; |
|
|
|
|
|
|
|
|
@ -207,25 +203,26 @@ pgstatindex(PG_FUNCTION_ARGS) |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.level); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", (indexStat.root_pages + |
|
|
|
|
indexStat.leaf_pages + |
|
|
|
|
indexStat.internal_pages + |
|
|
|
|
indexStat.deleted_pages + |
|
|
|
|
indexStat.empty_pages) * BLCKSZ); |
|
|
|
|
snprintf(values[j++], 32, INT64_FORMAT, |
|
|
|
|
(indexStat.root_pages + |
|
|
|
|
indexStat.leaf_pages + |
|
|
|
|
indexStat.internal_pages + |
|
|
|
|
indexStat.deleted_pages + |
|
|
|
|
indexStat.empty_pages) * BLCKSZ); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.root_blkno); |
|
|
|
|
snprintf(values[j++], 32, "%u", indexStat.root_blkno); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.internal_pages); |
|
|
|
|
snprintf(values[j++], 32, INT64_FORMAT, indexStat.internal_pages); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.leaf_pages); |
|
|
|
|
snprintf(values[j++], 32, INT64_FORMAT, indexStat.leaf_pages); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.empty_pages); |
|
|
|
|
snprintf(values[j++], 32, INT64_FORMAT, indexStat.empty_pages); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%d", indexStat.deleted_pages); |
|
|
|
|
snprintf(values[j++], 32, INT64_FORMAT, indexStat.deleted_pages); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%.2f", 100.0 - (float) indexStat.free_space / (float) indexStat.max_avail * 100.0); |
|
|
|
|
snprintf(values[j++], 32, "%.2f", 100.0 - (double) indexStat.free_space / (double) indexStat.max_avail * 100.0); |
|
|
|
|
values[j] = palloc(32); |
|
|
|
|
snprintf(values[j++], 32, "%.2f", (float) indexStat.fragments / (float) indexStat.leaf_pages * 100.0); |
|
|
|
|
snprintf(values[j++], 32, "%.2f", (double) indexStat.fragments / (double) indexStat.leaf_pages * 100.0); |
|
|
|
|
|
|
|
|
|
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc), |
|
|
|
|
values); |
|
|
|
@ -249,9 +246,9 @@ Datum |
|
|
|
|
pg_relpages(PG_FUNCTION_ARGS) |
|
|
|
|
{ |
|
|
|
|
text *relname = PG_GETARG_TEXT_P(0); |
|
|
|
|
int64 relpages; |
|
|
|
|
Relation rel; |
|
|
|
|
RangeVar *relrv; |
|
|
|
|
int4 relpages; |
|
|
|
|
|
|
|
|
|
if (!superuser()) |
|
|
|
|
ereport(ERROR, |
|
|
|
@ -265,5 +262,5 @@ pg_relpages(PG_FUNCTION_ARGS) |
|
|
|
|
|
|
|
|
|
relation_close(rel, AccessShareLock); |
|
|
|
|
|
|
|
|
|
PG_RETURN_INT32(relpages); |
|
|
|
|
PG_RETURN_INT64(relpages); |
|
|
|
|
} |
|
|
|
|