1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add pgstattuple

This commit is contained in:
Tatsuo Ishii
2001-10-01 01:52:38 +00:00
parent 95d4821b1c
commit 9a23885f72
7 changed files with 280 additions and 1 deletions

View File

@ -0,0 +1,22 @@
#-------------------------------------------------------------------------
#
# pgstattuple Makefile
#
# $Id: Makefile,v 1.1 2001/10/01 01:52:38 ishii Exp $
#
#-------------------------------------------------------------------------
subdir = contrib/pgstattuple
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULE_big := pgstattuple
SRCS += pgstattuple.c
OBJS := $(SRCS:.c=.o)
DOCS := README.pgstattuple README.pgstattuple.euc_jp
DATA_built := pgstattuple.sql
PG_CPPFLAGS :=
SHLIB_LINK :=
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -0,0 +1,47 @@
pgstattuple README 2001/10/01 Tatsuo Ishii
1. What is pgstattuple?
pgstattuple returns the percentage of the "dead" tuples of a
table. This will help users to judge if vacuum is needed.
In addition, pgstattuple prints more detailed information using
NOTICE.
test=# select pgstattuple('tellers');
NOTICE: physical length: 0.08MB live tuples: 20 (0.00MB, 1.17%) dead tuples: 320 (0.01MB, 18.75%) free/reusable space: 0.01MB (18.06%) overhead: 62.02%
pgstattuple
-------------
18.75
(1 row)
Above example shows tellers tables includes 18.75% dead tuples.
physical length physical size of the table in MB
live tuples information on the live tuples
dead tuples information on the dead tuples
free/reusable space available space
overhead overhead space
2. Installing pgstattuple
$ make
$ make install
$ psql -e -f /usr/local/pgsql/share/contrib/pgstattuple.sql test
3. Using pgstattuple
pgstattuple can be called as a function:
pgstattuple(NAME) RETURNS FLOAT8
The argument is the table name. pgstattuple returns the percentage
of the "dead" tuples of a table.
4. Notes
pgstattuple does not lock the target table at all. So concurrent
update may affect the result.
pgstattuple judges a tuple is "dead" if HeapTupleSatisfiesNow()
returns false.

View File

