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

Commit 028ec5c

Browse files
committed
Adjust /contrib/pg_freespace to show index free space as NULL (FSM only
tracks index pages, not free space on pages): 1/ Index free bytes set to NULL 2/ Comment added to the README briefly mentioning the index business 3/ Columns reordered more logically 4/ 'Blockid' column removed 5/ Free bytes column renamed to just 'bytes' instead of 'blockfreebytes' Mark Kirkwood
1 parent 59d6140 commit 028ec5c

File tree

3 files changed

+71
-50
lines changed

3 files changed

+71
-50
lines changed

contrib/pg_freespacemap/README.pg_freespacemap

+25-23
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,22 @@ Notes
3434

3535
Column | references | Description
3636
----------------+----------------------+------------------------------------
37-
blockid | | Id, 1.. max_fsm_pages
38-
relfilenode | pg_class.relfilenode | Refilenode of the relation.
3937
reltablespace | pg_tablespace.oid | Tablespace oid of the relation.
4038
reldatabase | pg_database.oid | Database for the relation.
39+
relfilenode | pg_class.relfilenode | Refilenode of the relation.
4140
relblocknumber | | Offset of the page in the relation.
42-
blockfreebytes | | Free bytes in the block/page.
41+
bytes | | Free bytes in the block/page, or NULL
42+
| | for an index page (see below).
4343

4444

4545
There is one row for each page in the free space map.
4646

4747
Because the map is shared by all the databases, there are pages from
4848
relations not belonging to the current database.
4949

50+
The free space map can contain pages for btree indexes if they were emptied
51+
by a vacuum process. The bytes field is set to NULL in this case.
52+
5053
When the pg_freespacemap view is accessed, internal free space map locks are
5154
taken, and a copy of the map data is made for the view to display.
5255
This ensures that the view produces a consistent set of results, while not
@@ -58,34 +61,33 @@ Sample output
5861
-------------
5962

6063
regression=# \d pg_freespacemap
61-
View "public.pg_freespacemap"
64+
View "public.pg_freespacemap"
6265
Column | Type | Modifiers
63-
---------------+---------+-----------
64-
blockid | integer |
65-
relfilenode | oid |
66+
----------------+---------+-----------
6667
reltablespace | oid |
6768
reldatabase | oid |
69+
relfilenode | oid |
6870
relblocknumber | bigint |
69-
blockfreebytes | integer |
71+
bytes | integer |
7072
View definition:
71-
SELECT p.blockid, p.relfilenode, p.reltablespace, p.reldatabase, p.relblocknumber, p.blockfreebytes
72-
FROM pg_freespacemap() p(blockid integer, relfilenode oid, reltablespace oid, reldatabase oid, relblocknumber bigint, blockfreebytes integer);
73+
SELECT p.reltablespace, p.reldatabase, p.relfilenode, p.relblocknumber, p.bytes
74+
FROM pg_freespacemap() p(reltablespace oid, reldatabase oid, relfilenode oid, relblocknumber bigint, bytes integer);
7375

74-
regression=# SELECT c.relname, m.relblocknumber, m.blockfreebytes
76+
regression=# SELECT c.relname, m.relblocknumber, m.bytes
7577
FROM pg_freespacemap m INNER JOIN pg_class c
7678
ON c.relfilenode = m.relfilenode LIMIT 10;
77-
relname | relblocknumber | blockfreebytes
78-
------------------------+----------------+----------------
79-
sql_features | 5 | 2696
80-
sql_implementation_info | 0 | 7104
81-
sql_languages | 0 | 8016
82-
sql_packages | 0 | 7376
83-
sql_sizing | 0 | 6032
84-
pg_authid | 0 | 7424
85-
pg_toast_2618 | 13 | 4588
86-
pg_toast_2618 | 12 | 1680
87-
pg_toast_2618 | 10 | 1436
88-
pg_toast_2618 | 7 | 1136
79+
relname | relblocknumber | bytes
80+
------------------------+----------------+--------
81+
sql_features | 5 | 2696
82+
sql_implementation_info | 0 | 7104
83+
sql_languages | 0 | 8016
84+
sql_packages | 0 | 7376
85+
sql_sizing | 0 | 6032
86+
pg_authid | 0 | 7424
87+
pg_toast_2618 | 13 | 4588
88+
pg_toast_2618 | 12 | 1680
89+
pg_toast_2618 | 10 | 1436
90+
pg_toast_2618 | 7 | 1136
8991
(10 rows)
9092

