PostgreSQL Source Code: src/backend/utils/adt/dbsize.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

13

14#include <sys/stat.h>

15

33

34

35#define half_rounded(x) (((x) + ((x) < 0 ? -1 : 1)) / 2)

36

37

39{

40 const char *name;

41 uint32 limit;

42

43 bool round;

44 uint8 unitbits;

45

46};

47

48

50 {"bytes", 10 * 1024, false, 0},

51 {"kB", 20 * 1024 - 1, true, 10},

52 {"MB", 20 * 1024 - 1, true, 20},

53 {"GB", 20 * 1024 - 1, true, 30},

54 {"TB", 20 * 1024 - 1, true, 40},

55 {"PB", 20 * 1024 - 1, true, 50},

56 {NULL, 0, false, 0}

57};

58

59

61{

63 int unit_index;

64};

65

66

68 {"B", 0},

69 {NULL}

70};

71

72

75{

76 int64 dirsize = 0;

77 struct dirent *direntry;

78 DIR *dirdesc;

80

82

83 if (!dirdesc)

84 return 0;

85

86 while ((direntry = ReadDir(dirdesc, path)) != NULL)

87 {

88 struct stat fst;

89

91

92 if (strcmp(direntry->d_name, ".") == 0 ||

93 strcmp(direntry->d_name, "..") == 0)

94 continue;

95

97

99 {

100 if (errno == ENOENT)

101 continue;

102 else

105 errmsg("could not stat file \"%s\": %m", filename)));

106 }

108 }

109

111 return dirsize;

112}

113

114

115

116

119{

121 DIR *dirdesc;

122 struct dirent *direntry;

126

127

128

129

130

134 {

137 }

138

139

140

141

142 snprintf(pathname, sizeof(pathname), "base/%u", dbOid);

144

145

148

149 while ((direntry = ReadDir(dirdesc, dirpath)) != NULL)

150 {

152

153 if (strcmp(direntry->d_name, ".") == 0 ||

154 strcmp(direntry->d_name, "..") == 0)

155 continue;

156

157 snprintf(pathname, sizeof(pathname), "%s/%s/%s/%u",

160 }

161

163

164 return totalsize;

165}

166

169{

172

173

174

175

176

179 errcode(ERRCODE_UNDEFINED_OBJECT),

180 errmsg("database with OID %u does not exist", dbOid));

181

183

184 if (size == 0)

186

188}

189

192{

196

198

199 if (size == 0)

201

203}

204

205

206

207

208

209

212{

215 int64 totalsize = 0;

216 DIR *dirdesc;

217 struct dirent *direntry;

219

220

221

222

223

224

227 {

232 }

233

234 if (tblspcOid == DEFAULTTABLESPACE_OID)

236 else if (tblspcOid == GLOBALTABLESPACE_OID)

238 else

241

243

244 if (!dirdesc)

245 return -1;

246

247 while ((direntry = ReadDir(dirdesc, tblspcPath)) != NULL)

248 {

249 struct stat fst;

250

252

253 if (strcmp(direntry->d_name, ".") == 0 ||

254 strcmp(direntry->d_name, "..") == 0)

255 continue;

256

257 snprintf(pathname, sizeof(pathname), "%s/%s", tblspcPath, direntry->d_name);

258

259 if (stat(pathname, &fst) < 0)

260 {

261 if (errno == ENOENT)

262 continue;

263 else

266 errmsg("could not stat file \"%s\": %m", pathname)));

267 }

268

271

272 totalsize += fst.st_size;

273 }

274

276

277 return totalsize;

278}

279

282{

285

286

287

288

289

292 errcode(ERRCODE_UNDEFINED_OBJECT),

293 errmsg("tablespace with OID %u does not exist", tblspcOid));

294

296

297 if (size < 0)

299

301}

302

305{

309

311

312 if (size < 0)

314

316}

317

318

319

320

321

322

323

324