@ -0,0 +1,70 @@
$Id: README.pgstattuple.euc_jp,v 1.1 2001/10/01 01:52:38 ishii Exp $
pgstattuple README 2001/10/01 <20>а<EFBFBD>ã<EFBFBD><C3A3>
1. pgstattuple<6C>Ȥ<EFBFBD>
pgstattuple<6C>ϡ<EFBFBD>UPDATE<54><45>DELETE<54>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD>줿<EFBFBD>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5>Υ<EFBFBD><CEA5><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD><EFBFBD><E7A4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20>ơ<EFBFBD><C6A1>֥뼫<D6A5>Τ<EFBFBD>ʪ<EFBFBD><CAAA>Ū<EFBFBD><C5AA><EFBFBD><EFBFBD><E7A4AD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><D0A4><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD><C6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵѤ<D6B5><D1A4>ޤ<EFBFBD><DEA4><EFBFBD><EFBFBD><EFBFBD>
<20>ޤꡤ<DEA4>ֵ<EFBFBD><D6B5>ͤ<EFBFBD><CDA4><EFBFBD><E7A4AD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߤ<EFBFBD>¿<EFBFBD><C2BF><EFBFBD>Τǡ<CEA4>vacuum<75>򤫤<EFBFBD><F2A4ABA4><EFBFBD>ɬ
<20>פ<EFBFBD><D7A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥ<EFBFBD><C8A4><EFBFBD>Ƚ<EFBFBD>Ǥν<C7A4><CEBD><EFBFBD><EFBFBD>ˤʤ<CBA4><CAA4><EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǤϾ<C7A4><CFBE><EFBFBD><EFBFBD>̤<EFBFBD><CCA4><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4>Τǡ<CEA4>NOTICE<43><45><EFBFBD>å<EFBFBD><C3A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20><><EFBFBD>Ǥ˽<C7A4><CBBD>Ϥ<EFBFBD><CFA4>ޤ<EFBFBD><DEA4><EFBFBD>
test=# select pgstattuple('tellers');
NOTICE: physical length: 0.08MB live tuples: 20 (0.00MB, 1.17%) dead tuples: 320 (0.01MB, 18.75%) free/reusable space: 0.01MB (18.06%) overhead: 62.02%
pgstattuple
-------------
18.75
(1 row)
<20><><EFBFBD>μ¹<CEBC><C2B9><EFBFBD><EFBFBD>Ǥϡ<C7A4>19%<25>ۤɤ<DBA4><C9A4><EFBFBD><EFBFBD>ߤˤʤäƤ<C3A4><C6A4><EFBFBD>Ȥ<EFBFBD><C8A4>Ǥ<EFBFBD><C7A4>ޤ<EFBFBD><DEA4><EFBFBD>NOTICE<43><45><EFBFBD><EFBFBD>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>θ<EFBFBD><CEB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񤤤Ƥ<F1A4A4A4><C6A4><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
physical length <09>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5><EFBFBD>ʪ<EFBFBD><CAAA>Ū<EFBFBD>ʥ<EFBFBD><CAA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MBñ<42>̤<EFBFBD>ɽ<EFBFBD><C9BD>
live tuples <09><><EFBFBD>ߤǤϤʤ<CFA4><CAA4><EFBFBD><EFBFBD>ץ<EFBFBD><D7A5>˴ؤ<CBB4><D8A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󡥥<EFBFBD><F3A1A5A5>ץ<EFBFBD><D7A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<09><><EFBFBD>ץ뤬<D7A5><EBA4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0>ι<EFBFBD><CEB9>ס<EFBFBD><D7A1>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5><EFBFBD><EFBFBD>Τ<EFBFBD><CEA4>Ф<EFBFBD><D0A4><EFBFBD>
<09><>Ψ<EFBFBD><CEA8>ɽ<EFBFBD><C9BD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
dead tuples <09><><EFBFBD>ߤˤʤä<CAA4><C3A4><EFBFBD><EFBFBD>ץ<EFBFBD><D7A5>˴ؤ<CBB4><D8A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
free/reusable space <09><><EFBFBD>Ѳ<EFBFBD>ǽ<EFBFBD><C7BD>̤<EFBFBD><CCA4><EFBFBD><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD>ǽ<EFBFBD>ΰ<EFBFBD>
overhead <09><><EFBFBD><EFBFBD><EFBFBD>Τ<EFBFBD><CEA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ΰ褬<CEB0>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5><EFBFBD><EFBFBD>Τ<EFBFBD><CEA4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ψ
2. pgstattuple<6C>Υ<EFBFBD><CEA5>󥹥ȡ<F3A5B9A5><C8A1><EFBFBD>
PostgreSQL<51><4C>/usr/local/pgsql<71>˥<EFBFBD><CBA5>󥹥ȡ<F3A5B9A5><C8A1><EFBFBD><EFBFBD>ѤǤ<D1A4><C7A4>ꡤtest<73>ǡ<EFBFBD><C7A1><EFBFBD><EFBFBD>١<EFBFBD>
<20><><EFBFBD><EFBFBD>pgstattuple<6C>򥤥󥹥ȡ<F3A5B9A5><C8A1><EFBFBD><EBA4B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD>򼨤<EFBFBD><F2BCA8A4>ޤ<EFBFBD><DEA4><EFBFBD>
$ make
$ make install
<20><EFBFBD><E6A1BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD><CFBF><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
$ psql -e -f /usr/local/pgsql/share/contrib/pgstattuple.sql test
3. pgstattuple<6C>λȤ<CEBB><C8A4><EFBFBD>
pgstattuple<6C>θƤӽФ<D3BD><D0A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰʲ<CFB0><CAB2>Ǥ<EFBFBD><C7A4><EFBFBD>
pgstattuple(NAME) RETURNS FLOAT8
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20>ơ<EFBFBD><C6A1>֥<EFBFBD>̾
<20>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UPDATE<54><45>DELETE<54>Ǻ<EFBFBD><C7BA><EFBFBD><EFBFBD>줿<EFBFBD>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5>Υ<EFBFBD><CEA5><EFBFBD><EFBFBD>ΰ<EFBFBD><CEB0><EFBFBD><EFBFBD><EFBFBD><E7A4AD><EFBFBD>ǡ<EFBFBD>
<20>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5><EFBFBD>ʪ<EFBFBD><CAAA>Ū<EFBFBD><C5AA><EFBFBD><EFBFBD><E7A4AD><EFBFBD><EFBFBD><EFBFBD>Ф<EFBFBD><D0A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD>ֵѤ<D6B5><D1A4>ޤ<EFBFBD><DEA4><EFBFBD>
<20>ʤ<EFBFBD><CAA4><EFBFBD>pgstattuple<6C>ϥơ<CFA5><C6A1>֥<EFBFBD><D6A5>˰<EFBFBD><CBB0>ڥ<EFBFBD><DAA5>å<EFBFBD><C3A5>򤫤<EFBFBD><F2A4ABA4>ʤ<EFBFBD><CAA4>Τǡ<CEA4>pgstattuple
<20><><EFBFBD>¹<EFBFBD><C2B9><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD>ơ<EFBFBD><C6A1>֥<EFBFBD><D6A5>˹<EFBFBD><CBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȯ<EFBFBD><C8AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>̤<EFBFBD><CCA4><EFBFBD>
<20><><EFBFBD><EFBFBD>ǽ<EFBFBD><C7BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>
4. pgstattuple<6C>Υ<CEA5><E9A5A4><EFBFBD>󥹾<EFBFBD><F3A5B9BE><EFBFBD><EFBFBD>ˤĤ<CBA4><C4A4><EFBFBD>
pgstattuple.c<><63><EFBFBD><EFBFBD>Ƭ<EFBFBD>˽񤤤Ƥ<F1A4A4A4><C6A4><EFBFBD><EFBFBD>̤<EFBFBD><CCA4>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD>pgstattuple <20>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><CCB5>
<20>ڤǤ<DAA4><C7A4><EFBFBD>pgstattuple <20><><EFBFBD><EFBFBD><EFBFBD>Ѥ<EFBFBD><D1A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȥˤ<C8A4><CBA4>ä<EFBFBD><C3A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA4A4><EFBFBD>ʤ<EFBFBD><CAA4><EFBFBD><EFBFBD>̤˴ؤ<CBB4><D8A4><EFBFBD>
<20><><EFBFBD><EFBFBD>Ǥ<EFBFBD><C7A4><EFBFBD><EFBFBD>ޤ<EFBFBD><DEA4><EFBFBD><EFBFBD><EFBFBD>
5. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2001/10/01 PostgreSQL 7.2 <20><>contrib module<6C><65><EFBFBD><EFBFBD>Ͽ
2001/08/30 pgstattuple <20>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

View File

@ -0,0 +1,131 @@
/*
* $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.1 2001/10/01 01:52:38 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 this paragraph and the following two
* paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF 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);
}

View File

@ -0,0 +1,4 @@
DROP FUNCTION pgstattuple(NAME);
CREATE FUNCTION pgstattuple(NAME) RETURNS FLOAT8
AS 'MODULE_PATHNAME', 'pgstattuple'
LANGUAGE 'c' WITH (isstrict);