9193
regression=#

contrib/pg_freespacemap/pg_freespacemap.c

+45-26
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* pg_freespacemap.c
44
* display some contents of the free space map.
55
*
6-
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.2 2006/02/14 15:03:59 tgl Exp $
6+
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.3 2006/04/26 22:41:18 momjian Exp $
77
*-------------------------------------------------------------------------
88
*/
99
#include "postgres.h"
@@ -12,7 +12,7 @@
1212
#include "storage/freespace.h"
1313
#include "utils/relcache.h"
1414

15-
#define NUM_FREESPACE_PAGES_ELEM 6
15+
#define NUM_FREESPACE_PAGES_ELEM 5
1616

1717
#if defined(WIN32) || defined(__CYGWIN__)
1818
/* Need DLLIMPORT for some things that are not so marked in main headers */
@@ -29,12 +29,12 @@ Datum pg_freespacemap(PG_FUNCTION_ARGS);
2929
typedef struct
3030
{
3131

32-
uint32 blockid;
33-
uint32 relfilenode;
3432
uint32 reltablespace;
3533
uint32 reldatabase;
34+
uint32 relfilenode;
3635
uint32 relblocknumber;
37-
uint32 blockfreebytes;
36+
uint32 bytes;
37+
bool isindex;
3838

3939
} FreeSpacePagesRec;
4040

@@ -91,17 +91,15 @@ pg_freespacemap(PG_FUNCTION_ARGS)
9191

