PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pgstatindex.c File Reference
#include "postgres.h"
#include "access/gin_private.h"
#include "access/heapam.h"
#include "access/hash.h"
#include "access/htup_details.h"
#include "access/nbtree.h"
#include "catalog/namespace.h"
#include "catalog/pg_am.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "utils/varlena.h"
Include dependency graph for pgstatindex.c:

Go to the source code of this file.

Data Structures

struct  BTIndexStat
 
struct  GinIndexStat
 
struct  HashIndexStat
 

Macros

#define IS_INDEX(r)   ((r)->rd_rel->relkind == RELKIND_INDEX)
 
#define IS_BTREE(r)   ((r)->rd_rel->relam == BTREE_AM_OID)
 
#define IS_GIN(r)   ((r)->rd_rel->relam == GIN_AM_OID)
 
#define IS_HASH(r)   ((r)->rd_rel->relam == HASH_AM_OID)
 

Typedefs

typedef struct BTIndexStat BTIndexStat
 
typedef struct GinIndexStat GinIndexStat
 
typedef struct HashIndexStat HashIndexStat
 

Functions

 PG_FUNCTION_INFO_V1 (pgstatindex)
 
 PG_FUNCTION_INFO_V1 (pgstatindexbyid)
 
 PG_FUNCTION_INFO_V1 (pg_relpages)
 
 PG_FUNCTION_INFO_V1 (pg_relpagesbyid)
 
 PG_FUNCTION_INFO_V1 (pgstatginindex)
 
 PG_FUNCTION_INFO_V1 (pgstathashindex)
 
 PG_FUNCTION_INFO_V1 (pgstatindex_v1_5)
 
 PG_FUNCTION_INFO_V1 (pgstatindexbyid_v1_5)
 
 PG_FUNCTION_INFO_V1 (pg_relpages_v1_5)
 
 PG_FUNCTION_INFO_V1 (pg_relpagesbyid_v1_5)
 
 PG_FUNCTION_INFO_V1 (pgstatginindex_v1_5)
 
Datum pgstatginindex_internal (Oid relid, FunctionCallInfo fcinfo)
 
static Datum pgstatindex_impl (Relation rel, FunctionCallInfo fcinfo)
 
static void GetHashPageStats (Page page, HashIndexStat *stats)
 
Datum pgstatindex (PG_FUNCTION_ARGS)
 
Datum pgstatindex_v1_5 (PG_FUNCTION_ARGS)
 
Datum pgstatindexbyid (PG_FUNCTION_ARGS)
 
Datum pgstatindexbyid_v1_5 (PG_FUNCTION_ARGS)
 
Datum pg_relpages (PG_FUNCTION_ARGS)
 
Datum pg_relpages_v1_5 (PG_FUNCTION_ARGS)
 
Datum pg_relpagesbyid (PG_FUNCTION_ARGS)
 
Datum pg_relpagesbyid_v1_5 (PG_FUNCTION_ARGS)
 
Datum pgstatginindex (PG_FUNCTION_ARGS)
 
Datum pgstatginindex_v1_5 (PG_FUNCTION_ARGS)
 
Datum pgstathashindex (PG_FUNCTION_ARGS)
 

Macro Definition Documentation

#define IS_BTREE (   r)    ((r)->rd_rel->relam == BTREE_AM_OID)

Definition at line 70 of file pgstatindex.c.

Referenced by pgstatindex_impl().

#define IS_GIN (   r)    ((r)->rd_rel->relam == GIN_AM_OID)

Definition at line 71 of file pgstatindex.c.

Referenced by pgstatginindex_internal().

#define IS_HASH (   r)    ((r)->rd_rel->relam == HASH_AM_OID)

Definition at line 72 of file pgstatindex.c.

Referenced by pgstathashindex().

#define IS_INDEX (   r)    ((r)->rd_rel->relkind == RELKIND_INDEX)

Definition at line 69 of file pgstatindex.c.

Referenced by pgstatginindex_internal(), and pgstatindex_impl().

Typedef Documentation

Function Documentation

static void GetHashPageStats ( Page  page,
HashIndexStat stats 
)
static

Definition at line 709 of file pgstatindex.c.

References HashIndexStat::dead_items, FirstOffsetNumber, HashIndexStat::free_space, ItemIdIsDead, HashIndexStat::live_items, PageGetExactFreeSpace(), PageGetItemId, and PageGetMaxOffsetNumber.

Referenced by pgstathashindex().

