diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index c814733b22..9cce6c3f34 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -516,10 +516,14 @@ table_block_relation_size(Relation rel, ForkNumber forkNumber) if (forkNumber == InvalidForkNumber) { for (int i = 0; i < MAX_FORKNUM; i++) - nblocks += smgrnblocks(rel->rd_smgr, i); + nblocks += smgrexists(rel->rd_smgr, i) + ? smgrnblocks(rel->rd_smgr, i) + : 0; } else - nblocks = smgrnblocks(rel->rd_smgr, forkNumber); + nblocks += smgrexists(rel->rd_smgr, forkNumber) + ? smgrnblocks(rel->rd_smgr, forkNumber) + : 0; return nblocks * BLCKSZ; } diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c index 840664429e..ce51726bc7 100644 --- a/src/backend/utils/adt/dbsize.c +++ b/src/backend/utils/adt/dbsize.c @@ -15,6 +15,7 @@ #include "access/htup_details.h" #include "access/relation.h" +#include "access/tableam.h" #include "catalog/catalog.h" #include "catalog/namespace.h" #include "catalog/pg_authid.h" @@ -342,7 +343,7 @@ pg_relation_size(PG_FUNCTION_ARGS) static int64 calculate_toast_table_size(Oid toastrelid) { - int64 size = 0; + uint64 size = 0; Relation toastRel; ForkNumber forkNum; ListCell *lc; @@ -352,8 +353,7 @@ calculate_toast_table_size(Oid toastrelid) /* toast heap size, including FSM and VM size */ for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) - size += calculate_relation_size(&(toastRel->rd_node), - toastRel->rd_backend, forkNum); + size += table_relation_size(toastRel, forkNum); /* toast index size, including FSM and VM size */ indexlist = RelationGetIndexList(toastRel); @@ -374,29 +374,30 @@ calculate_toast_table_size(Oid toastrelid) list_free(indexlist); relation_close(toastRel, AccessShareLock); - return size; + Assert(size < PG_INT64_MAX); + + return (int64)size; } /* * Calculate total on-disk size of a given table, - * including FSM and VM, plus TOAST table if any. + * 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; + * Note that this also behaves sanely if applied to a toast table; * those won't have attached toast tables, but they can have multiple forks. */ static int64 calculate_table_size(Relation rel) { - int64 size = 0; + uint64 size = 0; ForkNumber forkNum; /* - * heap size, including FSM and VM + * table size, including FSM and VM */ for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) - size += calculate_relation_size(&(rel->rd_node), rel->rd_backend, - forkNum); + size += table_relation_size(rel, forkNum); /* * Size of toast relation @@ -404,7 +405,9 @@ calculate_table_size(Relation rel) if (OidIsValid(rel->rd_rel->reltoastrelid)) size += calculate_toast_table_size(rel->rd_rel->reltoastrelid); - return size; + Assert(size < PG_INT64_MAX); + + return (int64)size; } /* @@ -452,14 +455,17 @@ pg_table_size(PG_FUNCTION_ARGS) { Oid relOid = PG_GETARG_OID(0); Relation rel; - int64 size; + int64 size = 0; rel = try_relation_open(relOid, AccessShareLock); if (rel == NULL) PG_RETURN_NULL(); - size = calculate_table_size(rel); + if (RELKIND_HAS_STORAGE(rel->rd_rel->relkind) && + rel->rd_rel->relkind != RELKIND_INDEX && + rel->rd_rel->relkind != RELKIND_SEQUENCE) + size = calculate_table_size(rel); relation_close(rel, AccessShareLock); @@ -487,7 +493,7 @@ pg_indexes_size(PG_FUNCTION_ARGS) /* * Compute the on-disk size of all files for the relation, - * including heap data, index data, toast data, FSM, VM. + * including table data, index data, toast data. */ static int64 calculate_total_relation_size(Relation rel)