327{

328 int64 totalsize = 0;

331 unsigned int segcount = 0;

332

333 relationpath = relpathbackend(*rfn, backend, forknum);

334

335 for (segcount = 0;; segcount++)

336 {

337 struct stat fst;

338

340

341 if (segcount == 0)

343 relationpath.str);

344 else

346 relationpath.str, segcount);

347

348 if (stat(pathname, &fst) < 0)

349 {

350 if (errno == ENOENT)

351 break;

352 else

355 errmsg("could not stat file \"%s\": %m", pathname)));

356 }

357 totalsize += fst.st_size;

358 }

359

360 return totalsize;

361}

362

365{

370

372

373

374

375

376

377

378

379

380 if (rel == NULL)

382

385

387

389}

390

391

392

393

394

397{

402 List *indexlist;

403

405

406

407 for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)

410

411

413

414

415 foreach(lc, indexlist)

416 {

418

421 for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)

424

426 }

429

430 return size;

431}

432

433

434

435

436

437

438

439

440

443{

446

447

448

449

450 for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)

452 forkNum);

453

454

455

456

459

460 return size;

461}

462

463

464

465

466

467

470{

472

473

474

475

476 if (rel->rd_rel->relhasindex)

477 {

480

481 foreach(cell, index_oids)

482 {

486

488

489 for (forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)

492 forkNum);

493

495 }

496

498 }

499

500 return size;

501}

502

505{

509

511

512 if (rel == NULL)

514

516

518

520}

521

524{

528

530

531 if (rel == NULL)

533

535

537

539}

540

541

542

543

544

547{

549

550

551

552

553

555

556

557

558

560

561 return size;

562}

563

566{

570

572

573 if (rel == NULL)

575

577

579

581}

582

583

584

585

588{

590 char buf[64];

592

594 {

597

598

599

600

601

602 if (unit[1].name == NULL || abs_size < unit->limit)

603 {

606

608 break;

609 }

610

611

612

613

614

615

616

617

618

619

621 + (unit->round == true));

622 size /= ((int64) 1) << bits;

623 }

624

626}

627

628static char *

630{

632

634}

635

636static bool

638{

641

643}

644

647{

650

653}

654

657{

663

667

670 else

672

675}

676

679{

681 Datum divisor_numeric;

683

687}

688

691{

693 char *result = NULL;

695

697 {

698 unsigned int shiftby;

699

700

701 if (unit[1].name == NULL ||

704 {

707

709 break;

710 }

711

712

713

714

715

716

717

718

720 + (unit->round == true));

722 }

723

725}

726

727

728

729

732{

734 char *str,

735 *strptr,

736 *endptr;

737 char saved_char;

740 bool have_digits = false;

741

743

744

745 strptr = str;

746 while (isspace((unsigned char) *strptr))

747 strptr++;

748

749

750 endptr = strptr;

751

752

753 if (*endptr == '-' || *endptr == '+')

754 endptr++;

755

756

757 if (isdigit((unsigned char) *endptr))

758 {

759 have_digits = true;

760 do

761 endptr++;

762 while (isdigit((unsigned char) *endptr));

763 }

764

765

766 if (*endptr == '.')

767 {

768 endptr++;

769 if (isdigit((unsigned char) *endptr))

770 {

771 have_digits = true;

772 do

773 endptr++;

774 while (isdigit((unsigned char) *endptr));

775 }

776 }

777

778

779 if (!have_digits)

781 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

782 errmsg("invalid size: \"%s\"", str)));

783

784

785 if (*endptr == 'e' || *endptr == 'E')

786 {

787 long exponent;

788 char *cp;

789

790

791

792

793

794 exponent = strtol(endptr + 1, &cp, 10);

795 (void) exponent;

796 if (cp > endptr + 1)

797 endptr = cp;

798 }

799

800

801

802

803

804 saved_char = *endptr;

805 *endptr = '\0';

806

811

812 *endptr = saved_char;

813

814

815 strptr = endptr;

816 while (isspace((unsigned char) *strptr))