710 {
711  OffsetNumber maxoff = PageGetMaxOffsetNumber(page);
712  int off;
713 
714  /* count live and dead tuples, and free space */
715  for (off = FirstOffsetNumber; off <= maxoff; off++)
716  {
717  ItemId id = PageGetItemId(page, off);
718 
719  if (!ItemIdIsDead(id))
720  stats->live_items++;
721  else
722  stats->dead_items++;
723  }
724  stats->free_space += PageGetExactFreeSpace(page);
725 }
uint64 free_space
Definition: pgstatindex.c:126
#define ItemIdIsDead(itemId)
Definition: itemid.h:112
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:354
uint16 OffsetNumber
Definition: off.h:24
int64 dead_items
Definition: pgstatindex.c:125
#define FirstOffsetNumber
Definition: off.h:27
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:232
Size PageGetExactFreeSpace(Page page)
Definition: bufpage.c:606
int64 live_items
Definition: pgstatindex.c:124
PG_FUNCTION_INFO_V1 ( pgstatindex  )
PG_FUNCTION_INFO_V1 ( pgstatindexbyid  )
PG_FUNCTION_INFO_V1 ( pg_relpages  )
PG_FUNCTION_INFO_V1 ( pg_relpagesbyid  )
PG_FUNCTION_INFO_V1 ( pgstatginindex  )
PG_FUNCTION_INFO_V1 ( pgstathashindex  )
PG_FUNCTION_INFO_V1 ( pgstatindex_v1_5  )
PG_FUNCTION_INFO_V1 ( pgstatindexbyid_v1_5  )
PG_FUNCTION_INFO_V1 ( pg_relpages_v1_5  )
PG_FUNCTION_INFO_V1 ( pg_relpagesbyid_v1_5  )
PG_FUNCTION_INFO_V1 ( pgstatginindex_v1_5  )
Datum pg_relpages ( PG_FUNCTION_ARGS  )

Definition at line 376 of file pgstatindex.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, makeRangeVarFromNameList(), PG_GETARG_TEXT_P, PG_RETURN_INT64, relation_close(), relation_openrv(), RelationGetNumberOfBlocks, superuser(), and textToQualifiedNameList().

377 {
378  text *relname = PG_GETARG_TEXT_P(0);
379  int64 relpages;
380  Relation rel;
381  RangeVar *relrv;
382 
383  if (!superuser())
384  ereport(ERROR,
385  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
386  (errmsg("must be superuser to use pgstattuple functions"))));
387 
389  rel = relation_openrv(relrv, AccessShareLock);
390 
391  /* note: this will work OK on non-local temp tables */
392 
393  relpages = RelationGetNumberOfBlocks(rel);
394 
396 
397  PG_RETURN_INT64(relpages);
398 }
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1195
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:435
Datum pg_relpages_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 402 of file pgstatindex.c.

References AccessShareLock, makeRangeVarFromNameList(), PG_GETARG_TEXT_P, PG_RETURN_INT64, relation_close(), relation_openrv(), RelationGetNumberOfBlocks, and textToQualifiedNameList().

403 {
404  text *relname = PG_GETARG_TEXT_P(0);
405  int64 relpages;
406  Relation rel;
407  RangeVar *relrv;
408 
410  rel = relation_openrv(relrv, AccessShareLock);
411 
412  /* note: this will work OK on non-local temp tables */
413 
414  relpages = RelationGetNumberOfBlocks(rel);
415 
417 
418  PG_RETURN_INT64(relpages);
419 }
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1195
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:435
Datum pg_relpagesbyid ( PG_FUNCTION_ARGS  )

Definition at line 423 of file pgstatindex.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, PG_GETARG_OID, PG_RETURN_INT64, relation_close(), relation_open(), RelationGetNumberOfBlocks, and superuser().

424 {
425  Oid relid = PG_GETARG_OID(0);
426  int64 relpages;
427  Relation rel;
428 
429  if (!superuser())
430  ereport(ERROR,
431  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
432  (errmsg("must be superuser to use pgstattuple functions"))));
433 
434  rel = relation_open(relid, AccessShareLock);
435 
436  /* note: this will work OK on non-local temp tables */
437 
438  relpages = RelationGetNumberOfBlocks(rel);
439 
441 
442  PG_RETURN_INT64(relpages);
443 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define ereport(elevel, rest)
Definition: elog.h:122
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
int errmsg(const char *fmt,...)
Definition: elog.c:797
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
Datum pg_relpagesbyid_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 447 of file pgstatindex.c.

References AccessShareLock, PG_GETARG_OID, PG_RETURN_INT64, relation_close(), relation_open(), and RelationGetNumberOfBlocks.

