/* * calculate size of (one fork of) a relation * * Iterator over all files belong to the relation and do stat. * The obviously better way is to use glob. For whatever reason, * glob is extremely slow if there are lots of relations in the * database. So we handle all cases, instead. * * Note: we can safely apply this to temp tables of other sessions, so there * is no check here or at the call sites for that. */ static int64 calculate_relation_size(Relation rel, ForkNumber forknum) { int64 totalsize = 0; char *relationpath; char pathname[MAXPGPATH]; unsigned int segcount = 0; relationpath = relpathbackend(rel->rd_node, rel->rd_backend, forknum); if (RelationIsHeap(rel)) { /* Ordinary relation, including heap and index. * They take form of relationpath, or relationpath.%d * There will be no holes, therefore, we can stop when * we reach the first non-existing file. */ for (segcount = 0;; segcount++) { struct stat fst; CHECK_FOR_INTERRUPTS(); if (segcount == 0) snprintf(pathname, MAXPGPATH, "%s", relationpath); else snprintf(pathname, MAXPGPATH, "%s.%u", relationpath, segcount); if (stat(pathname, &fst) < 0) { if (errno == ENOENT) break; else ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file %s: %m", pathname))); } totalsize += fst.st_size; } } /* AO tables don't have any extra forks. */ else if (forknum == MAIN_FORKNUM) { if (RelationIsAoRows(rel)) { totalsize = GetAOTotalBytes(rel, GetActiveSnapshot()); } else if (RelationIsAoCols(rel)) { totalsize = GetAOCSTotalBytes(rel, GetActiveSnapshot(), true); } } /* RELSTORAGE_VIRTUAL has no space usage */ return totalsize; }
/* * calculate size of a relation * * Iterator over all files belong to the relation and do stat. * The obviously better way is to use glob. For whatever reason, * glob is extremely slow if there are lots of relations in the * database. So we handle all cases, instead. */ int64 calculate_relation_size(Relation rel) { int64 totalsize = 0; char *relationpath; char pathname[MAXPGPATH]; struct stat fst; int i; relationpath = relpath(rel->rd_node); if(RelationIsHeap(rel)) { /* Ordinary relation, including heap and index. * They take form of relationpath, or relationpath.%d * There will be no holes, therefore, we can stop we * we reach the first non-exist file. */ for(i=0; ; ++i) { if (i==0) snprintf(pathname, MAXPGPATH, "%s", relationpath); else snprintf(pathname, MAXPGPATH, "%s.%d", relationpath, i); if (stat(pathname, &fst) >= 0) totalsize += fst.st_size; else { if (errno == ENOENT) break; else ereport(ERROR, (errcode_for_file_access(), errmsg("could not stat file %s: %m", pathname) )); } } } else if (RelationIsAoRows(rel)) totalsize = GetAOTotalBytes(rel, SnapshotNow); else if (RelationIsParquet(rel)) totalsize = GetParquetTotalBytes(rel, SnapshotNow); /* RELSTORAGE_VIRTUAL has no space usage */ return totalsize; }