From 29dbf4ad5bfeba14c8de931eee10ff235e0fd131 Mon Sep 17 00:00:00 2001 From: Georgios Kokolatos Date: Mon, 15 Mar 2021 11:29:27 +0000 Subject: [PATCH v5] Attempt to make dbsize a bit more consistent --- src/backend/access/table/tableam.c | 8 ++- src/backend/utils/adt/dbsize.c | 102 +++++++++++++---------------- 2 files changed, 51 insertions(+), 59 deletions(-) diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c index 5ea5bdd810..af0188177a 100644 --- a/src/backend/access/table/tableam.c +++ b/src/backend/access/table/tableam.c @@ -636,10 +636,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 64cdaa4134..d23aa4e140 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" @@ -34,6 +35,8 @@ /* Divide by two and round towards positive infinity. */ #define half_rounded(x) (((x) + ((x) < 0 ? 0 : 1)) / 2) +static int64 calculate_total_relation_size(Relation rel); + /* Return physical size of directory contents, or 0 if dir doesn't exist */ static int64 db_dir_size(const char *path) @@ -327,84 +330,53 @@ pg_relation_size(PG_FUNCTION_ARGS) if (rel == NULL) PG_RETURN_NULL(); - size = calculate_relation_size(&(rel->rd_node), rel->rd_backend, + if (rel->rd_tableam) + size = table_relation_size(rel, forkname_to_number(text_to_cstring(forkName))); + else + size = calculate_relation_size(&(rel->rd_node), rel->rd_backend, + forkname_to_number(text_to_cstring(forkName))); relation_close(rel, AccessShareLock); PG_RETURN_INT64(size); } -/* - * Calculate total on-disk size of a TOAST relation, including its indexes. - * Must not be applied to non-TOAST relations. - */ -static int64 -calculate_toast_table_size(Oid toastrelid) -{ - int64 size = 0; - Relation toastRel; - ForkNumber forkNum; - ListCell *lc; - List *indexlist; - - 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), - toastRel->rd_backend, forkNum); - - /* toast index size, including FSM and VM size */ - indexlist = RelationGetIndexList(toastRel); - - /* Size is calculated using all the indexes available */ - foreach(lc, indexlist) - { - Relation toastIdxRel; - - toastIdxRel = relation_open(lfirst_oid(lc), - AccessShareLock); - for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) - size += calculate_relation_size(&(toastIdxRel->rd_node), - toastIdxRel->rd_backend, forkNum); - - relation_close(toastIdxRel, AccessShareLock); - } - list_free(indexlist); - relation_close(toastRel, AccessShareLock); - - return 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; - * those won't have attached toast tables, but they can have multiple forks. + * Note that this also behaves sanely if applied to a toast table. */ static int64 calculate_table_size(Relation rel) { - int64 size = 0; + uint64 size = 0; ForkNumber forkNum; /* - * heap size, including FSM and VM + * table size, including all implemented forks (e.g. FSM, VM for heap AM) + * excluding TOAST relation */ 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 */ if (OidIsValid(rel->rd_rel->reltoastrelid)) - size += calculate_toast_table_size(rel->rd_rel->reltoastrelid); + { + Relation toastRel; - return size; + toastRel = relation_open(rel->rd_rel->reltoastrelid, AccessShareLock); + + size += calculate_total_relation_size(toastRel); + + relation_close(toastRel, AccessShareLock); + } + + return (int64)size; } /* @@ -452,14 +424,22 @@ 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 (rel->rd_tableam) + size = calculate_table_size(rel); + else + { + for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++) + size += calculate_relation_size(&(rel->rd_node), + rel->rd_backend, + forkNum); + } relation_close(rel, AccessShareLock); @@ -487,7 +467,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) @@ -513,14 +493,22 @@ pg_total_relation_size(PG_FUNCTION_ARGS) { Oid relOid = PG_GETARG_OID(0); Relation rel; - int64 size; + uint64 size = 0; rel = try_relation_open(relOid, AccessShareLock); if (rel == NULL) PG_RETURN_NULL(); - size = calculate_total_relation_size(rel); + if (rel->rd_rel->relkind == RELKIND_RELATION || + rel->rd_rel->relkind == RELKIND_TOASTVALUE || + rel->rd_rel->relkind == RELKIND_MATVIEW) + size = calculate_total_relation_size(rel); + else + { + relation_close(rel, AccessShareLock); + PG_RETURN_NULL(); + } relation_close(rel, AccessShareLock); -- 2.25.1