448 {
449  Oid relid = PG_GETARG_OID(0);
450  int64 relpages;
451  Relation rel;
452 
453  rel = relation_open(relid, AccessShareLock);
454 
455  /* note: this will work OK on non-local temp tables */
456 
457  relpages = RelationGetNumberOfBlocks(rel);
458 
460 
461  PG_RETURN_INT64(relpages);
462 }
#define PG_RETURN_INT64(x)
Definition: fmgr.h:311
#define AccessShareLock
Definition: lockdefs.h:36
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
Datum pgstatginindex ( PG_FUNCTION_ARGS  )

Definition at line 473 of file pgstatindex.c.

References ereport, errcode(), errmsg(), ERROR, PG_GETARG_OID, PG_RETURN_DATUM, pgstatginindex_internal(), and superuser().

474 {
475  Oid relid = PG_GETARG_OID(0);
476 
477  if (!superuser())
478  ereport(ERROR,
479  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
480  (errmsg("must be superuser to use pgstattuple functions"))));
481 
483 }
Datum pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:495
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
unsigned int Oid
Definition: postgres_ext.h:31
#define ERROR
Definition: elog.h:43
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
int errmsg(const char *fmt,...)
Definition: elog.c:797
Datum pgstatginindex_internal ( Oid  relid,
FunctionCallInfo  fcinfo 
)

Definition at line 495 of file pgstatindex.c.

References AccessShareLock, BufferGetPage, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), GIN_METAPAGE_BLKNO, GIN_SHARE, GinPageGetMeta, GinMetaPageData::ginVersion, heap_form_tuple(), HeapTupleGetDatum, Int32GetDatum, Int64GetDatum(), IS_GIN, IS_INDEX, LockBuffer(), GinMetaPageData::nPendingHeapTuples, GinMetaPageData::nPendingPages, NULL, GinIndexStat::pending_pages, GinIndexStat::pending_tuples, ReadBuffer(), relation_close(), RELATION_IS_OTHER_TEMP, relation_open(), RelationGetRelationName, TYPEFUNC_COMPOSITE, UInt32GetDatum, UnlockReleaseBuffer(), values, and GinIndexStat::version.

Referenced by pgstatginindex(), and pgstatginindex_v1_5().

496 {
497  Relation rel;
498  Buffer buffer;
499  Page page;
500  GinMetaPageData *metadata;
501  GinIndexStat stats;
502  HeapTuple tuple;
504  Datum values[3];
505  bool nulls[3] = {false, false, false};
506  Datum result;
507 
508  rel = relation_open(relid, AccessShareLock);
509 
510  if (!IS_INDEX(rel) || !IS_GIN(rel))
511  elog(ERROR, "relation \"%s\" is not a GIN index",
513 
514  /*
515  * Reject attempts to read non-local temporary relations; we would be
516  * likely to get wrong data since we have no visibility into the owning
517  * session's local buffers.
518  */
519  if (RELATION_IS_OTHER_TEMP(rel))
520  ereport(ERROR,
521  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
522  errmsg("cannot access temporary indexes of other sessions")));
523 
524  /*
525  * Read metapage
526  */
527  buffer = ReadBuffer(rel, GIN_METAPAGE_BLKNO);
528  LockBuffer(buffer, GIN_SHARE);
529  page = BufferGetPage(buffer);
530  metadata = GinPageGetMeta(page);
531 
532  stats.version = metadata->ginVersion;
533  stats.pending_pages = metadata->nPendingPages;
534  stats.pending_tuples = metadata->nPendingHeapTuples;
535 
536  UnlockReleaseBuffer(buffer);
538 
539  /*
540  * Build a tuple descriptor for our result type
541  */
542  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
543  elog(ERROR, "return type must be a row type");
544 
545  values[0] = Int32GetDatum(stats.version);
546  values[1] = UInt32GetDatum(stats.pending_pages);
547  values[2] = Int64GetDatum(stats.pending_tuples);
548 
549  /*
550  * Build and return the tuple
551  */
552  tuple = heap_form_tuple(tupleDesc, values, nulls);
553  result = HeapTupleGetDatum(tuple);
554 
555  return (result);
556 }
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
int64 pending_tuples
Definition: pgstatindex.c:106
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
#define GIN_METAPAGE_BLKNO
Definition: ginblock.h:50
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
#define IS_INDEX(r)
Definition: pgstatindex.c:69
int64 nPendingHeapTuples
Definition: ginblock.h:73
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define UInt32GetDatum(X)
Definition: postgres.h:501
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
#define GIN_SHARE
Definition: gin_private.h:44
BlockNumber pending_pages
Definition: pgstatindex.c:105
#define IS_GIN(r)
Definition: pgstatindex.c:71
uintptr_t Datum
Definition: postgres.h:374
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
#define NULL
Definition: c.h:226
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition: bufmgr.c:594
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
int32 ginVersion
Definition: ginblock.h:98
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define Int32GetDatum(X)
Definition: postgres.h:487
int errmsg(const char *fmt,...)
Definition: elog.c:797
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
#define GinPageGetMeta(p)
Definition: ginblock.h:103
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
BlockNumber nPendingPages
Definition: ginblock.h:72
Datum pgstatginindex_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 487 of file pgstatindex.c.

