From 9a23885f7243cddff2cba06a4d245ab54b1ff81e Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii <ishii@postgresql.org> Date: Mon, 1 Oct 2001 01:52:38 +0000 Subject: [PATCH] Add pgstattuple --- contrib/Makefile | 3 +- contrib/README | 4 + contrib/pgstattuple/Makefile | 22 +++ contrib/pgstattuple/README.pgstattuple | 47 +++++++ contrib/pgstattuple/README.pgstattuple.euc_jp | 70 ++++++++++ contrib/pgstattuple/pgstattuple.c | 131 ++++++++++++++++++ contrib/pgstattuple/pgstattuple.sql.in | 4 + 7 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 contrib/pgstattuple/Makefile create mode 100644 contrib/pgstattuple/README.pgstattuple create mode 100644 contrib/pgstattuple/README.pgstattuple.euc_jp create mode 100644 contrib/pgstattuple/pgstattuple.c create mode 100644 contrib/pgstattuple/pgstattuple.sql.in diff --git a/contrib/Makefile b/contrib/Makefile index b83762fec65..1de0581e728 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -1,4 +1,4 @@ -# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.28 2001/09/29 03:11:58 momjian Exp $ +# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.29 2001/10/01 01:52:38 ishii Exp $ subdir = contrib top_builddir = .. @@ -27,6 +27,7 @@ WANTED_DIRS = \ pg_resetxlog \ pgbench \ pgcrypto \ + pgstattuple \ rserv \ rtree_gist \ seg \ diff --git a/contrib/README b/contrib/README index 54792b736e0..d58fbf8669e 100644 --- a/contrib/README +++ b/contrib/README @@ -137,6 +137,10 @@ pgcrypto - Cryptographic functions by Marko Kreen <marko@l-t.ee> +pgstattuple - + A function returns the percentage of "dead" tuples in a table + by Tatsuo Ishii <t-ishii@sra.co.jp> + retep - tools to build retep tools packages by Peter T Mount <peter@retep.org.uk> diff --git a/contrib/pgstattuple/Makefile b/contrib/pgstattuple/Makefile new file mode 100644 index 00000000000..88f1b658d41 --- /dev/null +++ b/contrib/pgstattuple/Makefile @@ -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 diff --git a/contrib/pgstattuple/README.pgstattuple b/contrib/pgstattuple/README.pgstattuple new file mode 100644 index 00000000000..c54f97e82f5 --- /dev/null +++ b/contrib/pgstattuple/README.pgstattuple @@ -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. diff --git a/contrib/pgstattuple/README.pgstattuple.euc_jp b/contrib/pgstattuple/README.pgstattuple.euc_jp new file mode 100644 index 00000000000..d23b995dd47 --- /dev/null +++ b/contrib/pgstattuple/README.pgstattuple.euc_jp @@ -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 �а�ã�� + +1. pgstattuple�Ȥ� + + pgstattuple�ϡ�UPDATE��DELETE�Ǻ��줿�ơ��֥�Υ����ΰ���礭���� + �ơ��֥뼫�Τ�ʪ��Ū���礭�����Ф���ѡ�����ơ������ֵѤ��ޤ����� + �ޤꡤ�ֵ��ͤ��礭����С�����������ߤ�¿���Τǡ�vacuum����ɬ + �פ�����Ȥ���Ƚ�Ǥν����ˤʤ�櫓�Ǥ��� + + ��������ǤϾ����̤����ʤ��Τǡ�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) + + ���μ¹���Ǥϡ�19%�ۤɤ����ߤˤʤäƤ��뤳�Ȥ��Ǥ��ޤ���NOTICE��� + �������θ�����Ƥ����ޤ��� + + physical length �ơ��֥��ʪ��Ū�ʥ�������MBñ�̤�ɽ�� + live tuples ���ߤǤϤʤ����ץ�˴ؤ�������ץ������ + ���ץ뤬�����ΰ�ι�ס��ơ��֥����Τ��Ф��� + ��Ψ��ɽ�����ޤ��� + dead tuples ���ߤˤʤä����ץ�˴ؤ������ + free/reusable space ���Ѳ�ǽ��̤�����ΰ������Ѳ�ǽ�ΰ� + overhead �����Τ�����ΰ褬�ơ��֥����Τ�������Ψ + +2. pgstattuple�Υ��ȡ��� + + PostgreSQL��/usr/local/pgsql�˥��ȡ���ѤǤ��ꡤtest�ǡ����١� + ����pgstattuple�ȡ��뤹����μ����ޤ��� + + $ make + $ make install + + �桼������ؿ�����Ͽ���ޤ��� + + $ psql -e -f /usr/local/pgsql/share/contrib/pgstattuple.sql test + + +3. pgstattuple�λȤ��� + + pgstattuple�θƤӽФ������ϰʲ��Ǥ��� + + pgstattuple(NAME) RETURNS FLOAT8 + + ������: �ơ��֥�̾ + + �ؿ�������UPDATE��DELETE�Ǻ��줿�ơ��֥�Υ����ΰ���礭���ǡ� + �ơ��֥��ʪ��Ū���礭�����Ф�����(�ѡ������)���ֵѤ��ޤ��� + + �ʤ���pgstattuple�ϥơ��֥�˰��ڥ��å����ʤ��Τǡ�pgstattuple + ��¹���˳����ơ��֥�˹���������ȯ������ȡ��������ʤ���̤��� + ����ǽ��������ޤ��� + +4. pgstattuple�Υ饤�����ˤĤ��� + + pgstattuple.c����Ƭ�˽Ƥ����̤�Ǥ����ޤ���pgstattuple �ϴ�����̵�� + �ڤǤ���pgstattuple ����Ѥ������Ȥˤ�ä������뤤���ʤ��̤˴ؤ��� + ����Ǥ���餤�ޤ��� + +5. �������� + + 2001/10/01 PostgreSQL 7.2 ��contrib module����Ͽ + 2001/08/30 pgstattuple �С������ 0.1���� diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c new file mode 100644 index 00000000000..e88be905011 --- /dev/null +++ b/contrib/pgstattuple/pgstattuple.c @@ -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); +} diff --git a/contrib/pgstattuple/pgstattuple.sql.in b/contrib/pgstattuple/pgstattuple.sql.in new file mode 100644 index 00000000000..7a7706fa190 --- /dev/null +++ b/contrib/pgstattuple/pgstattuple.sql.in @@ -0,0 +1,4 @@ +DROP FUNCTION pgstattuple(NAME); +CREATE FUNCTION pgstattuple(NAME) RETURNS FLOAT8 +AS 'MODULE_PATHNAME', 'pgstattuple' +LANGUAGE 'c' WITH (isstrict); -- GitLab