tuple statistics function - Mailing list pgsql-hackers
From | Tatsuo Ishii |
---|---|
Subject | tuple statistics function |
Date | |
Msg-id | 20010926133938J.t-ishii@sra.co.jp Whole thread Raw |
Responses |
Re: tuple statistics function
|
List | 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 by date: