summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas2017-04-12 15:53:00 +0000
committerRobert Haas2017-04-12 15:53:00 +0000
commit9cc27566c1a8d659c15b9eea2413dcc07a7a42c9 (patch)
treea3967f317e65a203c52b6e817b0c2c938e3ee71f
parent1d5fede4a900d135745c1fa5a70dcfe0b3359e3d (diff)
Fix pgstattuple's handling of unused hash pages.
Hash indexes can contain both pages which are all-zeroes (i.e. PageIsNew()) and pages which have been initialized but currently aren't used. The latter category can happen either when a page has been reserved but not yet used or when it is used for a time and then freed. pgstattuple was only prepared to deal with the pages that are actually-zeroes, which it called zero_pages. Rename the column to unused_pages (extension version 1.5 is as-yet-unreleased) and make it count both kinds of unused pages. Along the way, slightly tidy up the way we test for pages of various types. Robert Haas and Ashutosh Sharma, reviewed by Amit Kapila Discussion: http://postgr.es/m/CAE9k0PkTtKFB3YndOyQMjwuHx+-FtUP1ynK8E-nHtetoow3NtQ@mail.gmail.com
-rw-r--r--contrib/pgstattuple/expected/pgstattuple.out6
-rw-r--r--contrib/pgstattuple/pgstatindex.c24
-rw-r--r--contrib/pgstattuple/pgstattuple--1.4--1.5.sql2
-rw-r--r--doc/src/sgml/pgstattuple.sgml6
4 files changed, 22 insertions, 16 deletions
diff --git a/contrib/pgstattuple/expected/pgstattuple.out b/contrib/pgstattuple/expected/pgstattuple.out
index 86a7c78fbb5..c7c17328276 100644
--- a/contrib/pgstattuple/expected/pgstattuple.out
+++ b/contrib/pgstattuple/expected/pgstattuple.out
@@ -132,9 +132,9 @@ select * from pgstatginindex('test_ginidx');
create index test_hashidx on test using hash (b);
select * from pgstathashindex('test_hashidx');
- version | bucket_pages | overflow_pages | bitmap_pages | zero_pages | live_items | dead_items | free_percent
----------+--------------+----------------+--------------+------------+------------+------------+--------------
- 3 | 4 | 0 | 1 | 0 | 0 | 0 | 100
+ version | bucket_pages | overflow_pages | bitmap_pages | unused_pages | live_items | dead_items | free_percent
+---------+--------------+----------------+--------------+--------------+------------+------------+--------------
+ 3 | 4 | 0 | 1 | 0 | 0 | 0 | 100
(1 row)
-- these should error with the wrong type
diff --git a/contrib/pgstattuple/pgstatindex.c b/contrib/pgstattuple/pgstatindex.c
index d448e9ede65..15aedec1bfd 100644
--- a/contrib/pgstattuple/pgstatindex.c
+++ b/contrib/pgstattuple/pgstatindex.c
@@ -119,7 +119,7 @@ typedef struct HashIndexStat
BlockNumber bucket_pages;
BlockNumber overflow_pages;
BlockNumber bitmap_pages;
- BlockNumber zero_pages;
+ BlockNumber unused_pages;
int64 live_items;
int64 dead_items;
@@ -634,7 +634,6 @@ pgstathashindex(PG_FUNCTION_ARGS)
{
Buffer buf;
Page page;
- HashPageOpaque opaque;
CHECK_FOR_INTERRUPTS();
@@ -644,7 +643,7 @@ pgstathashindex(PG_FUNCTION_ARGS)
page = (Page) BufferGetPage(buf);
if (PageIsNew(page))
- stats.zero_pages++;
+ stats.unused_pages++;
else if (PageGetSpecialSize(page) !=
MAXALIGN(sizeof(HashPageOpaqueData)))
ereport(ERROR,
@@ -654,19 +653,26 @@ pgstathashindex(PG_FUNCTION_ARGS)
BufferGetBlockNumber(buf))));
else
{
+ HashPageOpaque opaque;
+ int pagetype;
+
opaque = (HashPageOpaque) PageGetSpecialPointer(page);
- if (opaque->hasho_flag & LH_BUCKET_PAGE)
+ pagetype = opaque->hasho_flag & LH_PAGE_TYPE;
+
+ if (pagetype == LH_BUCKET_PAGE)
{
stats.bucket_pages++;
GetHashPageStats(page, &stats);
}
- else if (opaque->hasho_flag & LH_OVERFLOW_PAGE)
+ else if (pagetype == LH_OVERFLOW_PAGE)
{
stats.overflow_pages++;
GetHashPageStats(page, &stats);
}
- else if (opaque->hasho_flag & LH_BITMAP_PAGE)
+ else if (pagetype == LH_BITMAP_PAGE)
stats.bitmap_pages++;
+ else if (pagetype == LH_UNUSED_PAGE)
+ stats.unused_pages++;
else
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
@@ -680,8 +686,8 @@ pgstathashindex(PG_FUNCTION_ARGS)
/* Done accessing the index */
index_close(rel, AccessShareLock);
- /* Count zero pages as free space. */
- stats.free_space += stats.zero_pages * stats.space_per_page;
+ /* Count unused pages as free space. */
+ stats.free_space += stats.unused_pages * stats.space_per_page;
/*
* Total space available for tuples excludes the metapage and the bitmap
@@ -710,7 +716,7 @@ pgstathashindex(PG_FUNCTION_ARGS)
values[1] = Int64GetDatum((int64) stats.bucket_pages);
values[2] = Int64GetDatum((int64) stats.overflow_pages);
values[3] = Int64GetDatum((int64) stats.bitmap_pages);
- values[4] = Int64GetDatum((int64) stats.zero_pages);
+ values[4] = Int64GetDatum((int64) stats.unused_pages);
values[5] = Int64GetDatum(stats.live_items);
values[6] = Int64GetDatum(stats.dead_items);
values[7] = Float8GetDatum(free_percent);
diff --git a/contrib/pgstattuple/pgstattuple--1.4--1.5.sql b/contrib/pgstattuple/pgstattuple--1.4--1.5.sql
index 05ae51fa4bb..5d03544a214 100644
--- a/contrib/pgstattuple/pgstattuple--1.4--1.5.sql
+++ b/contrib/pgstattuple/pgstattuple--1.4--1.5.sql
@@ -125,7 +125,7 @@ CREATE OR REPLACE FUNCTION pgstathashindex(IN relname regclass,
OUT bucket_pages BIGINT,
OUT overflow_pages BIGINT,
OUT bitmap_pages BIGINT,
- OUT zero_pages BIGINT,
+ OUT unused_pages BIGINT,
OUT live_items BIGINT,
OUT dead_items BIGINT,
OUT free_percent FLOAT8)
diff --git a/doc/src/sgml/pgstattuple.sgml b/doc/src/sgml/pgstattuple.sgml
index 141d8e225fb..b6a5f19e706 100644
--- a/doc/src/sgml/pgstattuple.sgml
+++ b/doc/src/sgml/pgstattuple.sgml
@@ -372,7 +372,7 @@ version | 2
bucket_pages | 33081
overflow_pages | 0
bitmap_pages | 1
-zero_pages | 32455
+unused_pages | 32455
live_items | 10204006
dead_items | 0
free_percent | 61.8005949100872
@@ -418,9 +418,9 @@ free_percent | 61.8005949100872
</row>
<row>
- <entry><structfield>zero_pages</structfield></entry>
+ <entry><structfield>unused_pages</structfield></entry>
<entry><type>bigint</type></entry>
- <entry>Number of new or zero pages</entry>
+ <entry>Number of unused pages</entry>
</row>
<row>