9292
/* Construct a tuple to return. */
9393
tupledesc = CreateTemplateTupleDesc(NUM_FREESPACE_PAGES_ELEM, false);
94-
TupleDescInitEntry(tupledesc, (AttrNumber) 1, "blockid",
95-
INT4OID, -1, 0);
96-
TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode",
94+
TupleDescInitEntry(tupledesc, (AttrNumber) 1, "reltablespace",
9795
OIDOID, -1, 0);
98-
TupleDescInitEntry(tupledesc, (AttrNumber) 3, "reltablespace",
96+
TupleDescInitEntry(tupledesc, (AttrNumber) 2, "reldatabase",
9997
OIDOID, -1, 0);
100-
TupleDescInitEntry(tupledesc, (AttrNumber) 4, "reldatabase",
98+
TupleDescInitEntry(tupledesc, (AttrNumber) 3, "relfilenode",
10199
OIDOID, -1, 0);
102-
TupleDescInitEntry(tupledesc, (AttrNumber) 5, "relblocknumber",
100+
TupleDescInitEntry(tupledesc, (AttrNumber) 4, "relblocknumber",
103101
INT8OID, -1, 0);
104-
TupleDescInitEntry(tupledesc, (AttrNumber) 6, "blockfreebytes",
102+
TupleDescInitEntry(tupledesc, (AttrNumber) 5, "bytes",
105103
INT4OID, -1, 0);
106104

107105
/* Generate attribute metadata needed later to produce tuples */
@@ -129,7 +127,6 @@ pg_freespacemap(PG_FUNCTION_ARGS)
129127
fctx->values[2] = (char *) palloc(3 * sizeof(uint32) + 1);
130128
fctx->values[3] = (char *) palloc(3 * sizeof(uint32) + 1);
131129
fctx->values[4] = (char *) palloc(3 * sizeof(uint32) + 1);
132-
fctx->values[5] = (char *) palloc(3 * sizeof(uint32) + 1);
133130

134131

135132
/* Return to original context when allocating transient memory */
@@ -158,12 +155,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
158155
for (nPages = 0; nPages < fsmrel->storedPages; nPages++)
159156
{
160157

161-
fctx->record[i].blockid = i;
162-
fctx->record[i].relfilenode = fsmrel->key.relNode;
163158
fctx->record[i].reltablespace = fsmrel->key.spcNode;
164159
fctx->record[i].reldatabase = fsmrel->key.dbNode;
160+
fctx->record[i].relfilenode = fsmrel->key.relNode;
165161
fctx->record[i].relblocknumber = IndexFSMPageGetPageNum(page);
166-
fctx->record[i].blockfreebytes = 0; /* index.*/
162+
fctx->record[i].bytes = 0;
163+
fctx->record[i].isindex = true;
167164

168165
page++;
169166
i++;
@@ -178,12 +175,12 @@ pg_freespacemap(PG_FUNCTION_ARGS)
178175

179176
for (nPages = 0; nPages < fsmrel->storedPages; nPages++)
180177
{
181-
fctx->record[i].blockid = i;
182-
fctx->record[i].relfilenode = fsmrel->key.relNode;
183178
fctx->record[i].reltablespace = fsmrel->key.spcNode;
184179
fctx->record[i].reldatabase = fsmrel->key.dbNode;
180+
fctx->record[i].relfilenode = fsmrel->key.relNode;
185181
fctx->record[i].relblocknumber = FSMPageGetPageNum(page);
186-
fctx->record[i].blockfreebytes = FSMPageGetSpace(page);
182+
fctx->record[i].bytes = FSMPageGetSpace(page);
183+
fctx->record[i].isindex = false;
187184

188185
page++;
189186
i++;
@@ -209,19 +206,41 @@ pg_freespacemap(PG_FUNCTION_ARGS)
209206
if (funcctx->call_cntr < funcctx->max_calls)
210207
{
211208
uint32 i = funcctx->call_cntr;
209+
char *values[NUM_FREESPACE_PAGES_ELEM];
210+
int j;
212211

212+
/*
213+
* Use a temporary values array, initially pointing to fctx->values,
214+
* so it can be reassigned w/o losing the storage for subsequent
215+
* calls.
216+
*/
217+
for (j = 0; j < NUM_FREESPACE_PAGES_ELEM; j++)
218+
{
219+
values[j] = fctx->values[j];
220+
}
221+
222+
223+
sprintf(values[0], "%u", fctx->record[i].reltablespace);
224+
sprintf(values[1], "%u", fctx->record[i].reldatabase);
225+
sprintf(values[2], "%u", fctx->record[i].relfilenode);
226+
sprintf(values[3], "%u", fctx->record[i].relblocknumber);
213227

214-
sprintf(fctx->values[0], "%u", fctx->record[i].blockid);
215-
sprintf(fctx->values[1], "%u", fctx->record[i].relfilenode);
216-
sprintf(fctx->values[2], "%u", fctx->record[i].reltablespace);
217-
sprintf(fctx->values[3], "%u", fctx->record[i].reldatabase);
218-
sprintf(fctx->values[4], "%u", fctx->record[i].relblocknumber);
219-
sprintf(fctx->values[5], "%u", fctx->record[i].blockfreebytes);
220228

229+
/*
230+
* Set (free) bytes to NULL for an index relation.
231+
*/
232+
if (fctx->record[i].isindex == true)
233+
{
234+
values[4] = NULL;
235+
}
236+
else
237+
{
238+
sprintf(values[4], "%u", fctx->record[i].bytes);
239+
}
221240

222241

223242
/* Build and return the tuple. */
224-
tuple = BuildTupleFromCStrings(funcctx->attinmeta, fctx->values);
243+
tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
225244
result = HeapTupleGetDatum(tuple);
226245

227246

contrib/pg_freespacemap/pg_freespacemap.sql.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LANGUAGE C;
1111
-- Create a view for convenient access.
1212
CREATE VIEW pg_freespacemap AS
1313
SELECT P.* FROM pg_freespacemap() AS P
14-
(blockid int4, relfilenode oid, reltablespace oid, reldatabase oid, relblocknumber int8, blockfreebytes int4);
14+
(reltablespace oid, reldatabase oid, relfilenode oid, relblocknumber int8, bytes int4);
1515

1616
-- Don't want these to be available at public.
1717
REVOKE ALL ON FUNCTION pg_freespacemap() FROM PUBLIC;

0 commit comments

Comments
 (0)