]> granicus.if.org Git - postgresql/commitdiff
Add pg_table_size() and pg_indexes_size() to provide more user-friendly
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 19 Jan 2010 05:50:18 +0000 (05:50 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 19 Jan 2010 05:50:18 +0000 (05:50 +0000)
wrappers around the pg_relation_size() function.

Bernd Helmle, reviewed by Greg Smith

doc/src/sgml/func.sgml
src/backend/utils/adt/dbsize.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h

index 49ca0874677a5db9761af4029702f2fa3b294712..3143767dc5ec1cdcedc998b5d1fd420dcaee66cb 100644 (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>
@@ -13207,19 +13207,25 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
     <primary>pg_column_size</primary>
    </indexterm>
    <indexterm>
-    <primary>pg_database_size</primary>
+    <primary>pg_total_relation_size</primary>
    </indexterm>
    <indexterm>
-    <primary>pg_relation_size</primary>
+    <primary>pg_table_size</primary>
    </indexterm>
    <indexterm>
-    <primary>pg_size_pretty</primary>
+    <primary>pg_indexes_size</primary>
+   </indexterm>
+   <indexterm>
+    <primary>pg_database_size</primary>
    </indexterm>
    <indexterm>
     <primary>pg_tablespace_size</primary>
    </indexterm>
    <indexterm>
-    <primary>pg_total_relation_size</primary>
+    <primary>pg_relation_size</primary>
+   </indexterm>
+   <indexterm>
+    <primary>pg_size_pretty</primary>
    </indexterm>
 
    <table id="functions-admin-dbsize">
@@ -13238,44 +13244,48 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
       </row>
       <row>
        <entry>
-        <literal><function>pg_database_size</function>(<type>oid</type>)</literal>
+        <literal><function>pg_total_relation_size</function>(<type>regclass</type>)</literal>
         </entry>
        <entry><type>bigint</type></entry>
-       <entry>Disk space used by the database with the specified OID</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_database_size</function>(<type>name</type>)</literal>
+        <literal><function>pg_table_size</function>(<type>regclass</type>)</literal>
         </entry>
        <entry><type>bigint</type></entry>
-       <entry>Disk space used by the database with the specified name</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_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>, <parameter>fork</parameter> <type>text</type>)</literal>
+        <literal><function>pg_indexes_size</function>(<type>regclass</type>)</literal>
         </entry>
        <entry><type>bigint</type></entry>
        <entry>
-        Disk space used by the specified fork (<literal>'main'</literal>,
-        <literal>'fsm'</literal> or <literal>'vm'</>)
-        of the table or index with the specified OID or name
+        Total disk space used by indexes attached to the table with the
+        specified OID or name
        </entry>
       </row>
       <row>
        <entry>
-        <literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>)</literal>
+        <literal><function>pg_database_size</function>(<type>oid</type>)</literal>
         </entry>
        <entry><type>bigint</type></entry>
-       <entry>
-        Shorthand for <literal>pg_relation_size(..., 'main')</literal>
-       </entry>
+       <entry>Disk space used by the database with the specified OID</entry>
       </row>
       <row>
        <entry>
-        <literal><function>pg_size_pretty</function>(<type>bigint</type>)</literal>
+        <literal><function>pg_database_size</function>(<type>name</type>)</literal>
         </entry>
-       <entry><type>text</type></entry>
-       <entry>Converts a size in bytes into a human-readable format with size units</entry>
+       <entry><type>bigint</type></entry>
+       <entry>Disk space used by the database with the specified name</entry>
       </row>
       <row>
        <entry>
@@ -13293,14 +13303,31 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
       </row>
       <row>
        <entry>
-        <literal><function>pg_total_relation_size</function>(<type>regclass</type>)</literal>
+        <literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>, <parameter>fork</parameter> <type>text</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
+        Disk space used by the specified fork (<literal>'main'</literal>,
+        <literal>'fsm'</literal> or <literal>'vm'</>)
+        of the table or index with the specified OID or name
        </entry>
       </row>
+      <row>
+       <entry>
+        <literal><function>pg_relation_size</function>(<parameter>relation</parameter> <type>regclass</type>)</literal>
+        </entry>
+       <entry><type>bigint</type></entry>
+       <entry>
+        Shorthand for <literal>pg_relation_size(..., 'main')</literal>
+       </entry>
+      </row>
+      <row>
+       <entry>
+        <literal><function>pg_size_pretty</function>(<type>bigint</type>)</literal>
+        </entry>
+       <entry><type>text</type></entry>
+       <entry>Converts a size in bytes into a human-readable format with size units</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
index d8d2aaa238c8b81ea9176656b4feb87fc9c28d9f..47d1df88fa814eb00b774391034665ff87429e85 100644 (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);
 }
 
+/*
+ * 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;
 }
index 1740b2b38c459f22cda7c1bea0ce50884d48aedb..9b36997499a80ee7136af70eaf5bb5c702907069 100644 (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
index a498cc5172006d9b2dedd90353324b9a4647a8eb..e5d6b402b70781475a22b20a288e48d0b6a5b82d 100644 (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_));
 
index 4989f51b16a6c4ae4208d3a75962e13a033b92c8..758aeee79fdac962746be64193605dbc281636d1 100644 (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);