Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d287818

Browse files
committed
Adjust pgstatindex() to give correct answers for indexes larger than
2^31 blocks. Also fix pg_relpages() for the same case. Tatsuhito Kasahara
1 parent 458c585 commit d287818

File tree

3 files changed

+69
-78
lines changed

3 files changed

+69
-78
lines changed

contrib/pgstattuple/pgstatindex.c

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -59,19 +59,19 @@ PG_FUNCTION_INFO_V1(pg_relpages);
5959
typedef struct BTIndexStat
6060
{
6161
uint32 version;
62-
BlockNumber root_blkno;
6362
uint32 level;
63+
BlockNumber root_blkno;
6464

65-
uint32 root_pages;
66-
uint32 internal_pages;
67-
uint32 leaf_pages;
68-
uint32 empty_pages;
69-
uint32 deleted_pages;
65+
uint64 root_pages;
66+
uint64 internal_pages;
67+
uint64 leaf_pages;
68+
uint64 empty_pages;
69+
uint64 deleted_pages;
7070

71-
uint32 max_avail;
72-
uint32 free_space;
71+
uint64 max_avail;
72+
uint64 free_space;
7373

74-
uint32 fragments;
74+
uint64 fragments;
7575
} BTIndexStat;
7676

7777
/* ------------------------------------------------------
@@ -87,8 +87,8 @@ pgstatindex(PG_FUNCTION_ARGS)
8787
Relation rel;
8888
RangeVar *relrv;
8989
Datum result;
90-
uint32 nblocks;
91-
uint32 blkno;
90+
BlockNumber nblocks;
91+
BlockNumber blkno;
9292
BTIndexStat indexStat;
9393

9494
if (!superuser())
@@ -112,30 +112,29 @@ pgstatindex(PG_FUNCTION_ARGS)
112112
BTMetaPageData *metad = BTPageGetMeta(page);
113113

114114
indexStat.version = metad->btm_version;
115-
indexStat.root_blkno = metad->btm_root;
116115
indexStat.level = metad->btm_level;
116+
indexStat.root_blkno = metad->btm_root;
117117

118118
ReleaseBuffer(buffer);
119119
}
120120

121-
nblocks = RelationGetNumberOfBlocks(rel);
122-
123-
/* -- init stat -- */
124-
indexStat.fragments = 0;
125-
121+
/* -- init counters -- */
126122
indexStat.root_pages = 0;
127-
indexStat.leaf_pages = 0;
128123
indexStat.internal_pages = 0;
124+
indexStat.leaf_pages = 0;
129125
indexStat.empty_pages = 0;
130126
indexStat.deleted_pages = 0;
131127

132128
indexStat.max_avail = 0;
133129
indexStat.free_space = 0;
134130

