55 * Copyright (c) 2002-2005, PostgreSQL Global Development Group
66 *
77 * IDENTIFICATION
8- * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.4 2005/09/16 05:35:40 neilc Exp $
8+ * $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.5 2005/09/29 22:04:36 alvherre Exp $
99 *
1010 */
1111
@@ -216,34 +216,33 @@ pg_tablespace_size_name(PG_FUNCTION_ARGS)
216216 * calculate size of a relation
217217 */
218218static int64
219- calculate_relation_size (Oid tblspcOid , Oid relnodeOid )
219+ calculate_relation_size (RelFileNode * rfn )
220220{
221- int64 totalsize = 0 ;
222- unsigned int segcount = 0 ;
223- char dirpath [MAXPGPATH ];
224- char pathname [ MAXPGPATH ] ;
221+ int64 totalsize = 0 ;
222+ char dirpath [ MAXPGPATH ] ;
223+ char pathname [MAXPGPATH ];
224+ unsigned int segcount = 0 ;
225225
226- if (!tblspcOid )
227- tblspcOid = MyDatabaseTableSpace ;
226+ Assert (OidIsValid (rfn -> spcNode ));
228227
229- if (tblspcOid == DEFAULTTABLESPACE_OID )
230- snprintf (dirpath ,MAXPGPATH ,"%s/base/%u" ,DataDir ,MyDatabaseId );
231- else if (tblspcOid == GLOBALTABLESPACE_OID )
228+ if (rfn -> spcNode == DEFAULTTABLESPACE_OID )
229+ snprintf (dirpath ,MAXPGPATH ,"%s/base/%u" ,DataDir ,rfn -> dbNode );
230+ else if (rfn -> spcNode == GLOBALTABLESPACE_OID )
232231snprintf (dirpath ,MAXPGPATH ,"%s/global" ,DataDir );
233232else
234233snprintf (dirpath ,MAXPGPATH ,"%s/pg_tblspc/%u/%u" ,
235- DataDir ,tblspcOid , MyDatabaseId );
234+ DataDir ,rfn -> spcNode , rfn -> dbNode );
236235
237- for (segcount = 0 ; ;segcount ++ )
236+ for (segcount = 0 ; ;segcount ++ )
238237{
239238struct stat fst ;
240239
241240if (segcount == 0 )
242241snprintf (pathname ,MAXPGPATH ,"%s/%u" ,
243- dirpath ,relnodeOid );
242+ dirpath ,rfn -> relNode );
244243else
245244snprintf (pathname ,MAXPGPATH ,"%s/%u.%u" ,
246- dirpath ,relnodeOid ,segcount );
245+ dirpath ,rfn -> relNode ,segcount );
247246
248247if (stat (pathname ,& fst )< 0 )
249248{
@@ -264,102 +263,82 @@ Datum
264263pg_relation_size_oid (PG_FUNCTION_ARGS )
265264{
266265Oid relOid = PG_GETARG_OID (0 );
267- HeapTuple tuple ;
268- Form_pg_class pg_class ;
269- Oid relnodeOid ;
270- Oid tblspcOid ;
266+ Relation rel ;
267+ int64 size ;
271268
272- tuple = SearchSysCache (RELOID ,
273- ObjectIdGetDatum (relOid ),
274- 0 ,0 ,0 );
275- if (!HeapTupleIsValid (tuple ))
276- elog (ERROR ,"cache lookup failed for relation %u" ,relOid );
269+ rel = relation_open (relOid ,AccessShareLock );
277270
278- pg_class = (Form_pg_class )GETSTRUCT (tuple );
279- relnodeOid = pg_class -> relfilenode ;
280- tblspcOid = pg_class -> reltablespace ;
271+ size = calculate_relation_size (& (rel -> rd_node ));
281272
282- ReleaseSysCache ( tuple );
273+ relation_close ( rel , AccessShareLock );
283274
284- PG_RETURN_INT64 (calculate_relation_size ( tblspcOid , relnodeOid ) );
275+ PG_RETURN_INT64 (size );
285276}
286277
287278Datum
288279pg_relation_size_name (PG_FUNCTION_ARGS )
289280{
290281text * relname = PG_GETARG_TEXT_P (0 );
291282RangeVar * relrv ;
292- Relation relation ;
293- Oid relnodeOid ;
294- Oid tblspcOid ;
283+ Relation rel ;
284+ int64 size ;
295285
296286relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
297- relation = relation_openrv (relrv ,AccessShareLock );
287+ rel = relation_openrv (relrv ,AccessShareLock );
298288
299- tblspcOid = relation -> rd_rel -> reltablespace ;
300- relnodeOid = relation -> rd_rel -> relfilenode ;
289+ size = calculate_relation_size (& (rel -> rd_node ));
301290
302- relation_close (relation ,AccessShareLock );
291+ relation_close (rel ,AccessShareLock );
303292
304- PG_RETURN_INT64 (calculate_relation_size ( tblspcOid , relnodeOid ) );
293+ PG_RETURN_INT64 (size );
305294}
306295
307296
308297/*
309- * Compute the on-disk size of files for' relation' according to the
298+ * Compute the on-disk size of files forthe relation according to the
310299 * stat function, optionally including heap data, index data, and/or
311300 * toast data.
312301 */
313302static int64
314- calculate_total_relation_size (Oid tblspcOid , Oid relnodeOid )
303+ calculate_total_relation_size (Oid Relid )
315304{
316- Relation heapRelation ;
317- Relation idxRelation ;
318- Relation toastRelation ;
319- Oid idxOid ;
320- Oid idxTblspcOid ;
321- Oid toastOid ;
322- Oid toastTblspcOid ;
323- bool hasIndices ;
324- int64 size ;
325- List * indexoidlist ;
326- ListCell * idx ;
327-
328- heapRelation = relation_open (relnodeOid ,AccessShareLock );
329- toastOid = heapRelation -> rd_rel -> reltoastrelid ;
330- hasIndices = heapRelation -> rd_rel -> relhasindex ;
331-
332- /* Get the heap size */
333- size = calculate_relation_size (tblspcOid ,relnodeOid );
334-
335- /* Get index size */
336- if (hasIndices )
305+ Relation heapRel ;
306+ Oid toastOid ;
307+ int64 size ;
308+ ListCell * cell ;
309+
310+ heapRel = relation_open (Relid ,AccessShareLock );
311+ toastOid = heapRel -> rd_rel -> reltoastrelid ;
312+
313+ /* Get the heap size */
314+ size = calculate_relation_size (& (heapRel -> rd_node ));
315+
316+ /* Get index size */
317+ if (heapRel -> rd_rel -> relhasindex )
337318{
338319/* recursively include any dependent indexes */
339- indexoidlist = RelationGetIndexList (heapRelation );
320+ List * index_oids = RelationGetIndexList (heapRel );
340321
341- foreach (idx , indexoidlist )
322+ foreach (cell , index_oids )
342323{
343- idxOid = lfirst_oid (idx );
344- idxRelation = relation_open (idxOid ,AccessShareLock );
345- idxTblspcOid = idxRelation -> rd_rel -> reltablespace ;
346- size += calculate_relation_size (idxTblspcOid ,idxOid );
347- relation_close (idxRelation ,AccessShareLock );
324+ Oid idxOid = lfirst_oid (cell );
325+ Relation iRel ;
326+
327+ iRel = relation_open (idxOid ,AccessShareLock );
328+
329+ size += calculate_relation_size (& (iRel -> rd_node ));
330+
331+ relation_close (iRel ,AccessShareLock );
348332}
349- list_free (indexoidlist );
333+
334+ list_free (index_oids );
350335}
351336
352- relation_close (heapRelation ,AccessShareLock );
337+ /* Get toast table (and index) size */
338+ if (OidIsValid (toastOid ))
339+ size += calculate_total_relation_size (toastOid );
353340
354- /* Get toast table size */
355- if (toastOid != 0 )
356- {
357- /* recursively include any toast relations */
358- toastRelation = relation_open (toastOid ,AccessShareLock );
359- toastTblspcOid = toastRelation -> rd_rel -> reltablespace ;
360- size += calculate_relation_size (toastTblspcOid ,toastOid );
361- relation_close (toastRelation ,AccessShareLock );
362- }
341+ relation_close (heapRel ,AccessShareLock );
363342
364343return size ;
365344}
@@ -371,45 +350,22 @@ calculate_total_relation_size(Oid tblspcOid, Oid relnodeOid)
371350Datum
372351pg_total_relation_size_oid (PG_FUNCTION_ARGS )
373352{
374- Oid relOid = PG_GETARG_OID (0 );
375- HeapTuple tuple ;
376- Form_pg_class pg_class ;
377- Oid relnodeOid ;
378- Oid tblspcOid ;
379-
380- tuple = SearchSysCache (RELOID ,
381- ObjectIdGetDatum (relOid ),
382- 0 ,0 ,0 );
383- if (!HeapTupleIsValid (tuple ))
384- elog (ERROR ,"cache lookup failed for relation %u" ,relOid );
385-
386- pg_class = (Form_pg_class )GETSTRUCT (tuple );
387- relnodeOid = pg_class -> relfilenode ;
388- tblspcOid = pg_class -> reltablespace ;
389-
390- ReleaseSysCache (tuple );
353+ Oid relid = PG_GETARG_OID (0 );
391354
392- PG_RETURN_INT64 (calculate_total_relation_size (tblspcOid , relnodeOid ));
355+ PG_RETURN_INT64 (calculate_total_relation_size (relid ));
393356}
394357
395358Datum
396359pg_total_relation_size_name (PG_FUNCTION_ARGS )
397360{
398- text * relname = PG_GETARG_TEXT_P (0 );
399- RangeVar * relrv ;
400- Relation relation ;
401- Oid relnodeOid ;
402- Oid tblspcOid ;
361+ text * relname = PG_GETARG_TEXT_P (0 );
362+ RangeVar * relrv ;
363+ Oid relid ;
403364
404365relrv = makeRangeVarFromNameList (textToQualifiedNameList (relname ));
405- relation = relation_openrv (relrv ,AccessShareLock );
366+ relid = RangeVarGetRelid (relrv ,false );
406367
407- tblspcOid = relation -> rd_rel -> reltablespace ;
408- relnodeOid = relation -> rd_rel -> relfilenode ;
409-
410- relation_close (relation ,AccessShareLock );
411-
412- PG_RETURN_INT64 (calculate_total_relation_size (tblspcOid ,relnodeOid ));
368+ PG_RETURN_INT64 (calculate_total_relation_size (relid ));
413369}
414370
415371/*
@@ -418,37 +374,36 @@ pg_total_relation_size_name(PG_FUNCTION_ARGS)
418374Datum
419375pg_size_pretty (PG_FUNCTION_ARGS )
420376{
421- int64 size = PG_GETARG_INT64 (0 );
422- char * result = palloc (50 + VARHDRSZ );
423- int64 limit = 10 * 1024 ;
424- int64 mult = 1 ;
425-
426- if (size < limit * mult )
427- snprintf (VARDATA (result ),50 ,INT64_FORMAT " bytes" ,
428- size );
377+ int64 size = PG_GETARG_INT64 (0 );
378+ char * result = palloc (50 + VARHDRSZ );
379+ int64 limit = 10 * 1024 ;
380+ int64 mult = 1 ;
381+
382+ if (size < limit * mult )
383+ snprintf (VARDATA (result ),50 ,INT64_FORMAT " bytes" ,size );
429384else
430385{
431386mult *=1024 ;
432- if (size < limit * mult )
387+ if (size < limit * mult )
433388snprintf (VARDATA (result ),50 ,INT64_FORMAT " kB" ,
434- (size + mult / 2 ) /mult );
389+ (size + mult / 2 ) /mult );
435390else
436391{
437392mult *=1024 ;
438- if (size < limit * mult )
393+ if (size < limit * mult )
439394snprintf (VARDATA (result ),50 ,INT64_FORMAT " MB" ,
440- (size + mult / 2 ) /mult );
395+ (size + mult / 2 ) /mult );
441396else
442397{
443398mult *=1024 ;
444- if (size < limit * mult )
399+ if (size < limit * mult )
445400snprintf (VARDATA (result ),50 ,INT64_FORMAT " GB" ,
446- (size + mult / 2 ) /mult );
401+ (size + mult / 2 ) /mult );
447402else
448403{
449404mult *=1024 ;
450405snprintf (VARDATA (result ),50 ,INT64_FORMAT " TB" ,
451- (size + mult / 2 ) /mult );
406+ (size + mult / 2 ) /mult );
452407}
453408}
454409}