817 strptr++;

818

819

820 if (*strptr != '\0')

821 {

823 int64 multiplier = 0;

824

825

827

828 while (isspace((unsigned char) *endptr))

829 endptr--;

830

831 endptr++;

832 *endptr = '\0';

833

835 {

836

838 break;

839 }

840

841

842 if (unit->name == NULL)

843 {

845 {

847 {

849 break;

850 }

851 }

852 }

853

854

855 if (unit->name == NULL)

857 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

859 errdetail("Invalid size unit: \"%s\".", strptr),

860 errhint("Valid units are \"bytes\", \"B\", \"kB\", \"MB\", \"GB\", \"TB\", and \"PB\".")));

861

863

864 if (multiplier > 1)

865 {

867

869

873 }

874 }

875

878

880}

881

882

883

884

885

886

887

888

889

890

891

892

893

894

895

898{

903

908

909 if (RELKIND_HAS_STORAGE(relform->relkind))

910 {

911 if (relform->relfilenode)

912 result = relform->relfilenode;

913 else

915 relform->relisshared);

916 }

917 else

918 {

919

921 }

922

924

927

929}

930

931

932

933

934

935

936

937

938

939

940

941

942

943

946{

949 Oid heaprel;

950

951

954

956

959 else

961}

962

963

964

965

966

967

970{

977

982

983 if (RELKIND_HAS_STORAGE(relform->relkind))

984 {

985

986 if (relform->reltablespace)

987 rlocator.spcOid = relform->reltablespace;

988 else

990 if (rlocator.spcOid == GLOBALTABLESPACE_OID)

992 else

994 if (relform->relfilenode)

995 rlocator.relNumber = relform->relfilenode;

996 else

998 relform->relisshared);

999 }

1000 else

1001 {

1002

1004

1007 }

1008

1010 {

1013 }

1014

1015

1016 switch (relform->relpersistence)

1017 {

1018 case RELPERSISTENCE_UNLOGGED:

1019 case RELPERSISTENCE_PERMANENT:

1021 break;

1022 case RELPERSISTENCE_TEMP:

1025 else

1026 {

1027

1030 }

1031 break;

1032 default:

1033 elog(ERROR, "invalid relpersistence: %c", relform->relpersistence);

1035 break;

1036 }

1037

1039

1041

1043}

bool has_privs_of_role(Oid member, Oid role)

void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)

AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)

char * get_tablespace_name(Oid spc_oid)

Oid get_tablespace_oid(const char *tablespacename, bool missing_ok)

Datum numeric_sub(PG_FUNCTION_ARGS)

Numeric int64_to_numeric(int64 val)

Datum numeric_int8(PG_FUNCTION_ARGS)

Datum numeric_ge(PG_FUNCTION_ARGS)

Datum numeric_out(PG_FUNCTION_ARGS)

Datum numeric_div_trunc(PG_FUNCTION_ARGS)

Datum numeric_in(PG_FUNCTION_ARGS)

Datum numeric_lt(PG_FUNCTION_ARGS)

Datum numeric_add(PG_FUNCTION_ARGS)

Datum numeric_abs(PG_FUNCTION_ARGS)

Datum numeric_mul(PG_FUNCTION_ARGS)

#define OidIsValid(objectId)

Oid get_database_oid(const char *dbname, bool missing_ok)

char * get_database_name(Oid dbid)

static int64 calculate_total_relation_size(Relation rel)

static char * numeric_to_cstring(Numeric n)

static bool numeric_is_less(Numeric a, Numeric b)

Datum pg_indexes_size(PG_FUNCTION_ARGS)

Datum pg_size_bytes(PG_FUNCTION_ARGS)

static Numeric numeric_truncated_divide(Numeric n, int64 divisor)

static const struct size_bytes_unit_alias size_bytes_aliases[]

Datum pg_database_size_oid(PG_FUNCTION_ARGS)

Datum pg_total_relation_size(PG_FUNCTION_ARGS)

Datum pg_tablespace_size_name(PG_FUNCTION_ARGS)

static int64 calculate_tablespace_size(Oid tblspcOid)

Datum pg_size_pretty_numeric(PG_FUNCTION_ARGS)

Datum pg_relation_size(PG_FUNCTION_ARGS)

static int64 calculate_indexes_size(Relation rel)

static int64 db_dir_size(const char *path)

Datum pg_database_size_name(PG_FUNCTION_ARGS)

static Numeric numeric_absolute(Numeric n)

Datum pg_size_pretty(PG_FUNCTION_ARGS)

static int64 calculate_database_size(Oid dbOid)

Datum pg_table_size(PG_FUNCTION_ARGS)

Datum pg_tablespace_size_oid(PG_FUNCTION_ARGS)

static Numeric numeric_half_rounded(Numeric n)

Datum pg_relation_filenode(PG_FUNCTION_ARGS)

Datum pg_filenode_relation(PG_FUNCTION_ARGS)

static const struct size_pretty_unit size_pretty_units[]

static int64 calculate_relation_size(RelFileLocator *rfn, ProcNumber backend, ForkNumber forknum)

Datum pg_relation_filepath(PG_FUNCTION_ARGS)

static int64 calculate_toast_table_size(Oid toastrelid)

static int64 calculate_table_size(Relation rel)

int errcode_for_file_access(void)

int errdetail(const char *fmt,...)

int errhint(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

DIR * AllocateDir(const char *dirname)

struct dirent * ReadDir(DIR *dir, const char *dirname)

#define PG_GETARG_TEXT_PP(n)

#define DirectFunctionCall2(func, arg1, arg2)

#define PG_RETURN_INT64(x)

#define DirectFunctionCall1(func, arg1)

#define PG_GETARG_INT64(n)

#define PG_GETARG_NAME(n)

#define PG_RETURN_TEXT_P(x)

#define DirectFunctionCall3(func, arg1, arg2, arg3)

Assert(PointerIsAligned(start, uint64))

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

void list_free(List *list)

#define CHECK_FOR_INTERRUPTS()

bool isTempOrTempToastNamespace(Oid namespaceId)

ProcNumber GetTempNamespaceProcNumber(Oid namespaceId)

static Numeric DatumGetNumeric(Datum X)

#define PG_GETARG_NUMERIC(n)

static Datum NumericGetDatum(Numeric X)

FormData_pg_class * Form_pg_class

static const char * dbName

int pg_strcasecmp(const char *s1, const char *s2)

static bool DatumGetBool(Datum X)

static int64 DatumGetInt64(Datum X)

static Datum ObjectIdGetDatum(Oid X)

static char * DatumGetCString(Datum X)

static Datum CStringGetDatum(const char *X)

static Datum Int32GetDatum(int32 X)

#define INVALID_PROC_NUMBER

#define ProcNumberForTempRelations()

char * psprintf(const char *fmt,...)

List * RelationGetIndexList(Relation relation)

Oid RelidByRelfilenumber(Oid reltablespace, RelFileNumber relfilenumber)

RelFileNumber RelationMapOidToFilenumber(Oid relationId, bool shared)

ForkNumber forkname_to_number(const char *forkName)

#define InvalidRelFileNumber

#define relpathbackend(rlocator, backend, forknum)

#define TABLESPACE_VERSION_DIRECTORY

#define RelFileNumberIsValid(relnumber)

void relation_close(Relation relation, LOCKMODE lockmode)

Relation try_relation_open(Oid relationId, LOCKMODE lockmode)

Relation relation_open(Oid relationId, LOCKMODE lockmode)

char str[REL_PATH_STR_MAXLEN+1]

RelFileLocator rd_locator

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

#define SearchSysCacheExists1(cacheId, key1)

#define VARSIZE_ANY_EXHDR(PTR)

text * cstring_to_text(const char *s)

char * text_to_cstring(const text *t)