References PG_GETARG_OID, PG_RETURN_DATUM, and pgstatginindex_internal().

488 {
489  Oid relid = PG_GETARG_OID(0);
490 
492 }
Datum pgstatginindex_internal(Oid relid, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:495
unsigned int Oid
Definition: postgres_ext.h:31
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
Datum pgstathashindex ( PG_FUNCTION_ARGS  )

Definition at line 565 of file pgstatindex.c.

References _hash_getbuf(), _hash_relbuf(), AccessShareLock, BAS_BULKREAD, HashIndexStat::bitmap_pages, BlessTupleDesc(), HashIndexStat::bucket_pages, buf, BUFFER_LOCK_SHARE, BufferGetBlockNumber(), BufferGetPage, CHECK_FOR_INTERRUPTS, HashIndexStat::dead_items, elog, ereport, errcode(), errmsg(), ERROR, Float8GetDatum(), HashIndexStat::free_space, get_call_result_type(), GetAccessStrategy(), GetHashPageStats(), HASH_METAPAGE, HASH_READ, HashMetaPageData::hashm_bsize, HashMetaPageData::hashm_version, HashPageOpaqueData::hasho_flag, HashPageGetMeta, heap_form_tuple(), HeapTupleGetDatum, index_close(), index_open(), Int32GetDatum, Int64GetDatum(), IS_HASH, LH_BITMAP_PAGE, LH_BUCKET_PAGE, LH_META_PAGE, LH_OVERFLOW_PAGE, HashIndexStat::live_items, LockBuffer(), MAIN_FORKNUM, MAXALIGN, MemSet, NULL, HashIndexStat::overflow_pages, PageGetSpecialPointer, PageGetSpecialSize, PageIsNew, PG_GETARG_OID, PG_RETURN_DATUM, RBM_NORMAL, ReadBufferExtended(), RELATION_IS_OTHER_TEMP, RelationGetNumberOfBlocks, RelationGetRelationName, HashIndexStat::space_per_page, TYPEFUNC_COMPOSITE, UnlockReleaseBuffer(), values, HashIndexStat::version, and HashIndexStat::zero_pages.

566 {
567  Oid relid = PG_GETARG_OID(0);
568  BlockNumber nblocks;
569  BlockNumber blkno;
570  Relation rel;
571  HashIndexStat stats;
572  BufferAccessStrategy bstrategy;
573  HeapTuple tuple;
575  Datum values[8];
576  bool nulls[8];
577  Buffer metabuf;
578  HashMetaPage metap;
579  float8 free_percent;
580  uint64 total_space;
581 
582  rel = index_open(relid, AccessShareLock);
583 
584  if (!IS_HASH(rel))
585  elog(ERROR, "relation \"%s\" is not a HASH index",
587 
588  /*
589  * Reject attempts to read non-local temporary relations; we would be
590  * likely to get wrong data since we have no visibility into the owning
591  * session's local buffers.
592  */
593  if (RELATION_IS_OTHER_TEMP(rel))
594  ereport(ERROR,
595  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
596  errmsg("cannot access temporary indexes of other sessions")));
597 
598  /* Get the information we need from the metapage. */
599  memset(&stats, 0, sizeof(stats));
601  metap = HashPageGetMeta(BufferGetPage(metabuf));
602  stats.version = metap->hashm_version;
603  stats.space_per_page = metap->hashm_bsize;
604  _hash_relbuf(rel, metabuf);
605 
606  /* Get the current relation length */
607  nblocks = RelationGetNumberOfBlocks(rel);
608 
609  /* prepare access strategy for this index */
610  bstrategy = GetAccessStrategy(BAS_BULKREAD);
611 
612  /* Start from blkno 1 as 0th block is metapage */
613  for (blkno = 1; blkno < nblocks; blkno++)
614  {
615  Buffer buf;
616  Page page;
617  HashPageOpaque opaque;
618 
620 
621  buf = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL,
622  bstrategy);
624  page = (Page) BufferGetPage(buf);
625 
626  if (PageIsNew(page))
627  stats.zero_pages++;
628  else if (PageGetSpecialSize(page) !=
629  MAXALIGN(sizeof(HashPageOpaqueData)))
630  ereport(ERROR,
631  (errcode(ERRCODE_INDEX_CORRUPTED),
632  errmsg("index \"%s\" contains corrupted page at block %u",
634  BufferGetBlockNumber(buf))));
635  else
636  {
637  opaque = (HashPageOpaque) PageGetSpecialPointer(page);
638  if (opaque->hasho_flag & LH_BUCKET_PAGE)
639  {
640  stats.bucket_pages++;
641  GetHashPageStats(page, &stats);
642  }
643  else if (opaque->hasho_flag & LH_OVERFLOW_PAGE)
644  {
645  stats.overflow_pages++;
646  GetHashPageStats(page, &stats);
647  }
648  else if (opaque->hasho_flag & LH_BITMAP_PAGE)
649  stats.bitmap_pages++;
650  else
651  ereport(ERROR,
652  (errcode(ERRCODE_INDEX_CORRUPTED),
653  errmsg("unexpected page type 0x%04X in HASH index \"%s\" block %u",
654  opaque->hasho_flag, RelationGetRelationName(rel),
655  BufferGetBlockNumber(buf))));
656  }
657  UnlockReleaseBuffer(buf);
658  }
659 
660  /* Done accessing the index */
662 
663  /* Count zero pages as free space. */
664  stats.free_space += stats.zero_pages * stats.space_per_page;
665 
666  /*
667  * Total space available for tuples excludes the metapage and the bitmap
668  * pages.
669  */
670  total_space = (nblocks - (stats.bitmap_pages + 1)) * stats.space_per_page;
671 
672  if (total_space == 0)
673  free_percent = 0.0;
674  else
675  free_percent = 100.0 * stats.free_space / total_space;
676 
677  /*
678  * Build a tuple descriptor for our result type
679  */
680  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
681  elog(ERROR, "return type must be a row type");
682 
683  tupleDesc = BlessTupleDesc(tupleDesc);
684 
685  /*
686  * Build and return the tuple
687  */
688  MemSet(nulls, 0, sizeof(nulls));
689  values[0] = Int32GetDatum(stats.version);
690  values[1] = Int64GetDatum((int64) stats.bucket_pages);
691  values[2] = Int64GetDatum((int64) stats.overflow_pages);
692  values[3] = Int64GetDatum((int64) stats.bitmap_pages);
693  values[4] = Int64GetDatum((int64) stats.zero_pages);
694  values[5] = Int64GetDatum(stats.live_items);
695  values[6] = Int64GetDatum(stats.dead_items);
696  values[7] = Float8GetDatum(free_percent);
697  tuple = heap_form_tuple(tupleDesc, values, nulls);
698 
700 }
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:525
BlockNumber overflow_pages
Definition: pgstatindex.c:120
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
#define LH_BITMAP_PAGE
Definition: hash.h:55
#define LH_META_PAGE
Definition: hash.h:56
BlockNumber bitmap_pages
Definition: pgstatindex.c:121
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
BlockNumber zero_pages
Definition: pgstatindex.c:122
#define MemSet(start, val, len)
Definition: c.h:853
uint32 BlockNumber
Definition: block.h:31
uint64 free_space
Definition: pgstatindex.c:126
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:692
Buffer _hash_getbuf(Relation rel, BlockNumber blkno, int access, int flags)
Definition: hashpage.c:79
unsigned int Oid
Definition: postgres_ext.h:31
Datum Float8GetDatum(float8 X)
Definition: fmgr.c:2126
int32 space_per_page
Definition: pgstatindex.c:117
#define HASH_READ
Definition: hash.h:254
int64 dead_items
Definition: pgstatindex.c:125
void UnlockReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3315
#define ERROR
Definition: elog.h:43
double float8
Definition: c.h:378
static void GetHashPageStats(Page page, HashIndexStat *stats)
Definition: pgstatindex.c:709
uint32 hashm_version
Definition: hash.h:177
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:1031
static char * buf
Definition: pg_test_fsync.c:65
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define IS_HASH(r)
Definition: pgstatindex.c:72
Datum Int64GetDatum(int64 X)
Definition: fmgr.c:2102
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
uint16 hashm_bsize
Definition: hash.h:180
#define HASH_METAPAGE
Definition: hash.h:146
uintptr_t Datum
Definition: postgres.h:374
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define LH_OVERFLOW_PAGE
Definition: hash.h:53
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
void _hash_relbuf(Relation rel, Buffer buf)
Definition: hashpage.c:245
#define LH_BUCKET_PAGE
Definition: hash.h:54
#define NULL
Definition: c.h:226
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
#define PageGetSpecialPointer(page)
Definition: bufpage.h:323
HashPageOpaqueData * HashPageOpaque
Definition: hash.h:84
#define MAXALIGN(LEN)
Definition: c.h:584
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
#define PageGetSpecialSize(page)
Definition: bufpage.h:297
void index_close(Relation relation, LOCKMODE lockmode)
Definition: indexam.c:176
uint16 hasho_flag
Definition: hash.h:80
static Datum values[MAXATTR]
Definition: bootstrap.c:162
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition: bufmgr.c:2588
#define Int32GetDatum(X)
Definition: postgres.h:487
#define PageIsNew(page)
Definition: bufpage.h:226
#define HashPageGetMeta(page)
Definition: hash.h:238
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
BlockNumber bucket_pages
Definition: pgstatindex.c:119
Relation index_open(Oid relationId, LOCKMODE lockmode)
Definition: indexam.c:151
Pointer Page
Definition: bufpage.h:74
int64 live_items
Definition: pgstatindex.c:124
Datum pgstatindex ( PG_FUNCTION_ARGS  )

