1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-20 15:22:23 +03:00

Fix confusion between relfilenode and Oid.

Also, make pg_total_relation_size include the size of the
TOAST index.
This commit is contained in:
Alvaro Herrera
2005-09-29 22:04:36 +00:00
parent c775b423c1
commit a7084efd2d

View File

@ -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,23 +216,22 @@ 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++)
{ {
@ -240,10 +239,10 @@ calculate_relation_size(Oid tblspcOid, Oid relnodeOid)
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
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,78 +280,66 @@ 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;
Relation toastRelation;
Oid idxOid;
Oid idxTblspcOid;
Oid toastOid; Oid toastOid;
Oid toastTblspcOid;
bool hasIndices;
int64 size; int64 size;
List *indexoidlist; ListCell *cell;
ListCell *idx;
heapRelation = relation_open(relnodeOid, AccessShareLock); heapRel = relation_open(Relid, AccessShareLock);
toastOid = heapRelation->rd_rel->reltoastrelid; toastOid = heapRel->rd_rel->reltoastrelid;
hasIndices = heapRelation->rd_rel->relhasindex;
/* Get the heap size */ /* Get the heap size */
size = calculate_relation_size(tblspcOid, relnodeOid); size = calculate_relation_size(&(heapRel->rd_node));
/* Get index size */ /* Get index size */
if (hasIndices) if (heapRel->rd_rel->relhasindex)
{ {
/* 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));
list_free(indexoidlist);
relation_close(iRel, AccessShareLock);
} }
relation_close(heapRelation, AccessShareLock); list_free(index_oids);
/* Get toast table size */
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);
} }
/* Get toast table (and index) size */
if (OidIsValid(toastOid))
size += calculate_total_relation_size(toastOid);
relation_close(heapRel, AccessShareLock);
return size; return size;
} }
@ -371,25 +350,9 @@ 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, PG_RETURN_INT64(calculate_total_relation_size(relid));
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));
} }
Datum Datum
@ -397,19 +360,12 @@ 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));
} }
/* /*
@ -424,8 +380,7 @@ pg_size_pretty(PG_FUNCTION_ARGS)
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;