Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfa352d6

Browse files
committed
Make pg_relation_size() and friends return NULL if the object doesn't exist.
That avoids errors when the functions are used in queries like "SELECTpg_relation_size(oid) FROM pg_class", and a table is dropped concurrently.Phil Sorber
1 parent6f6b46c commitfa352d6

File tree

2 files changed

+89
-35
lines changed

2 files changed

+89
-35
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14979,6 +14979,11 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
1497914979
the table name.
1498014980
</para>
1498114981

14982+
<para>
14983+
If an OID that does not represent an existing object is passed as
14984+
argument to one of the above functions, NULL is returned.
14985+
</para>
14986+
1498214987
<para>
1498314988
The functions shown in <xref linkend="functions-admin-dblocation"> assist
1498414989
in identifying the specific disk files associated with database objects.

‎src/backend/utils/adt/dbsize.c

Lines changed: 84 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -120,35 +120,42 @@ calculate_database_size(Oid dbOid)
120120

121121
FreeDir(dirdesc);
122122

123-
/* Complain if we found no trace of the DB at all */
124-
if (!totalsize)
125-
ereport(ERROR,
126-
(ERRCODE_UNDEFINED_DATABASE,
127-
errmsg("database with OID %u does not exist",dbOid)));
128-
129123
returntotalsize;
130124
}
131125

132126
Datum
133127
pg_database_size_oid(PG_FUNCTION_ARGS)
134128
{
135129
OiddbOid=PG_GETARG_OID(0);
130+
int64size;
136131

137-
PG_RETURN_INT64(calculate_database_size(dbOid));
132+
size=calculate_database_size(dbOid);
133+
134+
if (size==0)
135+
PG_RETURN_NULL();
136+
137+
PG_RETURN_INT64(size);
138138
}
139139

140140
Datum
141141
pg_database_size_name(PG_FUNCTION_ARGS)
142142
{
143143
NamedbName=PG_GETARG_NAME(0);
144144
OiddbOid=get_database_oid(NameStr(*dbName), false);
145+
int64size;
146+
147+
size=calculate_database_size(dbOid);
145148

146-
PG_RETURN_INT64(calculate_database_size(dbOid));
149+
if (size==0)
150+
PG_RETURN_NULL();
151+
152+
PG_RETURN_INT64(size);
147153
}
148154

149155

150156
/*
151-
* calculate total size of tablespace
157+
* Calculate total size of tablespace. Returns -1 if the tablespace directory
158+
* cannot be found.
152159
*/
153160
staticint64
154161
calculate_tablespace_size(OidtblspcOid)
@@ -184,10 +191,7 @@ calculate_tablespace_size(Oid tblspcOid)
184191
dirdesc=AllocateDir(tblspcPath);
185192

186193
if (!dirdesc)
187-
ereport(ERROR,
188-
(errcode_for_file_access(),
189-
errmsg("could not open tablespace directory \"%s\": %m",
190-
tblspcPath)));
194+
return-1;
191195

192196
while ((direntry=ReadDir(dirdesc,tblspcPath))!=NULL)
193197
{
@@ -226,17 +230,29 @@ Datum
226230
pg_tablespace_size_oid(PG_FUNCTION_ARGS)
227231
{
228232
OidtblspcOid=PG_GETARG_OID(0);
233+
int64size;
234+
235+
size=calculate_tablespace_size(tblspcOid);
229236

230-
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
237+
if (size<0)
238+
PG_RETURN_NULL();
239+
240+
PG_RETURN_INT64(size);
231241
}
232242

233243
Datum
234244
pg_tablespace_size_name(PG_FUNCTION_ARGS)
235245
{
236246
NametblspcName=PG_GETARG_NAME(0);
237247
OidtblspcOid=get_tablespace_oid(NameStr(*tblspcName), false);
248+
int64size;
238249

239-
PG_RETURN_INT64(calculate_tablespace_size(tblspcOid));
250+
size=calculate_tablespace_size(tblspcOid);
251+
252+
if (size<0)
253+
PG_RETURN_NULL();
254+
255+
PG_RETURN_INT64(size);
240256
}
241257

242258

@@ -289,7 +305,17 @@ pg_relation_size(PG_FUNCTION_ARGS)
289305
Relationrel;
290306
int64size;
291307

292-
rel=relation_open(relOid,AccessShareLock);
308+
rel=try_relation_open(relOid,AccessShareLock);
309+
310+
/*
311+
* Before 9.2, we used to throw an error if the relation didn't exist, but
312+
* that makes queries like "SELECT pg_relation_size(oid) FROM pg_class"
313+
* less robust, because while we scan pg_class with an MVCC snapshot,
314+
* someone else might drop the table. It's better to return NULL for
315+
* alread-dropped tables than throw an error and abort the whole query.
316+
*/
317+
if (rel==NULL)
318+
PG_RETURN_NULL();
293319

294320
size=calculate_relation_size(&(rel->rd_node),rel->rd_backend,
295321
forkname_to_number(text_to_cstring(forkName)));
@@ -339,14 +365,11 @@ calculate_toast_table_size(Oid toastrelid)
339365
* those won't have attached toast tables, but they can have multiple forks.
340366
*/
341367
staticint64
342-
calculate_table_size(OidrelOid)
368+
calculate_table_size(Relationrel)
343369
{
344370
int64size=0;
345-
Relationrel;
346371
ForkNumberforkNum;
347372

348-
rel=relation_open(relOid,AccessShareLock);
349-
350373
/*
351374
* heap size, including FSM and VM
352375
*/
@@ -360,8 +383,6 @@ calculate_table_size(Oid relOid)
360383
if (OidIsValid(rel->rd_rel->reltoastrelid))
361384
size+=calculate_toast_table_size(rel->rd_rel->reltoastrelid);
362385

363-
relation_close(rel,AccessShareLock);
364-
365386
returnsize;
366387
}
367388

@@ -371,12 +392,9 @@ calculate_table_size(Oid relOid)
371392
* Can be applied safely to an index, but you'll just get zero.
372393
*/
373394
staticint64
374-
calculate_indexes_size(OidrelOid)
395+
calculate_indexes_size(Relationrel)
375396
{
376397
int64size=0;
377-
Relationrel;
378-
379-
rel=relation_open(relOid,AccessShareLock);
380398

381399
/*
382400
* Aggregate all indexes on the given relation
@@ -405,56 +423,87 @@ calculate_indexes_size(Oid relOid)
405423
list_free(index_oids);
406424
}
407425

408-
relation_close(rel,AccessShareLock);
409-
410426
returnsize;
411427
}
412428

413429
Datum
414430
pg_table_size(PG_FUNCTION_ARGS)
415431
{
416432
OidrelOid=PG_GETARG_OID(0);
433+
Relationrel;
434+
int64size;
435+
436+
rel=try_relation_open(relOid,AccessShareLock);
437+
438+
if (rel==NULL)
439+
PG_RETURN_NULL();
417440

418-
PG_RETURN_INT64(calculate_table_size(relOid));
441+
size=calculate_table_size(rel);
442+
443+
relation_close(rel,AccessShareLock);
444+
445+
PG_RETURN_INT64(size);
419446
}
420447

421448
Datum
422449
pg_indexes_size(PG_FUNCTION_ARGS)
423450
{
424451
OidrelOid=PG_GETARG_OID(0);
452+
Relationrel;
453+
int64size;
425454

426-
PG_RETURN_INT64(calculate_indexes_size(relOid));
455+
rel=try_relation_open(relOid,AccessShareLock);
456+
457+
if (rel==NULL)
458+
PG_RETURN_NULL();
459+
460+
size=calculate_indexes_size(rel);
461+
462+
relation_close(rel,AccessShareLock);
463+
464+
PG_RETURN_INT64(size);
427465
}
428466

429467
/*
430468
*Compute the on-disk size of all files for the relation,
431469
*including heap data, index data, toast data, FSM, VM.
432470
*/
433471
staticint64
434-
calculate_total_relation_size(OidRelid)
472+
calculate_total_relation_size(Relationrel)
435473
{
436474
int64size;
437475

438476
/*
439477
* Aggregate the table size, this includes size of the heap, toast and
440478
* toast index with free space and visibility map
441479
*/
442-
size=calculate_table_size(Relid);
480+
size=calculate_table_size(rel);
443481

444482
/*
445483
* Add size of all attached indexes as well
446484
*/
447-
size+=calculate_indexes_size(Relid);
485+
size+=calculate_indexes_size(rel);
448486

449487
returnsize;
450488
}
451489

452490
Datum
453491
pg_total_relation_size(PG_FUNCTION_ARGS)
454492
{
455-
Oidrelid=PG_GETARG_OID(0);
493+
OidrelOid=PG_GETARG_OID(0);
494+
Relationrel;
495+
int64size;
496+
497+
rel=try_relation_open(relOid,AccessShareLock);
498+
499+
if (rel==NULL)
500+
PG_RETURN_NULL();
456501

457-
PG_RETURN_INT64(calculate_total_relation_size(relid));
502+
size=calculate_total_relation_size(rel);
503+
504+
relation_close(rel,AccessShareLock);
505+
506+
PG_RETURN_INT64(size);
458507
}
459508

460509
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp