Skip to content
Snippets Groups Projects
Commit a7084efd authored by Alvaro Herrera's avatar Alvaro Herrera
Browse files

Fix confusion between relfilenode and Oid.

Also, make pg_total_relation_size include the size of the
TOAST index.
parent c775b423
No related branches found
No related tags found
No related merge requests found
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright (c) 2002-2005, PostgreSQL Global Development Group * Copyright (c) 2002-2005, PostgreSQL Global Development Group
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.4 2005/09/16 05:35:40 neilc Exp $ * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.5 2005/09/29 22:04:36 alvherre Exp $
* *
*/ */
...@@ -216,34 +216,33 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS) ...@@ -216,34 +216,33 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
* calculate size of a relation * calculate size of a relation
*/ */
static int64 static int64
calculate_relation_size(Oid tblspcOid, Oid relnodeOid) calculate_relation_size(RelFileNode *rfn)
{ {
int64 totalsize=0; int64 totalsize = 0;
unsigned int segcount=0; char dirpath[MAXPGPATH];
char dirpath[MAXPGPATH]; char pathname[MAXPGPATH];
char pathname[MAXPGPATH]; unsigned int segcount = 0;
if (!tblspcOid) Assert(OidIsValid(rfn->spcNode));
tblspcOid = MyDatabaseTableSpace;
if (tblspcOid == DEFAULTTABLESPACE_OID) if (rfn->spcNode == DEFAULTTABLESPACE_OID)
snprintf(dirpath, MAXPGPATH, "%s/base/%u", DataDir, MyDatabaseId); snprintf(dirpath, MAXPGPATH, "%s/base/%u", DataDir, rfn->dbNode);
else if (tblspcOid == GLOBALTABLESPACE_OID) else if (rfn->spcNode == GLOBALTABLESPACE_OID)
snprintf(dirpath, MAXPGPATH, "%s/global", DataDir); snprintf(dirpath, MAXPGPATH, "%s/global", DataDir);
else else
snprintf(dirpath, MAXPGPATH, "%s/pg_tblspc/%u/%u", snprintf(dirpath, MAXPGPATH, "%s/pg_tblspc/%u/%u",
DataDir, tblspcOid, MyDatabaseId); DataDir, rfn->spcNode, rfn->dbNode);
for (segcount = 0 ;; segcount++) for (segcount = 0; ; segcount++)
{ {
struct stat fst; struct stat fst;
if (segcount == 0) if (segcount == 0)
snprintf(pathname, MAXPGPATH, "%s/%u", snprintf(pathname, MAXPGPATH, "%s/%u",
dirpath, relnodeOid); dirpath, rfn->relNode);
else else
snprintf(pathname, MAXPGPATH, "%s/%u.%u", snprintf(pathname, MAXPGPATH, "%s/%u.%u",
dirpath, relnodeOid, segcount); dirpath, rfn->relNode, segcount);
if (stat(pathname, &fst) < 0) if (stat(pathname, &fst) < 0)
{ {
...@@ -264,24 +263,16 @@ Datum ...@@ -264,24 +263,16 @@ Datum
pg_relation_size_oid(PG_FUNCTION_ARGS) pg_relation_size_oid(PG_FUNCTION_ARGS)
{ {
Oid relOid=PG_GETARG_OID(0); Oid relOid=PG_GETARG_OID(0);
HeapTuple tuple; Relation rel;
Form_pg_class pg_class; int64 size;
Oid relnodeOid;
Oid tblspcOid;
tuple = SearchSysCache(RELOID, rel = relation_open(relOid, AccessShareLock);
ObjectIdGetDatum(relOid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", relOid);
pg_class = (Form_pg_class) GETSTRUCT(tuple); size = calculate_relation_size(&(rel->rd_node));
relnodeOid = pg_class->relfilenode;
tblspcOid = pg_class->reltablespace;
ReleaseSysCache(tuple); relation_close(rel, AccessShareLock);
PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid)); PG_RETURN_INT64(size);
} }
Datum Datum
...@@ -289,77 +280,65 @@ pg_relation_size_name(PG_FUNCTION_ARGS) ...@@ -289,77 +280,65 @@ pg_relation_size_name(PG_FUNCTION_ARGS)
{ {
text *relname = PG_GETARG_TEXT_P(0); text *relname = PG_GETARG_TEXT_P(0);
RangeVar *relrv; RangeVar *relrv;
Relation relation; Relation rel;
Oid relnodeOid; int64 size;
Oid tblspcOid;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
relation = relation_openrv(relrv, AccessShareLock); rel = relation_openrv(relrv, AccessShareLock);
tblspcOid = relation->rd_rel->reltablespace; size = calculate_relation_size(&(rel->rd_node));
relnodeOid = relation->rd_rel->relfilenode;
relation_close(relation, AccessShareLock); relation_close(rel, AccessShareLock);
PG_RETURN_INT64(calculate_relation_size(tblspcOid, relnodeOid)); PG_RETURN_INT64(size);
} }
/* /*
* Compute the on-disk size of files for 'relation' according to the * Compute the on-disk size of files for the relation according to the
* stat function, optionally including heap data, index data, and/or * stat function, optionally including heap data, index data, and/or
* toast data. * toast data.
*/ */
static int64 static int64
calculate_total_relation_size(Oid tblspcOid, Oid relnodeOid) calculate_total_relation_size(Oid Relid)
{ {
Relation heapRelation; Relation heapRel;
Relation idxRelation; Oid toastOid;
Relation toastRelation; int64 size;
Oid idxOid; ListCell *cell;
Oid idxTblspcOid;
Oid toastOid; heapRel = relation_open(Relid, AccessShareLock);
Oid toastTblspcOid; toastOid = heapRel->rd_rel->reltoastrelid;
bool hasIndices;
int64 size; /* Get the heap size */
List *indexoidlist; size = calculate_relation_size(&(heapRel->rd_node));
ListCell *idx;
/* Get index size */
heapRelation = relation_open(relnodeOid, AccessShareLock); if (heapRel->rd_rel->relhasindex)
toastOid = heapRelation->rd_rel->reltoastrelid;
hasIndices = heapRelation->rd_rel->relhasindex;
/* Get the heap size */
size = calculate_relation_size(tblspcOid, relnodeOid);
/* Get index size */
if (hasIndices)
{ {
/* recursively include any dependent indexes */ /* recursively include any dependent indexes */
indexoidlist = RelationGetIndexList(heapRelation); List *index_oids = RelationGetIndexList(heapRel);
foreach(idx, indexoidlist) foreach(cell, index_oids)
{ {
idxOid = lfirst_oid(idx); Oid idxOid = lfirst_oid(cell);
idxRelation = relation_open(idxOid, AccessShareLock); Relation iRel;
idxTblspcOid = idxRelation->rd_rel->reltablespace;
size += calculate_relation_size(idxTblspcOid, idxOid); iRel = relation_open(idxOid, AccessShareLock);
relation_close(idxRelation, AccessShareLock);
size += calculate_relation_size(&(iRel->rd_node));
relation_close(iRel, AccessShareLock);
} }
list_free(indexoidlist);
list_free(index_oids);
} }
relation_close(heapRelation, AccessShareLock); /* Get toast table (and index) size */
if (OidIsValid(toastOid))
size += calculate_total_relation_size(toastOid);
/* Get toast table size */ relation_close(heapRel, AccessShareLock);
if (toastOid != 0)
{
/* recursively include any toast relations */
toastRelation = relation_open(toastOid, AccessShareLock);
toastTblspcOid = toastRelation->rd_rel->reltablespace;
size += calculate_relation_size(toastTblspcOid, toastOid);
relation_close(toastRelation, AccessShareLock);
}
return size; return size;
} }
...@@ -371,45 +350,22 @@ calculate_total_relation_size(Oid tblspcOid, Oid relnodeOid) ...@@ -371,45 +350,22 @@ calculate_total_relation_size(Oid tblspcOid, Oid relnodeOid)
Datum Datum
pg_total_relation_size_oid(PG_FUNCTION_ARGS) pg_total_relation_size_oid(PG_FUNCTION_ARGS)
{ {
Oid relOid=PG_GETARG_OID(0); Oid relid = PG_GETARG_OID(0);
HeapTuple tuple;
Form_pg_class pg_class;
Oid relnodeOid;
Oid tblspcOid;
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relOid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "cache lookup failed for relation %u", relOid);
pg_class = (Form_pg_class) GETSTRUCT(tuple);
relnodeOid = pg_class->relfilenode;
tblspcOid = pg_class->reltablespace;
ReleaseSysCache(tuple);
PG_RETURN_INT64(calculate_total_relation_size(tblspcOid, relnodeOid)); PG_RETURN_INT64(calculate_total_relation_size(relid));
} }
Datum Datum
pg_total_relation_size_name(PG_FUNCTION_ARGS) pg_total_relation_size_name(PG_FUNCTION_ARGS)
{ {
text *relname = PG_GETARG_TEXT_P(0); text *relname = PG_GETARG_TEXT_P(0);
RangeVar *relrv; RangeVar *relrv;
Relation relation; Oid relid;
Oid relnodeOid;
Oid tblspcOid;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
relation = relation_openrv(relrv, AccessShareLock); relid = RangeVarGetRelid(relrv, false);
tblspcOid = relation->rd_rel->reltablespace; PG_RETURN_INT64(calculate_total_relation_size(relid));
relnodeOid = relation->rd_rel->relfilenode;
relation_close(relation, AccessShareLock);
PG_RETURN_INT64(calculate_total_relation_size(tblspcOid, relnodeOid));
} }
/* /*
...@@ -418,37 +374,36 @@ pg_total_relation_size_name(PG_FUNCTION_ARGS) ...@@ -418,37 +374,36 @@ pg_total_relation_size_name(PG_FUNCTION_ARGS)
Datum Datum
pg_size_pretty(PG_FUNCTION_ARGS) pg_size_pretty(PG_FUNCTION_ARGS)
{ {
int64 size=PG_GETARG_INT64(0); int64 size = PG_GETARG_INT64(0);
char *result=palloc(50+VARHDRSZ); char *result = palloc(50 + VARHDRSZ);
int64 limit = 10*1024; int64 limit = 10 * 1024;
int64 mult=1; int64 mult = 1;
if (size < limit*mult) if (size < limit * mult)
snprintf(VARDATA(result), 50, INT64_FORMAT" bytes", snprintf(VARDATA(result), 50, INT64_FORMAT " bytes", size);
size);
else else
{ {
mult *= 1024; mult *= 1024;
if (size < limit*mult) if (size < limit * mult)
snprintf(VARDATA(result), 50, INT64_FORMAT " kB", snprintf(VARDATA(result), 50, INT64_FORMAT " kB",
(size+mult/2) / mult); (size + mult / 2) / mult);
else else
{ {
mult *= 1024; mult *= 1024;
if (size < limit*mult) if (size < limit * mult)
snprintf(VARDATA(result), 50, INT64_FORMAT " MB", snprintf(VARDATA(result), 50, INT64_FORMAT " MB",
(size+mult/2) / mult); (size + mult / 2) / mult);
else else
{ {
mult *= 1024; mult *= 1024;
if (size < limit*mult) if (size < limit * mult)
snprintf(VARDATA(result), 50, INT64_FORMAT " GB", snprintf(VARDATA(result), 50, INT64_FORMAT " GB",
(size+mult/2) / mult); (size + mult / 2) / mult);
else else
{ {
mult *= 1024; mult *= 1024;
snprintf(VARDATA(result), 50, INT64_FORMAT " TB", snprintf(VARDATA(result), 50, INT64_FORMAT " TB",
(size+mult/2) / mult); (size + mult / 2) / mult);
} }
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment