tuple statistics function

Поиск
Список
Период
Сортировка
От Tatsuo Ishii
Тема tuple statistics function
Дата
Msg-id 20010926133938J.t-ishii@sra.co.jp
обсуждение исходный текст
Ответы Re: tuple statistics function
Список pgsql-hackers
Here is a revised version of pg_stattuple, which shows how many tuples
are "dead" etc. Per Tom's suggestion, a statistic of free/resuable
space is now printed.

test=# select pgstattuple('accounts');
NOTICE:  physical length: 39.06MB live tuples: 100000 (12.59MB, 32.23%) dead tuples: 200000 (25.18MB, 64.45%)
free/reusablespace: 0.04MB (0.10%) overhead: 3.22%pgstattuple 
 
-------------  64.453125

What I'm not sure is:

o Should I place any kind of lock after reading buffer?

o Should I use similar algorithm to the one used in vacuum to determin whether the tuple is "dead" or not?

Suggestions?
--
Tatsuo Ishii

-------------------------------------------------------------------------
/** $Header: /home/t-ishii/repository/pgstattuple/pgstattuple.c,v 1.2 2001/08/30 06:21:48 t-ishii Exp $** Copyright (c)
2001 Tatsuo Ishii** Permission to use, copy, modify, and distribute this software and* its documentation for any
purpose,without fee, and without a* written agreement is hereby granted, provided that the above* copyright notice and
thisparagraph and the following two* paragraphs appear in all copies.** IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY
PARTYFOR DIRECT,* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING* LOST PROFITS, ARISING OUT OF THE
USEOF THIS SOFTWARE AND ITS* DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED* OF THE POSSIBILITY
OFSUCH DAMAGE.** THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED
WARRANTIESOF MERCHANTABILITY AND FITNESS FOR* A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS* IS"
BASIS,AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.*/
 

#include "postgres.h"
#include "fmgr.h"
#include "access/heapam.h"
#include "access/transam.h"

PG_FUNCTION_INFO_V1(pgstattuple);

extern Datum pgstattuple(PG_FUNCTION_ARGS);

/* ----------* pgstattuple:* returns the percentage of dead tuples** C FUNCTION definition* pgstattuple(NAME) returns
FLOAT8*----------*/
 
Datum
pgstattuple(PG_FUNCTION_ARGS)
{   Name    p = PG_GETARG_NAME(0);
   Relation    rel;   HeapScanDesc    scan;   HeapTuple    tuple;   BlockNumber nblocks;   BlockNumber block =
InvalidBlockNumber;  double    table_len;   uint64    tuple_len = 0;   uint64    dead_tuple_len = 0;   uint32
tuple_count= 0;   uint32    dead_tuple_count = 0;   double    tuple_percent;   double    dead_tuple_percent;
 
   Buffer    buffer = InvalidBuffer;   uint64    free_space = 0;    /* free/reusable space in bytes */   double
free_percent;       /* free/reusable space in % */
 
   rel = heap_openr(NameStr(*p), NoLock);   nblocks = RelationGetNumberOfBlocks(rel);   scan = heap_beginscan(rel,
false,SnapshotAny, 0, NULL);
 
   while ((tuple = heap_getnext(scan,0)))   {if (HeapTupleSatisfiesNow(tuple->t_data)){    tuple_len += tuple->t_len;
tuple_count++;}else{    dead_tuple_len += tuple->t_len;    dead_tuple_count++;}
 
if (!BlockNumberIsValid(block) ||    block != BlockIdGetBlockNumber(&tuple->t_self.ip_blkid)){    block =
BlockIdGetBlockNumber(&tuple->t_self.ip_blkid);   buffer = ReadBuffer(rel, block);    free_space +=
PageGetFreeSpace((Page)BufferGetPage(buffer));   ReleaseBuffer(buffer);}   }   heap_endscan(scan);   heap_close(rel,
NoLock);
   table_len = (double)nblocks*BLCKSZ;
   if (nblocks == 0)   {tuple_percent = 0.0;dead_tuple_percent = 0.0;free_percent = 0.0;   }   else   {tuple_percent =
(double)tuple_len*100.0/table_len;dead_tuple_percent= (double)dead_tuple_len*100.0/table_len;free_percent =
(double)free_space*100.0/table_len;  }
 
   elog(NOTICE,"physical length: %.2fMB live tuples: %u (%.2fMB, %.2f%%) dead tuples: %u (%.2fMB, %.2f%%) free/reusable
space:%.2fMB (%.2f%%) overhead: %.2f%%",
 
 table_len/1024/1024,     /* phsical length in MB */
 tuple_count,    /* number of live tuples */ (double)tuple_len/1024/1024,    /* live tuples in MB */ tuple_percent,
/*live tuples in % */
 
 dead_tuple_count,    /* number of dead tuples */ (double)dead_tuple_len/1024/1024,    /* dead tuples in MB */
dead_tuple_percent,   /* dead tuples in % */
 
 (double)free_space/1024/1024,    /* free/available space in MB */
 free_percent,    /* free/available space in % */
 /* overhead in % */ (nblocks == 0)?0.0: 100.0 - tuple_percent - dead_tuple_percent- free_percent);
   PG_RETURN_FLOAT8(dead_tuple_percent);
}


В списке pgsql-hackers по дате отправления:

Предыдущее
От: "Christopher Kings-Lynne"
Дата:
Сообщение: O_DIRECT
Следующее
От: Tom Lane
Дата:
Сообщение: Re: Proposal: new GUC paramter