From 706a308806a066017c63024c454bb02953c9822c Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Fri, 3 Oct 2008 07:33:10 +0000 Subject: [PATCH] Add relation fork support to pg_relation_size() function. You can now pass name of a fork ('main' or 'fsm', at the moment) to pg_relation_size() to get the size of a specific fork. Defaults to 'main', if none given. While we're at it, modify pg_relation_size to take a regclass as argument, instead of separate variants taking oid and name. This change is transparent to typical use where the table name is passed as a string literal, like pg_relation_size('table'), but will break queries like pg_relation_size(namecol), where namecol is of type name. text-type input still works, and using a non-schema-qualified table name is not very reliable anyway, so this is unlikely to break anyone's queries in practice. --- doc/src/sgml/func.sgml | 38 +++++++------- src/backend/utils/adt/dbsize.c | 83 ++++++++++++++++--------------- src/include/catalog/catversion.h | 4 +- src/include/catalog/pg_proc.h | 12 ++--- src/include/storage/relfilenode.h | 7 ++- src/include/utils/builtins.h | 8 ++- 6 files changed, 76 insertions(+), 76 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 05f0aabddd..31ef6dc864 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -1,4 +1,4 @@ - + Functions and Operators @@ -12417,7 +12417,7 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); - pg_column_size(any) + pg_column_size(any) int Number of bytes used to store a particular value (possibly compressed) @@ -12437,19 +12437,22 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); - pg_relation_size(oid) + pg_relation_size(relation regclass, fork text) bigint - Disk space used by the table or index with the specified OID + + Disk space used by the specified fork, 'main' or + 'fsm', of a table or index with the specified OID + or name. The table name can be qualified with a schema name + - pg_relation_size(text) + pg_relation_size(relation regclass) bigint - Disk space used by the table or index with the specified name. - The table name can be qualified with a schema name + Shorthand for pg_relation_size(..., 'main') @@ -12475,21 +12478,11 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); - pg_total_relation_size(oid) + pg_total_relation_size(regclass) bigint - Total disk space used by the table with the specified OID, - including indexes and toasted data - - - - - pg_total_relation_size(text) - - bigint - - Total disk space used by the table with the specified name, + Total disk space used by the table with the specified OID or name, including indexes and toasted data. The table name can be qualified with a schema name @@ -12511,7 +12504,12 @@ postgres=# select * from pg_xlogfile_name_offset(pg_stop_backup()); pg_relation_size accepts the OID or name of a table, index or - toast table, and returns the size in bytes. + toast table, and returns the size in bytes. Specifying + 'main' or leaving out the second argument returns the + size of the main data fork of the relation. Specifying + 'fsm' returns the size of the + Free Space Map (see ) associated with the + relation. diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index e85d11c383..d225b3e7c7 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -5,7 +5,7 @@ * Copyright (c) 2002-2008, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.20 2008/08/11 11:05:11 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.21 2008/10/03 07:33:09 heikki Exp $ * */ @@ -248,15 +248,14 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS) * calculate size of a relation */ static int64 -calculate_relation_size(RelFileNode *rfn) +calculate_relation_size(RelFileNode *rfn, ForkNumber forknum) { int64 totalsize = 0; char *relationpath; char pathname[MAXPGPATH]; unsigned int segcount = 0; - /* XXX: This ignores the other forks. */ - relationpath = relpath(*rfn, MAIN_FORKNUM); + relationpath = relpath(*rfn, forknum); for (segcount = 0;; segcount++) { @@ -284,34 +283,47 @@ calculate_relation_size(RelFileNode *rfn) return totalsize; } + +/* + * XXX: Consider making this global and moving elsewhere. But currently + * there's no other users for this. + * + * Remember to also update the errhint below if you add entries, and the + * documentation for pg_relation_size(). + */ +static char *forkNames[] = { + "main", /* MAIN_FORKNUM */ + "fsm" /* FSM_FORKNUM */ +}; + +static ForkNumber +forkname_to_number(char *forkName) +{ + ForkNumber forkNum; + + for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) + if (strcmp(forkNames[forkNum], forkName) == 0) + return forkNum; + + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid fork name"), + errhint("Valid fork names are 'main' and 'fsm'"))); + return InvalidForkNumber; /* keep compiler quiet */ +} + Datum -pg_relation_size_oid(PG_FUNCTION_ARGS) +pg_relation_size(PG_FUNCTION_ARGS) { Oid relOid = PG_GETARG_OID(0); + text *forkName = PG_GETARG_TEXT_P(1); Relation rel; int64 size; rel = relation_open(relOid, AccessShareLock); - size = calculate_relation_size(&(rel->rd_node)); - - relation_close(rel, AccessShareLock); - - PG_RETURN_INT64(size); -} - -Datum -pg_relation_size_name(PG_FUNCTION_ARGS) -{ - text *relname = PG_GETARG_TEXT_P(0); - RangeVar *relrv; - Relation rel; - int64 size; - - relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - rel = relation_openrv(relrv, AccessShareLock); - - size = calculate_relation_size(&(rel->rd_node)); + size = calculate_relation_size(&(rel->rd_node), + forkname_to_number(text_to_cstring(forkName))); relation_close(rel, AccessShareLock); @@ -330,12 +342,15 @@ calculate_total_relation_size(Oid Relid) Oid toastOid; int64 size; ListCell *cell; + ForkNumber forkNum; heapRel = relation_open(Relid, AccessShareLock); toastOid = heapRel->rd_rel->reltoastrelid; /* Get the heap size */ - size = calculate_relation_size(&(heapRel->rd_node)); + size = 0; + for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) + size += calculate_relation_size(&(heapRel->rd_node), forkNum); /* Include any dependent indexes */ if (heapRel->rd_rel->relhasindex) @@ -349,7 +364,8 @@ calculate_total_relation_size(Oid Relid) iRel = relation_open(idxOid, AccessShareLock); - size += calculate_relation_size(&(iRel->rd_node)); + for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) + size += calculate_relation_size(&(iRel->rd_node), forkNum); relation_close(iRel, AccessShareLock); } @@ -367,26 +383,13 @@ calculate_total_relation_size(Oid Relid) } Datum -pg_total_relation_size_oid(PG_FUNCTION_ARGS) +pg_total_relation_size(PG_FUNCTION_ARGS) { Oid relid = PG_GETARG_OID(0); PG_RETURN_INT64(calculate_total_relation_size(relid)); } -Datum -pg_total_relation_size_name(PG_FUNCTION_ARGS) -{ - text *relname = PG_GETARG_TEXT_P(0); - RangeVar *relrv; - Oid relid; - - relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); - relid = RangeVarGetRelid(relrv, false); - - PG_RETURN_INT64(calculate_total_relation_size(relid)); -} - /* * formatting with size units */ diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 99b90624d6..e333b6d6d6 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -37,7 +37,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.490 2008/09/30 11:11:28 heikki Exp $ + * $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.491 2008/10/03 07:33:09 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 200809301 +#define CATALOG_VERSION_NO 200810031 #endif diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 42d8ce7fe8..2b3de5ece1 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.515 2008/09/19 19:03:40 tgl Exp $ + * $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.516 2008/10/03 07:33:09 heikki Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -3591,13 +3591,11 @@ DATA(insert OID = 2324 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 " DESCR("total disk space usage for the specified database"); DATA(insert OID = 2168 ( pg_database_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "19" _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 12 1 0 0 f f t f v 1 20 "26" _null_ _null_ _null_ pg_relation_size_oid _null_ _null_ _null_ )); +DATA(insert OID = 2325 ( pg_relation_size PGNSP PGUID 14 1 0 0 f f t f v 1 20 "2205" _null_ _null_ _null_ "select pg_catalog.pg_relation_size($1, ''main'')" _null_ _null_ _null_ )); DESCR("disk space usage for the specified table or index"); -DATA(insert OID = 2289 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "25" _null_ _null_ _null_ pg_relation_size_name _null_ _null_ _null_ )); -DESCR("disk space usage for the specified table or index"); -DATA(insert OID = 2286 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "26" _null_ _null_ _null_ pg_total_relation_size_oid _null_ _null_ _null_ )); -DESCR("total disk space usage for the specified table and associated indexes and toast tables"); -DATA(insert OID = 2287 ( pg_total_relation_size PGNSP PGUID 12 1 0 0 f f t f v 1 20 "25" _null_ _null_ _null_ pg_total_relation_size_name _null_ _null_ _null_ )); +DATA(insert OID = 2332 ( pg_relation_size PGNSP PGUID 12 1 0 0 f f t f v 2 20 "2205 25" _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 t f v 1 20 "2205" _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 = 2288 ( pg_size_pretty PGNSP PGUID 12 1 0 0 f f t f v 1 25 "20" _null_ _null_ _null_ pg_size_pretty _null_ _null_ _null_ )); DESCR("convert a long int to a human readable text using size units"); diff --git a/src/include/storage/relfilenode.h b/src/include/storage/relfilenode.h index 571f261c3d..128cff99a9 100644 --- a/src/include/storage/relfilenode.h +++ b/src/include/storage/relfilenode.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.17 2008/09/30 10:52:14 heikki Exp $ + * $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.18 2008/10/03 07:33:10 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -25,7 +25,10 @@ typedef enum ForkNumber InvalidForkNumber = -1, MAIN_FORKNUM = 0, FSM_FORKNUM - /* NOTE: change MAX_FORKNUM below when you add new forks */ + /* + * NOTE: if you add a new fork, change MAX_FORKNUM below and update the + * name to number mapping in utils/adt/dbsize.c + */ } ForkNumber; #define MAX_FORKNUM FSM_FORKNUM diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 09d38e9c1c..58ccb03429 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.320 2008/09/06 00:01:25 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.321 2008/10/03 07:33:10 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -389,10 +389,8 @@ extern Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS); extern Datum pg_tablespace_size_name(PG_FUNCTION_ARGS); extern Datum pg_database_size_oid(PG_FUNCTION_ARGS); extern Datum pg_database_size_name(PG_FUNCTION_ARGS); -extern Datum pg_relation_size_oid(PG_FUNCTION_ARGS); -extern Datum pg_relation_size_name(PG_FUNCTION_ARGS); -extern Datum pg_total_relation_size_oid(PG_FUNCTION_ARGS); -extern Datum pg_total_relation_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); /* genfile.c */