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
d5dd3d45
Commit
d5dd3d45
authored
Feb 12, 2006
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add contrib/pg_freespacemap to display free space map information.
Mark Kirkwood
parent
6c0d4aab
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
481 additions
and
98 deletions
+481
-98
contrib/Makefile
contrib/Makefile
+2
-1
contrib/README
contrib/README
+4
-0
contrib/pg_freespacemap/Makefile
contrib/pg_freespacemap/Makefile
+17
-0
contrib/pg_freespacemap/README.pg_freespacemap
contrib/pg_freespacemap/README.pg_freespacemap
+98
-0
contrib/pg_freespacemap/pg_freespacemap.c
contrib/pg_freespacemap/pg_freespacemap.c
+231
-0
contrib/pg_freespacemap/pg_freespacemap.sql.in
contrib/pg_freespacemap/pg_freespacemap.sql.in
+19
-0
src/backend/storage/freespace/freespace.c
src/backend/storage/freespace/freespace.c
+12
-96
src/include/storage/freespace.h
src/include/storage/freespace.h
+98
-1
No files found.
contrib/Makefile
View file @
d5dd3d45
# $PostgreSQL: pgsql/contrib/Makefile,v 1.6
1 2005/09/01 22:02:44 tgl
Exp $
# $PostgreSQL: pgsql/contrib/Makefile,v 1.6
2 2006/02/12 03:55:52 momjian
Exp $
subdir
=
contrib
top_builddir
=
..
...
...
@@ -21,6 +21,7 @@ WANTED_DIRS = \
ltree
\
oid2name
\
pg_buffercache
\
pg_freespacemap
\
pg_trgm
\
pgbench
\
pgcrypto
\
...
...
contrib/README
View file @
d5dd3d45
...
...
@@ -106,6 +106,10 @@ pg_buffercache -
Real time queries on the shared buffer cache
by Mark Kirkwood <markir@paradise.net.nz>
pg_freespacemap -
Displays the contents of the free space map (FSM)
by Mark Kirkwood <markir@paradise.net.nz>
pg_trgm -
Functions for determining the similarity of text based on trigram
matching.
...
...
contrib/pg_freespacemap/Makefile
0 → 100644
View file @
d5dd3d45
# $PostgreSQL: pgsql/contrib/pg_freespacemap/Makefile,v 1.1 2006/02/12 03:55:53 momjian Exp $
MODULE_big
=
pg_freespacemap
OBJS
=
pg_freespacemap.o
DATA_built
=
pg_freespacemap.sql
DOCS
=
README.pg_freespacemap
ifdef
USE_PGXS
PGXS
:=
$(
shell
pg_config
--pgxs
)
include
$(PGXS)
else
subdir
=
contrib/pg_freespacemap
top_builddir
=
../..
include
$(top_builddir)/src/Makefile.global
include
$(top_srcdir)/contrib/contrib-global.mk
endif
contrib/pg_freespacemap/README.pg_freespacemap
0 → 100644
View file @
d5dd3d45
Pg_freespacemap - Real time queries on the free space map (FSM).
---------------
This module consists of a C function 'pg_freespacemap()' that returns
a set of records, and a view 'pg_freespacemap' to wrapper the function.
The module provides the ability to examine the contents of the free space
map, without having to restart or rebuild the server with additional
debugging code.
By default public access is REVOKED from both of these, just in case there
are security issues lurking.
Installation
------------
Build and install the main Postgresql source, then this contrib module:
$ cd contrib/pg_freespacemap
$ gmake
$ gmake install
To register the functions:
$ psql -d <database> -f pg_freespacemap.sql
Notes
-----
The definition of the columns exposed in the view is:
Column | references | Description
----------------+----------------------+------------------------------------
blockid | | Id, 1.. max_fsm_pages
relfilenode | pg_class.relfilenode | Refilenode of the relation.
reltablespace | pg_tablespace.oid | Tablespace oid of the relation.
reldatabase | pg_database.oid | Database for the relation.
relblocknumber | | Offset of the page in the relation.
blockfreebytes | | Free bytes in the block/page.
There is one row for each page in the free space map.
Because the map is shared by all the databases, there are pages from
relations not belonging to the current database.
When the pg_freespacemap view is accessed, internal free space map locks are
taken, and a copy of the map data is made for the view to display.
This ensures that the view produces a consistent set of results, while not
blocking normal activity longer than necessary. Nonetheless there
could be some impact on database performance if this view is read often.
Sample output
-------------
regression=# \d pg_freespacemap
View "public.pg_freespacemap"
Column | Type | Modifiers
---------------+---------+-----------
blockid | integer |
relfilenode | oid |
reltablespace | oid |
reldatabase | oid |
relblocknumber | bigint |
blockfreebytes | integer |
View definition:
SELECT p.blockid, p.relfilenode, p.reltablespace, p.reldatabase, p.relblocknumber, p.blockfreebytes
FROM pg_freespacemap() p(blockid integer, relfilenode oid, reltablespace oid, reldatabase oid, relblocknumber bigint, blockfreebytes integer);
regression=# SELECT c.relname, m.relblocknumber, m.blockfreebytes
FROM pg_freespacemap m INNER JOIN pg_class c
ON c.relfilenode = m.relfilenode LIMIT 10;
relname | relblocknumber | blockfreebytes
------------------------+----------------+----------------
sql_features | 5 | 2696
sql_implementation_info | 0 | 7104
sql_languages | 0 | 8016
sql_packages | 0 | 7376
sql_sizing | 0 | 6032
pg_authid | 0 | 7424
pg_toast_2618 | 13 | 4588
pg_toast_2618 | 12 | 1680
pg_toast_2618 | 10 | 1436
pg_toast_2618 | 7 | 1136
(10 rows)
regression=#
Author
------
* Mark Kirkwood <markir@paradise.net.nz>
contrib/pg_freespacemap/pg_freespacemap.c
0 → 100644
View file @
d5dd3d45
/*-------------------------------------------------------------------------
*
* pg_freespacemap.c
* display some contents of the free space map.
*
* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.c,v 1.1 2006/02/12 03:55:53 momjian Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "funcapi.h"
#include "catalog/pg_type.h"
#include "storage/freespace.h"
#include "utils/relcache.h"
#define NUM_FREESPACE_PAGES_ELEM 6
#if defined(WIN32) || defined(__CYGWIN__)
extern
DLLIMPORT
volatile
uint32
InterruptHoldoffCount
;
#endif
Datum
pg_freespacemap
(
PG_FUNCTION_ARGS
);
/*
* Record structure holding the to be exposed free space data.
*/
typedef
struct
{
uint32
blockid
;
uint32
relfilenode
;
uint32
reltablespace
;
uint32
reldatabase
;
uint32
relblocknumber
;
uint32
blockfreebytes
;
}
FreeSpacePagesRec
;
/*
* Function context for data persisting over repeated calls.
*/
typedef
struct
{
AttInMetadata
*
attinmeta
;
FreeSpacePagesRec
*
record
;
char
*
values
[
NUM_FREESPACE_PAGES_ELEM
];
}
FreeSpacePagesContext
;
/*
* Function returning data from the Free Space Map (FSM).
*/
PG_FUNCTION_INFO_V1
(
pg_freespacemap
);
Datum
pg_freespacemap
(
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
())
{
uint32
i
;
uint32
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
);
/* Construct a tuple to return. */
tupledesc
=
CreateTemplateTupleDesc
(
NUM_FREESPACE_PAGES_ELEM
,
false
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
1
,
"blockid"
,
INT4OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
2
,
"relfilenode"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
3
,
"reltablespace"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
4
,
"reldatabase"
,
OIDOID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
5
,
"relblocknumber"
,
INT8OID
,
-
1
,
0
);
TupleDescInitEntry
(
tupledesc
,
(
AttrNumber
)
6
,
"blockfreebytes"
,
INT4OID
,
-
1
,
0
);
/* Generate attribute metadata needed later to produce tuples */
funcctx
->
attinmeta
=
TupleDescGetAttInMetadata
(
tupledesc
);
/*
* Create a function context for cross-call persistence and initialize
* the counters.
*/
fctx
=
(
FreeSpacePagesContext
*
)
palloc
(
sizeof
(
FreeSpacePagesContext
));
funcctx
->
user_fctx
=
fctx
;
/* Set an upper bound on the calls */
funcctx
->
max_calls
=
numPages
;
/* Allocate numPages worth of FreeSpacePagesRec records, this is also
* an upper bound.
*/
fctx
->
record
=
(
FreeSpacePagesRec
*
)
palloc
(
sizeof
(
FreeSpacePagesRec
)
*
numPages
);
/* allocate the strings for tuple formation */
fctx
->
values
[
0
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
fctx
->
values
[
1
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
fctx
->
values
[
2
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
fctx
->
values
[
3
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
fctx
->
values
[
4
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
fctx
->
values
[
5
]
=
(
char
*
)
palloc
(
3
*
sizeof
(
uint32
)
+
1
);
/* 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
].
blockid
=
i
;
fctx
->
record
[
i
].
relfilenode
=
fsmrel
->
key
.
relNode
;
fctx
->
record
[
i
].
reltablespace
=
fsmrel
->
key
.
spcNode
;
fctx
->
record
[
i
].
reldatabase
=
fsmrel
->
key
.
dbNode
;
fctx
->
record
[
i
].
relblocknumber
=
IndexFSMPageGetPageNum
(
page
);
fctx
->
record
[
i
].
blockfreebytes
=
0
;
/* index.*/
page
++
;
i
++
;
}
}
else
{
/* Heap relation. */
FSMPageData
*
page
;
page
=
(
FSMPageData
*
)
(
FreeSpaceMap
->
arena
+
fsmrel
->
firstChunk
*
CHUNKBYTES
);
for
(
nPages
=
0
;
nPages
<
fsmrel
->
storedPages
;
nPages
++
)
{
fctx
->
record
[
i
].
blockid
=
i
;
fctx
->
record
[
i
].
relfilenode
=
fsmrel
->
key
.
relNode
;
fctx
->
record
[
i
].
reltablespace
=
fsmrel
->
key
.
spcNode
;
fctx
->
record
[
i
].
reldatabase
=
fsmrel
->
key
.
dbNode
;
fctx
->
record
[
i
].
relblocknumber
=
FSMPageGetPageNum
(
page
);
fctx
->
record
[
i
].
blockfreebytes
=
FSMPageGetSpace
(
page
);
page
++
;
i
++
;
}
}
}
/* Set the real no. of calls as we know it now! */
funcctx
->
max_calls
=
i
;
/* Release free space map. */
LWLockRelease
(
FreeSpaceLock
);
}
funcctx
=
SRF_PERCALL_SETUP
();
/* Get the saved state */
fctx
=
funcctx
->
user_fctx
;
if
(
funcctx
->
call_cntr
<
funcctx
->
max_calls
)
{
uint32
i
=
funcctx
->
call_cntr
;
sprintf
(
fctx
->
values
[
0
],
"%u"
,
fctx
->
record
[
i
].
blockid
);
sprintf
(
fctx
->
values
[
1
],
"%u"
,
fctx
->
record
[
i
].
relfilenode
);
sprintf
(
fctx
->
values
[
2
],
"%u"
,
fctx
->
record
[
i
].
reltablespace
);
sprintf
(
fctx
->
values
[
3
],
"%u"
,
fctx
->
record
[
i
].
reldatabase
);
sprintf
(
fctx
->
values
[
4
],
"%u"
,
fctx
->
record
[
i
].
relblocknumber
);
sprintf
(
fctx
->
values
[
5
],
"%u"
,
fctx
->
record
[
i
].
blockfreebytes
);
/* Build and return the tuple. */
tuple
=
BuildTupleFromCStrings
(
funcctx
->
attinmeta
,
fctx
->
values
);
result
=
HeapTupleGetDatum
(
tuple
);
SRF_RETURN_NEXT
(
funcctx
,
result
);
}
else
SRF_RETURN_DONE
(
funcctx
);
}
contrib/pg_freespacemap/pg_freespacemap.sql.in
0 → 100644
View file @
d5dd3d45
-- Adjust this setting to control where the objects get created.
BEGIN;
SET search_path = public;
-- Register the function.
CREATE OR REPLACE FUNCTION pg_freespacemap()
RETURNS SETOF RECORD
AS 'MODULE_PATHNAME', 'pg_freespacemap'
LANGUAGE 'C';
-- Create a view for convenient access.
CREATE VIEW pg_freespacemap AS
SELECT P.* FROM pg_freespacemap() AS P
(blockid int4, relfilenode oid, reltablespace oid, reldatabase oid, relblocknumber int8, blockfreebytes int4);
-- Don't want these to be available at public.
REVOKE ALL ON FUNCTION pg_freespacemap() FROM PUBLIC;
REVOKE ALL ON pg_freespacemap FROM PUBLIC;
COMMIT;
src/backend/storage/freespace/freespace.c
View file @
d5dd3d45
...
...
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.5
0 2005/10/29 00:31:51 petere
Exp $
* $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.5
1 2006/02/12 03:55:53 momjian
Exp $
*
*
* NOTES:
...
...
@@ -71,44 +71,6 @@
#include "storage/shmem.h"
/* Initial value for average-request moving average */
#define INITIAL_AVERAGE ((Size) (BLCKSZ / 32))
/*
* Number of pages and bytes per allocation chunk. Indexes can squeeze 50%
* more pages into the same space because they don't need to remember how much
* free space on each page. The nominal number of pages, CHUNKPAGES, is for
* regular rels, and INDEXCHUNKPAGES is for indexes. CHUNKPAGES should be
* even so that no space is wasted in the index case.
*/
#define CHUNKPAGES 16
#define CHUNKBYTES (CHUNKPAGES * sizeof(FSMPageData))
#define INDEXCHUNKPAGES ((int) (CHUNKBYTES / sizeof(IndexFSMPageData)))
/*
* Typedefs and macros for items in the page-storage arena. We use the
* existing ItemPointer and BlockId data structures, which are designed
* to pack well (they should be 6 and 4 bytes apiece regardless of machine
* alignment issues). Unfortunately we can't use the ItemPointer access
* macros, because they include Asserts insisting that ip_posid != 0.
*/
typedef
ItemPointerData
FSMPageData
;
typedef
BlockIdData
IndexFSMPageData
;
#define FSMPageGetPageNum(ptr) \
BlockIdGetBlockNumber(&(ptr)->ip_blkid)
#define FSMPageGetSpace(ptr) \
((Size) (ptr)->ip_posid)
#define FSMPageSetPageNum(ptr, pg) \
BlockIdSet(&(ptr)->ip_blkid, pg)
#define FSMPageSetSpace(ptr, sz) \
((ptr)->ip_posid = (OffsetNumber) (sz))
#define IndexFSMPageGetPageNum(ptr) \
BlockIdGetBlockNumber(ptr)
#define IndexFSMPageSetPageNum(ptr, pg) \
BlockIdSet(ptr, pg)
/*----------
* During database shutdown, we store the contents of FSM into a disk file,
* which is re-read during startup. This way we don't have a startup
...
...
@@ -156,63 +118,6 @@ typedef struct FsmCacheRelHeader
int32
storedPages
;
/* # of pages stored in arena */
}
FsmCacheRelHeader
;
/*
* Shared free-space-map objects
*
* The per-relation objects are indexed by a hash table, and are also members
* of two linked lists: one ordered by recency of usage (most recent first),
* and the other ordered by physical location of the associated storage in
* the page-info arena.
*
* Each relation owns one or more chunks of per-page storage in the "arena".
* The chunks for each relation are always consecutive, so that it can treat
* its page storage as a simple array. We further insist that its page data
* be ordered by block number, so that binary search is possible.
*
* Note: we handle pointers to these items as pointers, not as SHMEM_OFFSETs.
* This assumes that all processes accessing the map will have the shared
* memory segment mapped at the same place in their address space.
*/
typedef
struct
FSMHeader
FSMHeader
;
typedef
struct
FSMRelation
FSMRelation
;
/* Header for whole map */
struct
FSMHeader
{
FSMRelation
*
usageList
;
/* FSMRelations in usage-recency order */
FSMRelation
*
usageListTail
;
/* tail of usage-recency list */
FSMRelation
*
firstRel
;
/* FSMRelations in arena storage order */
FSMRelation
*
lastRel
;
/* tail of storage-order list */
int
numRels
;
/* number of FSMRelations now in use */
double
sumRequests
;
/* sum of requested chunks over all rels */
char
*
arena
;
/* arena for page-info storage */
int
totalChunks
;
/* total size of arena, in chunks */
int
usedChunks
;
/* # of chunks assigned */
/* NB: there are totalChunks - usedChunks free chunks at end of arena */
};
/*
* Per-relation struct --- this is an entry in the shared hash table.
* The hash key is the RelFileNode value (hence, we look at the physical
* relation ID, not the logical ID, which is appropriate).
*/
struct
FSMRelation
{
RelFileNode
key
;
/* hash key (must be first) */
FSMRelation
*
nextUsage
;
/* next rel in usage-recency order */
FSMRelation
*
priorUsage
;
/* prior rel in usage-recency order */
FSMRelation
*
nextPhysical
;
/* next rel in arena-storage order */
FSMRelation
*
priorPhysical
;
/* prior rel in arena-storage order */
bool
isIndex
;
/* if true, we store only page numbers */
Size
avgRequest
;
/* moving average of space requests */
int
lastPageCount
;
/* pages passed to RecordRelationFreeSpace */
int
firstChunk
;
/* chunk # of my first chunk in arena */
int
storedPages
;
/* # of pages stored in arena */
int
nextPage
;
/* index (from 0) to start next search at */
};
int
MaxFSMRelations
;
/* these are set by guc.c */
int
MaxFSMPages
;
...
...
@@ -1838,6 +1743,17 @@ fsm_current_allocation(FSMRelation *fsmrel)
}
/*
* Return the FreeSpaceMap structure for examination.
*/
FSMHeader
*
GetFreeSpaceMap
(
void
)
{
return
FreeSpaceMap
;
}
#ifdef FREESPACE_DEBUG
/*
* Dump contents of freespace map for debugging.
...
...
src/include/storage/freespace.h
View file @
d5dd3d45
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/freespace.h,v 1.1
8 2005/08/20 23:26:33 tgl
Exp $
* $PostgreSQL: pgsql/src/include/storage/freespace.h,v 1.1
9 2006/02/12 03:55:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -16,6 +16,7 @@
#include "storage/block.h"
#include "storage/relfilenode.h"
#include "storage/itemptr.h"
/*
...
...
@@ -28,6 +29,101 @@ typedef struct PageFreeSpaceInfo
}
PageFreeSpaceInfo
;
/* Initial value for average-request moving average */
#define INITIAL_AVERAGE ((Size) (BLCKSZ / 32))
/*
* Number of pages and bytes per allocation chunk. Indexes can squeeze 50%
* more pages into the same space because they don't need to remember how much
* free space on each page. The nominal number of pages, CHUNKPAGES, is for
* regular rels, and INDEXCHUNKPAGES is for indexes. CHUNKPAGES should be
* even so that no space is wasted in the index case.
*/
#define CHUNKPAGES 16
#define CHUNKBYTES (CHUNKPAGES * sizeof(FSMPageData))
#define INDEXCHUNKPAGES ((int) (CHUNKBYTES / sizeof(IndexFSMPageData)))
/*
* Typedefs and macros for items in the page-storage arena. We use the
* existing ItemPointer and BlockId data structures, which are designed
* to pack well (they should be 6 and 4 bytes apiece regardless of machine
* alignment issues). Unfortunately we can't use the ItemPointer access
* macros, because they include Asserts insisting that ip_posid != 0.
*/
typedef
ItemPointerData
FSMPageData
;
typedef
BlockIdData
IndexFSMPageData
;
#define FSMPageGetPageNum(ptr) \
BlockIdGetBlockNumber(&(ptr)->ip_blkid)
#define FSMPageGetSpace(ptr) \
((Size) (ptr)->ip_posid)
#define FSMPageSetPageNum(ptr, pg) \
BlockIdSet(&(ptr)->ip_blkid, pg)
#define FSMPageSetSpace(ptr, sz) \
((ptr)->ip_posid = (OffsetNumber) (sz))
#define IndexFSMPageGetPageNum(ptr) \
BlockIdGetBlockNumber(ptr)
#define IndexFSMPageSetPageNum(ptr, pg) \
BlockIdSet(ptr, pg)
/*
* Shared free-space-map objects
*
* The per-relation objects are indexed by a hash table, and are also members
* of two linked lists: one ordered by recency of usage (most recent first),
* and the other ordered by physical location of the associated storage in
* the page-info arena.
*
* Each relation owns one or more chunks of per-page storage in the "arena".
* The chunks for each relation are always consecutive, so that it can treat
* its page storage as a simple array. We further insist that its page data
* be ordered by block number, so that binary search is possible.
*
* Note: we handle pointers to these items as pointers, not as SHMEM_OFFSETs.
* This assumes that all processes accessing the map will have the shared
* memory segment mapped at the same place in their address space.
*/
typedef
struct
FSMHeader
FSMHeader
;
typedef
struct
FSMRelation
FSMRelation
;
/* Header for whole map */
struct
FSMHeader
{
FSMRelation
*
usageList
;
/* FSMRelations in usage-recency order */
FSMRelation
*
usageListTail
;
/* tail of usage-recency list */
FSMRelation
*
firstRel
;
/* FSMRelations in arena storage order */
FSMRelation
*
lastRel
;
/* tail of storage-order list */
int
numRels
;
/* number of FSMRelations now in use */
double
sumRequests
;
/* sum of requested chunks over all rels */
char
*
arena
;
/* arena for page-info storage */
int
totalChunks
;
/* total size of arena, in chunks */
int
usedChunks
;
/* # of chunks assigned */
/* NB: there are totalChunks - usedChunks free chunks at end of arena */
};
/*
* Per-relation struct --- this is an entry in the shared hash table.
* The hash key is the RelFileNode value (hence, we look at the physical
* relation ID, not the logical ID, which is appropriate).
*/
struct
FSMRelation
{
RelFileNode
key
;
/* hash key (must be first) */
FSMRelation
*
nextUsage
;
/* next rel in usage-recency order */
FSMRelation
*
priorUsage
;
/* prior rel in usage-recency order */
FSMRelation
*
nextPhysical
;
/* next rel in arena-storage order */
FSMRelation
*
priorPhysical
;
/* prior rel in arena-storage order */
bool
isIndex
;
/* if true, we store only page numbers */
Size
avgRequest
;
/* moving average of space requests */
int
lastPageCount
;
/* pages passed to RecordRelationFreeSpace */
int
firstChunk
;
/* chunk # of my first chunk in arena */
int
storedPages
;
/* # of pages stored in arena */
int
nextPage
;
/* index (from 0) to start next search at */
};
/* GUC variables */
extern
int
MaxFSMRelations
;
extern
int
MaxFSMPages
;
...
...
@@ -62,6 +158,7 @@ extern void PrintFreeSpaceMapStatistics(int elevel);
extern
void
DumpFreeSpaceMap
(
int
code
,
Datum
arg
);
extern
void
LoadFreeSpaceMap
(
void
);
extern
FSMHeader
*
GetFreeSpaceMap
(
void
);
#ifdef FREESPACE_DEBUG
extern
void
DumpFreeSpace
(
void
);
...
...
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