Definition at line 144 of file pgstatindex.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, makeRangeVarFromNameList(), PG_GETARG_TEXT_P, PG_RETURN_DATUM, pgstatindex_impl(), relation_openrv(), superuser(), and textToQualifiedNameList().

145 {
146  text *relname = PG_GETARG_TEXT_P(0);
147  Relation rel;
148  RangeVar *relrv;
149 
150  if (!superuser())
151  ereport(ERROR,
152  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
153  (errmsg("must be superuser to use pgstattuple functions"))));
154 
156  rel = relation_openrv(relrv, AccessShareLock);
157 
158  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
159 }
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1195
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:215
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:435
static Datum pgstatindex_impl ( Relation  rel,
FunctionCallInfo  fcinfo 
)
static

Definition at line 215 of file pgstatindex.c.

References AccessShareLock, BAS_BULKREAD, BTMetaPageData::btm_level, BTMetaPageData::btm_root, BTMetaPageData::btm_version, BTPageGetMeta, BTPageOpaqueData::btpo_next, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, BuildTupleFromCStrings(), CHECK_FOR_INTERRUPTS, BTIndexStat::deleted_pages, elog, BTIndexStat::empty_pages, ereport, errcode(), errmsg(), ERROR, BTIndexStat::fragments, BTIndexStat::free_space, get_call_result_type(), GetAccessStrategy(), HeapTupleGetDatum, INT64_FORMAT, BTIndexStat::internal_pages, IS_BTREE, IS_INDEX, BTIndexStat::leaf_pages, BTIndexStat::level, LockBuffer(), MAIN_FORKNUM, BTIndexStat::max_avail, NULL, P_IGNORE, P_ISDELETED, P_ISLEAF, P_NONE, PageGetFreeSpace(), PageGetSpecialPointer, psprintf(), pstrdup(), RBM_NORMAL, ReadBufferExtended(), relation_close(), RELATION_IS_OTHER_TEMP, RelationGetNumberOfBlocks, RelationGetRelationName, ReleaseBuffer(), BTIndexStat::root_blkno, SizeOfPageHeaderData, TupleDescGetAttInMetadata(), TYPEFUNC_COMPOSITE, values, and BTIndexStat::version.

