Add pg_table_size() and pg_indexes_size() to provide more user-friendly

wrappers around the pg_relation_size() function.

Bernd Helmle, reviewed by Greg Smith
This commit is contained in:
Tom Lane 2010-01-19 05:50:18 +00:00
parent 309cd7cf18
commit 4f15699d70
5 changed files with 228 additions and 84 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.496 2010/01/15 09:18:58 heikki Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.497 2010/01/19 05:50:18 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
@ -13173,12 +13173,12 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
</entry>
<entry><type>text</type></entry>
<entry>Get last transaction log location received and synced to disk during
streaming recovery. If streaming recovery is still in progress
this will increase monotonically. If streaming recovery has completed
then this value will remain static at the value of the last WAL record
received and synced to disk during that recovery. When the server has
been started without a streaming recovery then the return value will be
InvalidXLogRecPtr (0/0).
streaming recovery. If streaming recovery is still in progress
this will increase monotonically. If streaming recovery has completed
then this value will remain static at the value of the last WAL record
received and synced to disk during that recovery. When the server has
been started without a streaming recovery then the return value will be
InvalidXLogRecPtr (0/0).
</entry>
</row>
<row>
@ -13187,11 +13187,11 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
</entry>
<entry><type>text</type></entry>
<entry>Get last transaction log location replayed during recovery.
If recovery is still in progress this will increase monotonically.
If recovery has completed then this value will remain static at
the value of the last WAL record applied during that recovery.
When the server has been started normally without a recovery
then the return value will be InvalidXLogRecPtr (0/0).
If recovery is still in progress this will increase monotonically.
If recovery has completed then this value will remain static at
the value of the last WAL record applied during that recovery.
When the server has been started normally without a recovery
then the return value will be InvalidXLogRecPtr (0/0).
</entry>
</row>
</tbody>
@ -13206,21 +13206,27 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<indexterm>
<primary>pg_column_size</primary>
</indexterm>
<indexterm>
<primary>pg_total_relation_size</primary>
</indexterm>
<indexterm>
<primary>pg_table_size</primary>
</indexterm>
<indexterm>
<primary>pg_indexes_size</primary>
</indexterm>
<indexterm>
<primary>pg_database_size</primary>
</indexterm>
<indexterm>
<primary>pg_tablespace_size</primary>
</indexterm>
<indexterm>
<primary>pg_relation_size</primary>
</indexterm>
<indexterm>
<primary>pg_size_pretty</primary>
</indexterm>
<indexterm>
<primary>pg_tablespace_size</primary>
</indexterm>
<indexterm>
<primary>pg_total_relation_size</primary>
</indexterm>
<table id="functions-admin-dbsize">
<title>Database Object Size Functions</title>
@ -13236,6 +13242,37 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<entry><type>int</type></entry>
<entry>Number of bytes used to store a particular value (possibly compressed)</entry>
</row>
<row>
<entry>
<literal><function>pg_total_relation_size</function>(<type>regclass</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>
Total disk space used by the table with the specified OID or name,
including all indexes and <acronym>TOAST</> data
</entry>
</row>
<row>
<entry>
<literal><function>pg_table_size</function>(<type>regclass</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>
Disk space used by the table with the specified OID or name,
excluding indexes (but including TOAST, free space map, and visibility
map)
</entry>
</row>
<row>
<entry>
<literal><function>pg_indexes_size</function>(<type>regclass</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>
Total disk space used by indexes attached to the table with the
specified OID or name
</entry>
</row>
<row>
<entry>
<literal><function>pg_database_size</function>(<type>oid</type>)</literal>
@ -13250,6 +13287,20 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<entry><type>bigint</type></entry>
<entry>Disk space used by the database with the specified name</entry>
</row>
<row>
<entry>
<literal><function>pg_tablespace_size</function>(<type>oid</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>Disk space used by the tablespace with the specified OID</entry>
</row>
<row>
<entry>
<literal><function>pg_tablespace_size</function>(<type>name</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>Disk space used by the tablespace with the specified name</entry>
</row>
<row>
<entry>
<literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>, <parameter>fork</parameter> <type>text</type>)</literal>
@ -13277,30 +13328,6 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<entry><type>text</type></entry>
<entry>Converts a size in bytes into a human-readable format with size units</entry>
</row>
<row>
<entry>
<literal><function>pg_tablespace_size</function>(<type>oid</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>Disk space used by the tablespace with the specified OID</entry>
</row>
<row>
<entry>
<literal><function>pg_tablespace_size</function>(<type>name</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>Disk space used by the tablespace with the specified name</entry>
</row>
<row>
<entry>
<literal><function>pg_total_relation_size</function>(<type>regclass</type>)</literal>
</entry>
<entry><type>bigint</type></entry>
<entry>
Total disk space used by the table with the specified OID or name,
including indexes and <acronym>TOAST</> data
</entry>
</row>
</tbody>
</tgroup>
</table>
@ -13310,6 +13337,26 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
data value.
</para>
<para>
<function>pg_total_relation_size</> accepts the OID or name of a
table or toast table, and returns the total on-disk space used for
that table, including all associated indexes. This function is
equivalent to <function>pg_table_size</function>
<literal>+</> <function>pg_indexes_size</function>.
</para>
<para>
<function>pg_table_size</> accepts the OID or name of a table and
returns the disk space needed for that table, exclusive of indexes.
(TOAST space, free space map, and visibility map are included.)
</para>
<para>
<function>pg_indexes_size</> accepts the OID or name of a table and
returns the total disk space used by all the indexes attached to that
table.
</para>
<para>
<function>pg_database_size</function> and <function>pg_tablespace_size</>
accept the OID or name of a database or tablespace, and return the total
@ -13318,14 +13365,17 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
<para>
<function>pg_relation_size</> accepts the OID or name of a table, index or
toast table, and returns the size in bytes. Specifying
toast table, and returns the on-disk size in bytes. Specifying
<literal>'main'</literal> or leaving out the second argument returns the
size of the main data fork of the relation. Specifying
<literal>'fsm'</literal> returns the size of the
Free Space Map (see <xref linkend="storage-fsm">) associated with the
relation. Specifying <literal>'vm'</literal> returns the size of the
Visibility Map (see <xref linkend="storage-vm">) associated with the
relation.
relation. Note that this function shows the size of only one fork;
for most purposes it is more convenient to use the higher-level
functions <function>pg_total_relation_size</> or
<function>pg_table_size</>.
</para>
<para>
@ -13334,12 +13384,6 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
appropriate.
</para>
<para>
<function>pg_total_relation_size</> accepts the OID or name of a
table or toast table, and returns the size in bytes of the data
and all associated indexes and toast tables.
</para>
<para>
The functions shown in <xref
linkend="functions-admin-genfile"> provide native access to

View File

@ -5,7 +5,7 @@
* Copyright (c) 2002-2010, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.26 2010/01/12 02:42:52 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.27 2010/01/19 05:50:18 tgl Exp $
*
*/
@ -246,7 +246,7 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
/*
* calculate size of a relation
* calculate size of (one fork of) a relation
*/
static int64
calculate_relation_size(RelFileNode *rfn, ForkNumber forknum)
@ -302,54 +302,148 @@ pg_relation_size(PG_FUNCTION_ARGS)
PG_RETURN_INT64(size);
}
/*
* Compute the on-disk size of files for the relation according to the
* stat function, including heap data, index data, and toast data.
* Calculate total on-disk size of a TOAST relation, including its index.
* Must not be applied to non-TOAST relations.
*/
static int64
calculate_total_relation_size(Oid Relid)
calculate_toast_table_size(Oid toastrelid)
{
Relation heapRel;
Oid toastOid;
int64 size;
ListCell *cell;
ForkNumber forkNum;
int64 size = 0;
Relation toastRel;
Relation toastIdxRel;
ForkNumber forkNum;
heapRel = relation_open(Relid, AccessShareLock);
toastOid = heapRel->rd_rel->reltoastrelid;
toastRel = relation_open(toastrelid, AccessShareLock);
/* Get the heap size */
size = 0;
/* toast heap size, including FSM and VM size */
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(heapRel->rd_node), forkNum);
size += calculate_relation_size(&(toastRel->rd_node), forkNum);
/* Include any dependent indexes */
if (heapRel->rd_rel->relhasindex)
/* toast index size, including FSM and VM size */
toastIdxRel = relation_open(toastRel->rd_rel->reltoastidxid, AccessShareLock);
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(toastIdxRel->rd_node), forkNum);
relation_close(toastIdxRel, AccessShareLock);
relation_close(toastRel, AccessShareLock);
return size;
}
/*
* Calculate total on-disk size of a given table,
* including FSM and VM, plus TOAST table if any.
* Indexes other than the TOAST table's index are not included.
*
* Note that this also behaves sanely if applied to an index or toast table;
* those won't have attached toast tables, but they can have multiple forks.
*/
static int64
calculate_table_size(Oid relOid)
{
int64 size = 0;
Relation rel;
ForkNumber forkNum;
rel = relation_open(relOid, AccessShareLock);
/*
* heap size, including FSM and VM
*/
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(rel->rd_node), forkNum);
/*
* Size of toast relation
*/
if (OidIsValid(rel->rd_rel->reltoastrelid))
size += calculate_toast_table_size(rel->rd_rel->reltoastrelid);
relation_close(rel, AccessShareLock);
return size;
}
/*
* Calculate total on-disk size of all indexes attached to the given table.
*
* Can be applied safely to an index, but you'll just get zero.
*/
static int64
calculate_indexes_size(Oid relOid)
{
int64 size = 0;
Relation rel;
rel = relation_open(relOid, AccessShareLock);
/*
* Aggregate all indexes on the given relation
*/
if (rel->rd_rel->relhasindex)
{
List *index_oids = RelationGetIndexList(heapRel);
List *index_oids = RelationGetIndexList(rel);
ListCell *cell;
foreach(cell, index_oids)
{
Oid idxOid = lfirst_oid(cell);
Relation iRel;
Relation idxRel;
ForkNumber forkNum;
iRel = relation_open(idxOid, AccessShareLock);
idxRel = relation_open(idxOid, AccessShareLock);
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
size += calculate_relation_size(&(iRel->rd_node), forkNum);
size += calculate_relation_size(&(idxRel->rd_node), forkNum);
relation_close(iRel, AccessShareLock);
relation_close(idxRel, AccessShareLock);
}
list_free(index_oids);
}
/* Recursively include toast table (and index) size */
if (OidIsValid(toastOid))
size += calculate_total_relation_size(toastOid);
relation_close(rel, AccessShareLock);
relation_close(heapRel, AccessShareLock);
return size;
}
Datum
pg_table_size(PG_FUNCTION_ARGS)
{
Oid relOid = PG_GETARG_OID(0);
PG_RETURN_INT64(calculate_table_size(relOid));
}
Datum
pg_indexes_size(PG_FUNCTION_ARGS)
{
Oid relOid = PG_GETARG_OID(0);
PG_RETURN_INT64(calculate_indexes_size(relOid));
}
/*
* Compute the on-disk size of all files for the relation,
* including heap data, index data, toast data, FSM, VM.
*/
static int64
calculate_total_relation_size(Oid Relid)
{
int64 size;
/*
* Aggregate the table size, this includes size of
* the heap, toast and toast index with free space
* and visibility map
*/
size = calculate_table_size(Relid);
/*
* Add size of all attached indexes as well
*/
size += calculate_indexes_size(Relid);
return size;
}

View File

@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.574 2010/01/17 22:56:23 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.575 2010/01/19 05:50:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201001171
#define CATALOG_VERSION_NO 201001181
#endif

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.562 2010/01/15 09:19:07 heikki Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.563 2010/01/19 05:50:18 tgl Exp $
*
* NOTES
* The script catalog/genbki.pl reads this file and generates .bki
@ -3702,13 +3702,17 @@ DESCR("total disk space usage for the specified database");
DATA(insert OID = 2168 ( pg_database_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "19" _null_ _null_ _null_ _null_ pg_database_size_name _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified database");
DATA(insert OID = 2325 ( pg_relation_size PGNSP PGUID 14 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ "select pg_catalog.pg_relation_size($1, ''main'')" _null_ _null_ _null_ ));
DESCR("disk space usage for the specified table or index");
DESCR("disk space usage for the main fork of the specified table or index");
DATA(insert OID = 2332 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f f t f v 2 0 20 "2205 25" _null_ _null_ _null_ _null_ pg_relation_size _null_ _null_ _null_ ));
DESCR("disk space usage for the specified fork of a table or index");
DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_total_relation_size _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified table and associated indexes and toast tables");
DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_total_relation_size _null_ _null_ _null_ ));
DESCR("total disk space usage for the specified table and associated indexes");
DATA(insert OID = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f f t f v 1 0 25 "20" _null_ _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ ));
DESCR("convert a long int to a human readable text using size units");
DATA(insert OID = 2997 ( pg_table_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_table_size _null_ _null_ _null_ ));
DESCR("disk space usage for the specified table, including TOAST, free space and visibility map");
DATA(insert OID = 2998 ( pg_indexes_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_indexes_size _null_ _null_ _null_ ));
DESCR("disk space usage for all indexes attached to the specified table");
DATA(insert OID = 2316 ( postgresql_fdw_validator PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "1009 26" _null_ _null_ _null_ _null_ postgresql_fdw_validator _null_ _null_ _null_));

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.343 2010/01/02 16:58:10 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.344 2010/01/19 05:50:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -433,6 +433,8 @@ extern Datum pg_database_size_name(PG_FUNCTION_ARGS);
extern Datum pg_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
extern Datum pg_table_size(PG_FUNCTION_ARGS);
extern Datum pg_indexes_size(PG_FUNCTION_ARGS);
/* genfile.c */
extern Datum pg_stat_file(PG_FUNCTION_ARGS);