Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
d3de08a0
Commit
d3de08a0
authored
Sep 30, 2008
by
Heikki Linnakangas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rewrite pg_freespacemap to match the new FSM implementation. I missed these
changes from the main FSM commit for some reason.
parent
4e6ac2e1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
25 additions
and
369 deletions
+25
-369
contrib/pg_freespacemap/Makefile
contrib/pg_freespacemap/Makefile
+1
-1
contrib/pg_freespacemap/pg_freespacemap.c
contrib/pg_freespacemap/pg_freespacemap.c
+22
-366
contrib/pg_freespacemap/pg_freespacemap.sql.in
contrib/pg_freespacemap/pg_freespacemap.sql.in
+1
-1
contrib/pg_freespacemap/uninstall_pg_freespacemap.sql
contrib/pg_freespacemap/uninstall_pg_freespacemap.sql
+1
-1
No files found.
contrib/pg_freespacemap/Makefile
View file @
d3de08a0
# $PostgreSQL: pgsql/contrib/pg_freespacemap/Makefile,v 1.
4 2007/11/10 23:59:51 momjian
Exp $
# $PostgreSQL: pgsql/contrib/pg_freespacemap/Makefile,v 1.
5 2008/09/30 11:17:07 heikki
Exp $
MODULE_big
=
pg_freespacemap
OBJS
=
pg_freespacemap.o
...
...
contrib/pg_freespacemap/pg_freespacemap.c
View file @
d3de08a0
/*-------------------------------------------------------------------------
*
* pg_freespacemap.c
* display
some contents of the free space relation and page maps.
* display
contents of a free space map
*
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.1
0 2008/05/12 00:00:43 alvherre
Exp $
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.1
1 2008/09/30 11:17:07 heikki
Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/heapam.h"
#include "access/htup.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "storage/freespace.h"
#include "
storage/lmgr
.h"
#include "
utils/builtins
.h"
#define NUM_FREESPACE_PAGES_ELEM 5
#define NUM_FREESPACE_RELATIONS_ELEM 7
PG_MODULE_MAGIC
;
Datum
pg_freespacemap_pages
(
PG_FUNCTION_ARGS
);
Datum
pg_freespacemap_relations
(
PG_FUNCTION_ARGS
);
/*
* Record structure holding the to be exposed per-page data.
*/
typedef
struct
{
Oid
reltablespace
;
Oid
reldatabase
;
Oid
relfilenode
;
BlockNumber
relblocknumber
;
Size
bytes
;
bool
isindex
;
}
FreeSpacePagesRec
;
/*
* Record structure holding the to be exposed per-relation data.
*/
typedef
struct
{
Oid
reltablespace
;
Oid
reldatabase
;
Oid
relfilenode
;
Size
avgrequest
;
BlockNumber
interestingpages
;
int
storedpages
;
int
nextpage
;
bool
isindex
;
}
FreeSpaceRelationsRec
;
/*
* Function context for page data persisting over repeated calls.
*/
typedef
struct
{
TupleDesc
tupdesc
;
FreeSpacePagesRec
*
record
;
}
FreeSpacePagesContext
;
/*
* Function context for relation data persisting over repeated calls.
*/
typedef
struct
{
TupleDesc
tupdesc
;
FreeSpaceRelationsRec
*
record
;
}
FreeSpaceRelationsContext
;
/*
* Function returning page data from the Free Space Map (FSM).
*/
PG_FUNCTION_INFO_V1
(
pg_freespacemap_pages
);
Datum
pg_freespacemap_pages
(
PG_FUNCTION_ARGS
)
{
FuncCallContext
*
funcctx
;
Datum
result
;
MemoryContext
oldcontext
;
FreeSpacePagesContext
*
fctx
;
/* User function context. */
TupleDesc
tupledesc
;
HeapTuple
tuple
;
FSMHeader
*
FreeSpaceMap
;
/* FSM main structure. */
FSMRelation
*
fsmrel
;
/* Individual relation. */
if
(
SRF_IS_FIRSTCALL
())
{
int
i
;
int
numPages
;
/* Max possible no. of pages in map. */
int
nPages
;
/* Mapped pages for a relation. */
/*
* Get the free space map data structure.
*/
FreeSpaceMap
=
GetFreeSpaceMap
();
numPages
=
MaxFSMPages
;
funcctx
=
SRF_FIRSTCALL_INIT
();
/* Switch context when allocating stuff to be used in later calls */
oldcontext
=
MemoryContextSwitchTo
(
funcctx
->
multi_call_memory_ctx
);
/*
* Create a function context for cross-call persistence.
*/
fctx
=
(
FreeSpacePagesContext
*
)
palloc
(
sizeof
(
FreeSpacePagesContext
));
funcctx
->
user_fctx
=
fctx
;
/* Construct a tuple descriptor for the result rows. */
tupledesc
=
CreateTemplateTupleDesc
(
NUM_FREESPACE_PAGES_ELEM
,
false
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
1
,
"reltablespace"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
2
,
"reldatabase"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
3
,
"relfilenode"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
4
,
"relblocknumber"
,
INT8OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
5
,
"bytes"
,
INT4OID
,
-
1
,
0
);
fctx
->
tupdesc
=
BlessTupleDesc
(
tupledesc
);
/*
* Allocate numPages worth of FreeSpacePagesRec records, this is an
* upper bound.
*/
fctx
->
record
=
(
FreeSpacePagesRec
*
)
palloc
(
sizeof
(
FreeSpacePagesRec
)
*
numPages
);
/* Return to original context when allocating transient memory */
MemoryContextSwitchTo
(
oldcontext
);
/*
* Lock free space map and scan though all the relations. For each
* relation, gets all its mapped pages.
*/
LWLockAcquire
(
FreeSpaceLock
,
LW_EXCLUSIVE
);
i
=
0
;
for
(
fsmrel
=
FreeSpaceMap
->
usageList
;
fsmrel
;
fsmrel
=
fsmrel
->
nextUsage
)
{
if
(
fsmrel
->
isIndex
)
{
/* Index relation. */
IndexFSMPageData
*
page
;
page
=
(
IndexFSMPageData
*
)
(
FreeSpaceMap
->
arena
+
fsmrel
->
firstChunk
*
CHUNKBYTES
);
for
(
nPages
=
0
;
nPages
<
fsmrel
->
storedPages
;
nPages
++
)
{
fctx
->
record
[
i
].
reltablespace
=
fsmrel
->
key
.
spcNode
;
fctx
->
record
[
i
].
reldatabase
=
fsmrel
->
key
.
dbNode
;
fctx
->
record
[
i
].
relfilenode
=
fsmrel
->
key
.
relNode
;
fctx
->
record
[
i
].
relblocknumber
=
IndexFSMPageGetPageNum
(
page
);
fctx
->
record
[
i
].
bytes
=
0
;
fctx
->
record
[
i
].
isindex
=
true
;
page
++
;
i
++
;
}
}
else
{
/* Heap relation. */
FSMPageData
*
page
;
page
=
(
FSMPageData
*
)
(
FreeSpaceMap
->
arena
+
fsmrel
->
firstChunk
*
CHUNKBYTES
);
for
(
nPages
=
0
;
nPages
<
fsmrel
->
storedPages
;
nPages
++
)
{
fctx
->
record
[
i
].
reltablespace
=
fsmrel
->
key
.
spcNode
;
fctx
->
record
[
i
].
reldatabase
=
fsmrel
->
key
.
dbNode
;
fctx
->
record
[
i
].
relfilenode
=
fsmrel
->
key
.
relNode
;
fctx
->
record
[
i
].
relblocknumber
=
FSMPageGetPageNum
(
page
);
fctx
->
record
[
i
].
bytes
=
FSMPageGetSpace
(
page
);
fctx
->
record
[
i
].
isindex
=
false
;
page
++
;
i
++
;
}
}
}
/* Release free space map. */
LWLockRelease
(
FreeSpaceLock
);
/* Set the real no. of calls as we know it now! */
Assert
(
i
<=
numPages
);
funcctx
->
max_calls
=
i
;
}
funcctx
=
SRF_PERCALL_SETUP
();
/* Get the saved state */
fctx
=
funcctx
->
user_fctx
;
if
(
funcctx
->
call_cntr
<
funcctx
->
max_calls
)
{
int
i
=
funcctx
->
call_cntr
;
FreeSpacePagesRec
*
record
=
&
fctx
->
record
[
i
];
Datum
values
[
NUM_FREESPACE_PAGES_ELEM
];
bool
nulls
[
NUM_FREESPACE_PAGES_ELEM
];
values
[
0
]
=
ObjectIdGetDatum
(
record
->
reltablespace
);
nulls
[
0
]
=
false
;
values
[
1
]
=
ObjectIdGetDatum
(
record
->
reldatabase
);
nulls
[
1
]
=
false
;
values
[
2
]
=
ObjectIdGetDatum
(
record
->
relfilenode
);
nulls
[
2
]
=
false
;
values
[
3
]
=
Int64GetDatum
((
int64
)
record
->
relblocknumber
);
nulls
[
3
]
=
false
;
/*
* Set (free) bytes to NULL for an index relation.
*/
if
(
record
->
isindex
)
{
nulls
[
4
]
=
true
;
}
else
{
values
[
4
]
=
UInt32GetDatum
(
record
->
bytes
);
nulls
[
4
]
=
false
;
}
/* Build and return the tuple. */
tuple
=
heap_form_tuple
(
fctx
->
tupdesc
,
values
,
nulls
);
result
=
HeapTupleGetDatum
(
tuple
);
SRF_RETURN_NEXT
(
funcctx
,
result
);
}
else
SRF_RETURN_DONE
(
funcctx
);
}
Datum
pg_freespace
(
PG_FUNCTION_ARGS
);
Datum
pg_freespacedump
(
PG_FUNCTION_ARGS
);
/*
* Function returning relation data from the Free Space Map (FSM).
* Returns the amount of free space on a given page, according to the
* free space map.
*/
PG_FUNCTION_INFO_V1
(
pg_freespace
map_relations
);
PG_FUNCTION_INFO_V1
(
pg_freespace
);
Datum
pg_freespace
map_relations
(
PG_FUNCTION_ARGS
)
pg_freespace
(
PG_FUNCTION_ARGS
)
{
FuncCallContext
*
funcctx
;
Datum
result
;
MemoryContext
oldcontext
;
FreeSpaceRelationsContext
*
fctx
;
/* User function context. */
TupleDesc
tupledesc
;
HeapTuple
tuple
;
FSMHeader
*
FreeSpaceMap
;
/* FSM main structure. */
FSMRelation
*
fsmrel
;
/* Individual relation. */
if
(
SRF_IS_FIRSTCALL
())
{
int
i
;
int
numRelations
;
/* Max no. of Relations in map. */
/*
* Get the free space map data structure.
*/
FreeSpaceMap
=
GetFreeSpaceMap
();
numRelations
=
MaxFSMRelations
;
funcctx
=
SRF_FIRSTCALL_INIT
();
/* Switch context when allocating stuff to be used in later calls */
oldcontext
=
MemoryContextSwitchTo
(
funcctx
->
multi_call_memory_ctx
);
/*
* Create a function context for cross-call persistence.
*/
fctx
=
(
FreeSpaceRelationsContext
*
)
palloc
(
sizeof
(
FreeSpaceRelationsContext
));
funcctx
->
user_fctx
=
fctx
;
/* Construct a tuple descriptor for the result rows. */
tupledesc
=
CreateTemplateTupleDesc
(
NUM_FREESPACE_RELATIONS_ELEM
,
false
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
1
,
"reltablespace"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
2
,
"reldatabase"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
3
,
"relfilenode"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
4
,
"avgrequest"
,
INT4OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
5
,
"interestingpages"
,
INT4OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
6
,
"storedpages"
,
INT4OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
7
,
"nextpage"
,
INT4OID
,
-
1
,
0
);
fctx
->
tupdesc
=
BlessTupleDesc
(
tupledesc
);
/*
* Allocate numRelations worth of FreeSpaceRelationsRec records, this
* is also an upper bound.
*/
fctx
->
record
=
(
FreeSpaceRelationsRec
*
)
palloc
(
sizeof
(
FreeSpaceRelationsRec
)
*
numRelations
);
/* Return to original context when allocating transient memory */
MemoryContextSwitchTo
(
oldcontext
);
/*
* Lock free space map and scan though all the relations.
*/
LWLockAcquire
(
FreeSpaceLock
,
LW_EXCLUSIVE
);
i
=
0
;
for
(
fsmrel
=
FreeSpaceMap
->
usageList
;
fsmrel
;
fsmrel
=
fsmrel
->
nextUsage
)
{
fctx
->
record
[
i
].
reltablespace
=
fsmrel
->
key
.
spcNode
;
fctx
->
record
[
i
].
reldatabase
=
fsmrel
->
key
.
dbNode
;
fctx
->
record
[
i
].
relfilenode
=
fsmrel
->
key
.
relNode
;
fctx
->
record
[
i
].
avgrequest
=
(
int64
)
fsmrel
->
avgRequest
;
fctx
->
record
[
i
].
interestingpages
=
fsmrel
->
interestingPages
;
fctx
->
record
[
i
].
storedpages
=
fsmrel
->
storedPages
;
fctx
->
record
[
i
].
nextpage
=
fsmrel
->
nextPage
;
fctx
->
record
[
i
].
isindex
=
fsmrel
->
isIndex
;
i
++
;
}
/* Release free space map. */
LWLockRelease
(
FreeSpaceLock
);
/* Set the real no. of calls as we know it now! */
Assert
(
i
<=
numRelations
);
funcctx
->
max_calls
=
i
;
}
funcctx
=
SRF_PERCALL_SETUP
();
/* Get the saved state */
fctx
=
funcctx
->
user_fctx
;
if
(
funcctx
->
call_cntr
<
funcctx
->
max_calls
)
{
int
i
=
funcctx
->
call_cntr
;
FreeSpaceRelationsRec
*
record
=
&
fctx
->
record
[
i
];
Datum
values
[
NUM_FREESPACE_RELATIONS_ELEM
];
bool
nulls
[
NUM_FREESPACE_RELATIONS_ELEM
];
Oid
relid
=
PG_GETARG_OID
(
0
);
uint32
blkno
=
PG_GETARG_UINT32
(
1
);
int16
freespace
;
Relation
rel
;
values
[
0
]
=
ObjectIdGetDatum
(
record
->
reltablespace
);
nulls
[
0
]
=
false
;
values
[
1
]
=
ObjectIdGetDatum
(
record
->
reldatabase
);
nulls
[
1
]
=
false
;
values
[
2
]
=
ObjectIdGetDatum
(
record
->
relfilenode
);
nulls
[
2
]
=
false
;
rel
=
relation_open
(
relid
,
AccessShareLock
);
/*
* avgrequest isn't meaningful for an index
*/
if
(
record
->
isindex
)
{
nulls
[
3
]
=
true
;
}
else
{
values
[
3
]
=
UInt32GetDatum
(
record
->
avgrequest
);
nulls
[
3
]
=
false
;
}
values
[
4
]
=
Int32GetDatum
(
record
->
interestingpages
);
nulls
[
4
]
=
false
;
values
[
5
]
=
Int32GetDatum
(
record
->
storedpages
);
nulls
[
5
]
=
false
;
values
[
6
]
=
Int32GetDatum
(
record
->
nextpage
);
nulls
[
6
]
=
false
;
if
(
!
BlockNumberIsValid
(
blkno
))
ereport
(
ERROR
,
(
errcode
(
ERRCODE_INVALID_PARAMETER_VALUE
),
errmsg
(
"invalid block number"
)));
/* Build and return the tuple. */
tuple
=
heap_form_tuple
(
fctx
->
tupdesc
,
values
,
nulls
);
result
=
HeapTupleGetDatum
(
tuple
);
freespace
=
GetRecordedFreeSpace
(
rel
,
blkno
);
SRF_RETURN_NEXT
(
funcctx
,
result
);
}
else
SRF_RETURN_DONE
(
funcctx
);
relation_close
(
rel
,
AccessShareLock
);
PG_RETURN_INT16
(
freespace
);
}
contrib/pg_freespacemap/pg_freespacemap.sql.in
View file @
d3de08a0
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.sql.in,v 1.
9 2008/09/30 10:52:09
heikki Exp $ */
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.sql.in,v 1.
10 2008/09/30 11:17:07
heikki Exp $ */
-- Adjust this setting to control where the objects get created.
SET search_path = public;
...
...
contrib/pg_freespacemap/uninstall_pg_freespacemap.sql
View file @
d3de08a0
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/uninstall_pg_freespacemap.sql,v 1.
3 2007/11/13 04:24:28 momjian
Exp $ */
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/uninstall_pg_freespacemap.sql,v 1.
4 2008/09/30 11:17:07 heikki
Exp $ */
-- Adjust this setting to control where the objects get dropped.
SET
search_path
=
public
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment