aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/dbsize.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-19 05:50:18 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-19 05:50:18 +0000
commit4f15699d706130540f7cf1ed4f995b61cf50b09c (patch)
treecd3e03ee4f59c272166ebad588a9207de2926d99 /src/backend/utils/adt/dbsize.c
parent309cd7cf183d7e194205d8d97186c09ef67f83ae (diff)
downloadpostgresql-4f15699d706130540f7cf1ed4f995b61cf50b09c.tar.gz
postgresql-4f15699d706130540f7cf1ed4f995b61cf50b09c.zip
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
Diffstat (limited to 'src/backend/utils/adt/dbsize.c')
-rw-r--r--src/backend/utils/adt/dbsize.c146
1 files changed, 120 insertions, 26 deletions
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index d8d2aaa238c..47d1df88fa8 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -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);
}
+/*
+ * Calculate total on-disk size of a TOAST relation, including its index.
+ * Must not be applied to non-TOAST relations.
+ */
+static int64
+calculate_toast_table_size(Oid toastrelid)
+{
+ int64 size = 0;
+ Relation toastRel;
+ Relation toastIdxRel;
+ ForkNumber forkNum;
+
+ toastRel = relation_open(toastrelid, AccessShareLock);
+
+ /* toast heap size, including FSM and VM size */
+ for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ size += calculate_relation_size(&(toastRel->rd_node), forkNum);
+
+ /* 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;
+}
/*
- * 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 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_total_relation_size(Oid Relid)
+calculate_table_size(Oid relOid)
{
- Relation heapRel;
- Oid toastOid;
- int64 size;
- ListCell *cell;
- ForkNumber forkNum;
+ int64 size = 0;
+ Relation rel;
+ ForkNumber forkNum;
- heapRel = relation_open(Relid, AccessShareLock);
- toastOid = heapRel->rd_rel->reltoastrelid;
+ rel = relation_open(relOid, AccessShareLock);
- /* Get the heap size */
- size = 0;
+ /*
+ * heap size, including FSM and VM
+ */
for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
- size += calculate_relation_size(&(heapRel->rd_node), 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;
- /* Include any dependent indexes */
- if (heapRel->rd_rel->relhasindex)
+ 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);
+
+ 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);
- relation_close(heapRel, AccessShareLock);
+ /*
+ * Add size of all attached indexes as well
+ */
+ size += calculate_indexes_size(Relid);
return size;
}