Referenced by pgstatindex(), pgstatindex_v1_5(), pgstatindexbyid(), and pgstatindexbyid_v1_5().

216 {
217  Datum result;
218  BlockNumber nblocks;
219  BlockNumber blkno;
220  BTIndexStat indexStat;
222 
223  if (!IS_INDEX(rel) || !IS_BTREE(rel))
224  elog(ERROR, "relation \"%s\" is not a btree index",
226 
227  /*
228  * Reject attempts to read non-local temporary relations; we would be
229  * likely to get wrong data since we have no visibility into the owning
230  * session's local buffers.
231  */
232  if (RELATION_IS_OTHER_TEMP(rel))
233  ereport(ERROR,
234  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
235  errmsg("cannot access temporary tables of other sessions")));
236 
237  /*
238  * Read metapage
239  */
240  {
241  Buffer buffer = ReadBufferExtended(rel, MAIN_FORKNUM, 0, RBM_NORMAL, bstrategy);
242  Page page = BufferGetPage(buffer);
243  BTMetaPageData *metad = BTPageGetMeta(page);
244 
245  indexStat.version = metad->btm_version;
246  indexStat.level = metad->btm_level;
247  indexStat.root_blkno = metad->btm_root;
248 
249  ReleaseBuffer(buffer);
250  }
251 
252  /* -- init counters -- */
253  indexStat.internal_pages = 0;
254  indexStat.leaf_pages = 0;
255  indexStat.empty_pages = 0;
256  indexStat.deleted_pages = 0;
257 
258  indexStat.max_avail = 0;
259  indexStat.free_space = 0;
260 
261  indexStat.fragments = 0;
262 
263  /*
264  * Scan all blocks except the metapage
265  */
266  nblocks = RelationGetNumberOfBlocks(rel);
267 
268  for (blkno = 1; blkno < nblocks; blkno++)
269  {
270  Buffer buffer;
271  Page page;
272  BTPageOpaque opaque;
273 
275 
276  /* Read and lock buffer */
277  buffer = ReadBufferExtended(rel, MAIN_FORKNUM, blkno, RBM_NORMAL, bstrategy);
278  LockBuffer(buffer, BUFFER_LOCK_SHARE);
279 
280  page = BufferGetPage(buffer);
281  opaque = (BTPageOpaque) PageGetSpecialPointer(page);
282 
283  /* Determine page type, and update totals */
284 
285  if (P_ISDELETED(opaque))
286  indexStat.deleted_pages++;
287  else if (P_IGNORE(opaque))
288  indexStat.empty_pages++; /* this is the "half dead" state */
289  else if (P_ISLEAF(opaque))
290  {
291  int max_avail;
292 
293  max_avail = BLCKSZ - (BLCKSZ - ((PageHeader) page)->pd_special + SizeOfPageHeaderData);
294  indexStat.max_avail += max_avail;
295  indexStat.free_space += PageGetFreeSpace(page);
296 
297  indexStat.leaf_pages++;
298 
299  /*
300  * If the next leaf is on an earlier block, it means a
301  * fragmentation.
302  */
303  if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
304  indexStat.fragments++;
305  }
306  else
307  indexStat.internal_pages++;
308 
309  /* Unlock and release buffer */
311  ReleaseBuffer(buffer);
312  }
313 
315 
316  /*----------------------------
317  * Build a result tuple
318  *----------------------------
319  */
320  {
322  int j;
323  char *values[10];
324  HeapTuple tuple;
325 
326  /* Build a tuple descriptor for our result type */
327  if (get_call_result_type(fcinfo, NULL, &tupleDesc) != TYPEFUNC_COMPOSITE)
328  elog(ERROR, "return type must be a row type");
329 
330  j = 0;
331  values[j++] = psprintf("%d", indexStat.version);
332  values[j++] = psprintf("%d", indexStat.level);
333  values[j++] = psprintf(INT64_FORMAT,
334  (1 + /* include the metapage in index_size */
335  indexStat.leaf_pages +
336  indexStat.internal_pages +
337  indexStat.deleted_pages +
338  indexStat.empty_pages) * BLCKSZ);
339  values[j++] = psprintf("%u", indexStat.root_blkno);
340  values[j++] = psprintf(INT64_FORMAT, indexStat.internal_pages);
341  values[j++] = psprintf(INT64_FORMAT, indexStat.leaf_pages);
342  values[j++] = psprintf(INT64_FORMAT, indexStat.empty_pages);
343  values[j++] = psprintf(INT64_FORMAT, indexStat.deleted_pages);
344  if (indexStat.max_avail > 0)
345  values[j++] = psprintf("%.2f",
346  100.0 - (double) indexStat.free_space / (double) indexStat.max_avail * 100.0);
347  else
348  values[j++] = pstrdup("NaN");
349  if (indexStat.leaf_pages > 0)
350  values[j++] = psprintf("%.2f",
351  (double) indexStat.fragments / (double) indexStat.leaf_pages * 100.0);
352  else
353  values[j++] = pstrdup("NaN");
354 
356  values);
357 
358  result = HeapTupleGetDatum(tuple);
359  }
360 
361  return result;
362 }
uint64 empty_pages
Definition: pgstatindex.c:87
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition: freelist.c:525
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:87
BlockNumber btpo_next
Definition: nbtree.h:57
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:211
#define P_IGNORE(opaque)
Definition: nbtree.h:181
uint64 fragments
Definition: pgstatindex.c:93
uint32 version
Definition: pgstatindex.c:81
uint32 btm_version
Definition: nbtree.h:99
BlockNumber root_blkno
Definition: pgstatindex.c:83
char * pstrdup(const char *in)
Definition: mcxt.c:1165
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:640
#define P_NONE
Definition: nbtree.h:169
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: heapam.c:1263
uint32 BlockNumber
Definition: block.h:31
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3292
#define IS_INDEX(r)
Definition: pgstatindex.c:69
#define SizeOfPageHeaderData
Definition: bufpage.h:213
BTPageOpaqueData * BTPageOpaque
Definition: nbtree.h:67
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:582
HeapTuple BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
Definition: execTuples.c:1115
#define IS_BTREE(r)
Definition: pgstatindex.c:70
#define ERROR
Definition: elog.h:43
uint64 internal_pages
Definition: pgstatindex.c:85
#define BTPageGetMeta(p)
Definition: nbtree.h:106
#define RelationGetRelationName(relation)
Definition: rel.h:433
#define BufferGetPage(buffer)
Definition: bufmgr.h:160
#define ereport(elevel, rest)
Definition: elog.h:122
#define P_ISDELETED(opaque)
Definition: nbtree.h:179
uintptr_t Datum
Definition: postgres.h:374
AttInMetadata * TupleDescGetAttInMetadata(TupleDesc tupdesc)
Definition: execTuples.c:1068
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:3529
uint64 free_space
Definition: pgstatindex.c:91
BlockNumber btm_root
Definition: nbtree.h:100
#define RelationGetNumberOfBlocks(reln)
Definition: bufmgr.h:199
PageHeaderData * PageHeader
Definition: bufpage.h:162
#define NULL
Definition: c.h:226
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:530
uint64 leaf_pages
Definition: pgstatindex.c:86
#define PageGetSpecialPointer(page)
Definition: bufpage.h:323
uint32 level
Definition: pgstatindex.c:82
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:222
#define INT64_FORMAT
Definition: c.h:312
static Datum values[MAXATTR]
Definition: bootstrap.c:162
int errmsg(const char *fmt,...)
Definition: elog.c:797
uint32 btm_level
Definition: nbtree.h:101
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:88
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:97
uint64 deleted_pages
Definition: pgstatindex.c:88
#define elog
Definition: elog.h:219
int Buffer
Definition: buf.h:23
Pointer Page
Definition: bufpage.h:74
uint64 max_avail
Definition: pgstatindex.c:90
#define P_ISLEAF(opaque)
Definition: nbtree.h:177
Datum pgstatindex_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 169 of file pgstatindex.c.