135-
/*-----------------------
136-
* Scan all blocks
137-
*-----------------------
131+
indexStat.fragments = 0;
132+
133+
/*
134+
* Scan all blocks except the metapage
138135
*/
136+
nblocks = RelationGetNumberOfBlocks(rel);
137+
139138
for (blkno = 1; blkno < nblocks; blkno++)
140139
{
141140
Buffer buffer;
@@ -151,13 +150,7 @@ pgstatindex(PG_FUNCTION_ARGS)
151150

152151
/* Determine page type, and update totals */
153152

154-
if (P_ISDELETED(opaque))
155-
indexStat.deleted_pages++;
156-
157-
else if (P_IGNORE(opaque))
158-
indexStat.empty_pages++;
159-
160-
else if (P_ISLEAF(opaque))
153+
if (P_ISLEAF(opaque))
161154
{
162155
int max_avail;
163156

@@ -174,9 +167,12 @@ pgstatindex(PG_FUNCTION_ARGS)
174167
if (opaque->btpo_next != P_NONE && opaque->btpo_next < blkno)
175168
indexStat.fragments++;
176169
}
170+
else if (P_ISDELETED(opaque))
171+
indexStat.deleted_pages++;
172+
else if (P_IGNORE(opaque))
173+
indexStat.empty_pages++;
177174
else if (P_ISROOT(opaque))
178175
indexStat.root_pages++;
179-
180176
else
181177
indexStat.internal_pages++;
182178

@@ -207,25 +203,26 @@ pgstatindex(PG_FUNCTION_ARGS)
207203
values[j] = palloc(32);
208204
snprintf(values[j++], 32, "%d", indexStat.level);
209205
values[j] = palloc(32);
210-
snprintf(values[j++], 32, "%d", (indexStat.root_pages +
211-
indexStat.leaf_pages +
212-
indexStat.internal_pages +
213-
indexStat.deleted_pages +
214-
indexStat.empty_pages) * BLCKSZ);
206+
snprintf(values[j++], 32, INT64_FORMAT,
207+
(indexStat.root_pages +
208+
indexStat.leaf_pages +
209+
indexStat.internal_pages +
210+
indexStat.deleted_pages +
211+
indexStat.empty_pages) * BLCKSZ);
215212
values[j] = palloc(32);
216-
snprintf(values[j++], 32, "%d", indexStat.root_blkno);
213+
snprintf(values[j++], 32, "%u", indexStat.root_blkno);
217214
values[j] = palloc(32);
218-
snprintf(values[j++], 32, "%d", indexStat.internal_pages);
215+
snprintf(values[j++], 32, INT64_FORMAT, indexStat.internal_pages);
219216
values[j] = palloc(32);
220-
snprintf(values[j++], 32, "%d", indexStat.leaf_pages);
217+
snprintf(values[j++], 32, INT64_FORMAT, indexStat.leaf_pages);
221218
values[j] = palloc(32);
222-
snprintf(values[j++], 32, "%d", indexStat.empty_pages);
219+
snprintf(values[j++], 32, INT64_FORMAT, indexStat.empty_pages);
223220
values[j] = palloc(32);
224-
snprintf(values[j++], 32, "%d", indexStat.deleted_pages);
221+
snprintf(values[j++], 32, INT64_FORMAT, indexStat.deleted_pages);
225222
values[j] = palloc(32);
226-
snprintf(values[j++], 32, "%.2f", 100.0 - (float) indexStat.free_space / (float) indexStat.max_avail * 100.0);
223+
snprintf(values[j++], 32, "%.2f", 100.0 - (double) indexStat.free_space / (double) indexStat.max_avail * 100.0);
227224
values[j] = palloc(32);
228-
snprintf(values[j++], 32, "%.2f", (float) indexStat.fragments / (float) indexStat.leaf_pages * 100.0);
225+
snprintf(values[j++], 32, "%.2f", (double) indexStat.fragments / (double) indexStat.leaf_pages * 100.0);
229226

230227
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
231228
values);
@@ -249,9 +246,9 @@ Datum
249246
pg_relpages(PG_FUNCTION_ARGS)
250247
{
251248
text *relname = PG_GETARG_TEXT_P(0);
249+
int64 relpages;
252250
Relation rel;
253251
RangeVar *relrv;
254-
int4 relpages;
255252

256253
if (!superuser())
257254
ereport(ERROR,
@@ -265,5 +262,5 @@ pg_relpages(PG_FUNCTION_ARGS)
265262

266263
relation_close(rel, AccessShareLock);
267264

268-
PG_RETURN_INT32(relpages);
265+
PG_RETURN_INT64(relpages);
269266
}
Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.sql.in,v 1.15 2007/11/13 04:24:28 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/contrib/pgstattuple/pgstattuple.sql.in,v 1.16 2008/03/21 03:23:30 tgl Exp $ */
22

33
-- Adjust this setting to control where the objects get created.
44
SET search_path = public;
@@ -7,49 +7,43 @@ CREATE OR REPLACE FUNCTION pgstattuple(IN relname text,
77
OUT table_len BIGINT, -- physical table length in bytes
88
OUT tuple_count BIGINT, -- number of live tuples
99
OUT tuple_len BIGINT, -- total tuples length in bytes
10-
OUT tuple_percent FLOAT, -- live tuples in %
10+
OUT tuple_percent FLOAT8, -- live tuples in %
1111
OUT dead_tuple_count BIGINT, -- number of dead tuples
1212
OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
13-
OUT dead_tuple_percent FLOAT, -- dead tuples in %
13+
OUT dead_tuple_percent FLOAT8, -- dead tuples in %
1414
OUT free_space BIGINT, -- free space in bytes
15-
OUT free_percent FLOAT) -- free space in %
15+
OUT free_percent FLOAT8) -- free space in %
1616
AS 'MODULE_PATHNAME', 'pgstattuple'
1717
LANGUAGE C STRICT;
1818

1919
CREATE OR REPLACE FUNCTION pgstattuple(IN reloid oid,
2020
OUT table_len BIGINT, -- physical table length in bytes
2121
OUT tuple_count BIGINT, -- number of live tuples
2222
OUT tuple_len BIGINT, -- total tuples length in bytes
23-
OUT tuple_percent FLOAT, -- live tuples in %
23+
OUT tuple_percent FLOAT8, -- live tuples in %
2424
OUT dead_tuple_count BIGINT, -- number of dead tuples
2525
OUT dead_tuple_len BIGINT, -- total dead tuples length in bytes
26-
OUT dead_tuple_percent FLOAT, -- dead tuples in %
26+
OUT dead_tuple_percent FLOAT8, -- dead tuples in %
2727
OUT free_space BIGINT, -- free space in bytes
28-
OUT free_percent FLOAT) -- free space in %
28+
OUT free_percent FLOAT8) -- free space in %
2929
AS 'MODULE_PATHNAME', 'pgstattuplebyid'
3030
LANGUAGE C STRICT;
3131