References AccessShareLock, makeRangeVarFromNameList(), PG_GETARG_TEXT_P, PG_RETURN_DATUM, pgstatindex_impl(), relation_openrv(), and textToQualifiedNameList().

170 {
171  text *relname = PG_GETARG_TEXT_P(0);
172  Relation rel;
173  RangeVar *relrv;
174 
176  rel = relation_openrv(relrv, AccessShareLock);
177 
178  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
179 }
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: heapam.c:1195
#define AccessShareLock
Definition: lockdefs.h:36
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:2857
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:215
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3071
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
#define PG_GETARG_TEXT_P(n)
Definition: fmgr.h:269
Definition: c.h:435
Datum pgstatindexbyid ( PG_FUNCTION_ARGS  )

Definition at line 187 of file pgstatindex.c.

References AccessShareLock, ereport, errcode(), errmsg(), ERROR, PG_GETARG_OID, PG_RETURN_DATUM, pgstatindex_impl(), relation_open(), and superuser().

188 {
189  Oid relid = PG_GETARG_OID(0);
190  Relation rel;
191 
192  if (!superuser())
193  ereport(ERROR,
194  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
195  (errmsg("must be superuser to use pgstattuple functions"))));
196 
197  rel = relation_open(relid, AccessShareLock);
198 
199  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
200 }
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
unsigned int Oid
Definition: postgres_ext.h:31
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:215
#define ERROR
Definition: elog.h:43
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define ereport(elevel, rest)
Definition: elog.h:122
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
int errmsg(const char *fmt,...)
Definition: elog.c:797
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117
Datum pgstatindexbyid_v1_5 ( PG_FUNCTION_ARGS  )

Definition at line 204 of file pgstatindex.c.

References AccessShareLock, PG_GETARG_OID, PG_RETURN_DATUM, pgstatindex_impl(), and relation_open().

205 {
206  Oid relid = PG_GETARG_OID(0);
207  Relation rel;
208 
209  rel = relation_open(relid, AccessShareLock);
210 
211  PG_RETURN_DATUM(pgstatindex_impl(rel, fcinfo));
212 }
#define AccessShareLock
Definition: lockdefs.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static Datum pgstatindex_impl(Relation rel, FunctionCallInfo fcinfo)
Definition: pgstatindex.c:215
#define PG_GETARG_OID(n)
Definition: fmgr.h:231
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:297
Relation relation_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1117