32-
--
33-
-- pgstatindex
34-
--
3532
CREATE OR REPLACE FUNCTION pgstatindex(IN relname text,
36-
OUT version int4,
37-
OUT tree_level int4,
38-
OUT index_size int4,
39-
OUT root_block_no int4,
40-
OUT internal_pages int4,
41-
OUT leaf_pages int4,
42-
OUT empty_pages int4,
43-
OUT deleted_pages int4,
44-
OUT avg_leaf_density float8,
45-
OUT leaf_fragmentation float8)
33+
OUT version INT,
34+
OUT tree_level INT,
35+
OUT index_size BIGINT,
36+
OUT root_block_no BIGINT,
37+
OUT internal_pages BIGINT,
38+
OUT leaf_pages BIGINT,
39+
OUT empty_pages BIGINT,
40+
OUT deleted_pages BIGINT,
41+
OUT avg_leaf_density FLOAT8,
42+
OUT leaf_fragmentation FLOAT8)
4643
AS 'MODULE_PATHNAME', 'pgstatindex'
4744
LANGUAGE C STRICT;
4845

49-
--
50-
-- pg_relpages()
51-
--
52-
CREATE OR REPLACE FUNCTION pg_relpages(text)
53-
RETURNS int
46+
CREATE OR REPLACE FUNCTION pg_relpages(IN relname text)
47+
RETURNS BIGINT
5448
AS 'MODULE_PATHNAME', 'pg_relpages'
5549
LANGUAGE C STRICT;

doc/src/sgml/pgstattuple.sgml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgstattuple.sgml,v 1.3 2007/12/10 05:32:51 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgstattuple.sgml,v 1.4 2008/03/21 03:23:30 tgl Exp $ -->
22

33
<sect1 id="pgstattuple">
44
<title>pgstattuple</title>
@@ -190,37 +190,37 @@ leaf_fragmentation | 0
190190

191191
<row>
192192
<entry><structfield>index_size</structfield></entry>
193-
<entry><type>integer</type></entry>
193+
<entry><type>bigint</type></entry>
194194
<entry>Total number of pages in index</entry>
195195
</row>
196196

197197
<row>
198198
<entry><structfield>root_block_no</structfield></entry>
199-
<entry><type>integer</type></entry>
199+
<entry><type>bigint</type></entry>
200200
<entry>Location of root block</entry>
201201
</row>
202202

203203
<row>
204204
<entry><structfield>internal_pages</structfield></entry>
205-
<entry><type>integer</type></entry>
205+
<entry><type>bigint</type></entry>
206206
<entry>Number of <quote>internal</> (upper-level) pages</entry>
207207
</row>
208208

209209
<row>
210210
<entry><structfield>leaf_pages</structfield></entry>
211-
<entry><type>integer</type></entry>
211+
<entry><type>bigint</type></entry>
212212
<entry>Number of leaf pages</entry>
213213
</row>
214214

215215
<row>
216216
<entry><structfield>empty_pages</structfield></entry>
217-
<entry><type>integer</type></entry>
217+
<entry><type>bigint</type></entry>
218218
<entry>Number of empty pages</entry>
219219
</row>
220220

221221
<row>
222222
<entry><structfield>deleted_pages</structfield></entry>
223-
<entry><type>integer</type></entry>
223+
<entry><type>bigint</type></entry>
224224
<entry>Number of deleted pages</entry>
225225
</row>
226226

@@ -250,7 +250,7 @@ leaf_fragmentation | 0
250250

251251
<varlistentry>
252252
<term>
253-
<function>pg_relpages(text) returns integer</>
253+
<function>pg_relpages(text) returns bigint</>
254254
</term>
255255

256256
<listitem>
@@ -264,10 +264,10 @@ leaf_fragmentation | 0
264264
</sect2>
265265

266266
<sect2>
267-
<title>Author</title>
267+
<title>Authors</title>
268268

269269
<para>
270-
Tatsuo Ishii
270+
Tatsuo Ishii and Satoshi Nagayasu
271271
</para>
272272
</sect2>
273273

0 commit comments

Comments
 (0)