mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Rewrite the FSM. Instead of relying on a fixed-size shared memory segment, the
free space information is stored in a dedicated FSM relation fork, with each relation (except for hash indexes; they don't use FSM). This eliminates the max_fsm_relations and max_fsm_pages GUC options; remove any trace of them from the backend, initdb, and documentation. Rewrite contrib/pg_freespacemap to match the new FSM implementation. Also introduce a new variant of the get_raw_page(regclass, int4, int4) function in contrib/pageinspect that let's you to return pages from any relation fork, and a new fsm_page_contents() function to inspect the new FSM pages.
This commit is contained in:
@ -2,12 +2,12 @@
|
||||
#
|
||||
# pageinspect Makefile
|
||||
#
|
||||
# $PostgreSQL: pgsql/contrib/pageinspect/Makefile,v 1.3 2007/11/10 23:59:51 momjian Exp $
|
||||
# $PostgreSQL: pgsql/contrib/pageinspect/Makefile,v 1.4 2008/09/30 10:52:09 heikki Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
MODULE_big = pageinspect
|
||||
OBJS = rawpage.o heapfuncs.o btreefuncs.o
|
||||
OBJS = rawpage.o heapfuncs.o btreefuncs.o fsmfuncs.o
|
||||
DATA_built = pageinspect.sql
|
||||
DATA = uninstall_pageinspect.sql
|
||||
|
||||
|
61
contrib/pageinspect/fsmfuncs.c
Normal file
61
contrib/pageinspect/fsmfuncs.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* fsmfuncs.c
|
||||
* Functions to investigate FSM pages
|
||||
*
|
||||
* These functions are restricted to superusers for the fear of introducing
|
||||
* security holes if the input checking isn't as water-tight as it should.
|
||||
* You'd need to be superuser to obtain a raw page image anyway, so
|
||||
* there's hardly any use case for using these without superuser-rights
|
||||
* anyway.
|
||||
*
|
||||
* Copyright (c) 2007-2008, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/pageinspect/fsmfuncs.c,v 1.1 2008/09/30 10:52:09 heikki Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
#include "lib/stringinfo.h"
|
||||
#include "storage/fsm_internals.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "miscadmin.h"
|
||||
#include "funcapi.h"
|
||||
|
||||
Datum fsm_page_contents(PG_FUNCTION_ARGS);
|
||||
|
||||
/*
|
||||
* Dumps the contents of a FSM page.
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(fsm_page_contents);
|
||||
|
||||
Datum
|
||||
fsm_page_contents(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bytea *raw_page = PG_GETARG_BYTEA_P(0);
|
||||
int raw_page_size;
|
||||
StringInfoData sinfo;
|
||||
FSMPage fsmpage;
|
||||
int i;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to use raw page functions"))));
|
||||
|
||||
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
|
||||
fsmpage = (FSMPage) PageGetContents(VARDATA(raw_page));
|
||||
|
||||
initStringInfo(&sinfo);
|
||||
|
||||
for(i=0; i < NodesPerPage; i++)
|
||||
{
|
||||
if (fsmpage->fp_nodes[i] != 0)
|
||||
appendStringInfo(&sinfo, "%d: %d\n", i, fsmpage->fp_nodes[i]);
|
||||
}
|
||||
appendStringInfo(&sinfo, "fp_next_slot: %d\n", fsmpage->fp_next_slot);
|
||||
|
||||
PG_RETURN_TEXT_P(cstring_to_text(sinfo.data));
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.5 2008/09/30 10:52:09 heikki Exp $ */
|
||||
|
||||
-- Adjust this setting to control where the objects get created.
|
||||
SET search_path = public;
|
||||
@ -6,11 +6,16 @@ SET search_path = public;
|
||||
--
|
||||
-- get_raw_page()
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
|
||||
CREATE OR REPLACE FUNCTION get_raw_page(text, int4, int4)
|
||||
RETURNS bytea
|
||||
AS 'MODULE_PATHNAME', 'get_raw_page'
|
||||
LANGUAGE C STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
|
||||
RETURNS bytea
|
||||
AS $$ SELECT get_raw_page($1, 0, $2); $$
|
||||
LANGUAGE SQL STRICT;
|
||||
|
||||
--
|
||||
-- page_header()
|
||||
--
|
||||
@ -92,3 +97,11 @@ CREATE OR REPLACE FUNCTION bt_page_items(IN relname text, IN blkno int4,
|
||||
RETURNS SETOF record
|
||||
AS 'MODULE_PATHNAME', 'bt_page_items'
|
||||
LANGUAGE C STRICT;
|
||||
|
||||
--
|
||||
-- fsm_page_contents()
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION fsm_page_contents(IN page bytea)
|
||||
RETURNS text
|
||||
AS 'MODULE_PATHNAME', 'fsm_page_contents'
|
||||
LANGUAGE C STRICT;
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Copyright (c) 2007-2008, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.6 2008/05/12 00:00:43 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.7 2008/09/30 10:52:09 heikki Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -41,7 +41,8 @@ Datum
|
||||
get_raw_page(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *relname = PG_GETARG_TEXT_P(0);
|
||||
uint32 blkno = PG_GETARG_UINT32(1);
|
||||
uint32 forknum = PG_GETARG_UINT32(1);
|
||||
uint32 blkno = PG_GETARG_UINT32(2);
|
||||
|
||||
Relation rel;
|
||||
RangeVar *relrv;
|
||||
@ -54,6 +55,11 @@ get_raw_page(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to use raw functions"))));
|
||||
|
||||
if (forknum > MAX_FORKNUM)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("invalid fork number")));
|
||||
|
||||
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
|
||||
rel = relation_openrv(relrv, AccessShareLock);
|
||||
|
||||
@ -80,7 +86,7 @@ get_raw_page(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Take a verbatim copy of the page */
|
||||
|
||||
buf = ReadBuffer(rel, blkno);
|
||||
buf = ReadBufferWithFork(rel, forknum, blkno);
|
||||
LockBuffer(buf, BUFFER_LOCK_SHARE);
|
||||
|
||||
memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ);
|
||||
|
@ -1,44 +1,26 @@
|
||||
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.sql.in,v 1.8 2007/11/13 04:24:28 momjian Exp $ */
|
||||
/* $PostgreSQL: pgsql/contrib/pg_freespacemap/pg_freespacemap.sql.in,v 1.9 2008/09/30 10:52:09 heikki Exp $ */
|
||||
|
||||
-- Adjust this setting to control where the objects get created.
|
||||
SET search_path = public;
|
||||
|
||||
|
||||
-- Register the functions.
|
||||
CREATE OR REPLACE FUNCTION pg_freespacemap_pages()
|
||||
RETURNS SETOF RECORD
|
||||
AS 'MODULE_PATHNAME', 'pg_freespacemap_pages'
|
||||
-- Register the C function.
|
||||
CREATE OR REPLACE FUNCTION pg_freespace(regclass, int4)
|
||||
RETURNS int2
|
||||
AS 'MODULE_PATHNAME', 'pg_freespace'
|
||||
LANGUAGE C;
|
||||
|
||||
CREATE OR REPLACE FUNCTION pg_freespacemap_relations()
|
||||
-- pg_freespace shows the recorded space avail at each block in a relation
|
||||
CREATE OR REPLACE FUNCTION
|
||||
pg_freespace(rel regclass, blkno OUT int4, avail OUT int2)
|
||||
RETURNS SETOF RECORD
|
||||
AS 'MODULE_PATHNAME', 'pg_freespacemap_relations'
|
||||
LANGUAGE C;
|
||||
AS $$
|
||||
SELECT blkno::int4, pg_freespace($1, blkno::int4) AS avail
|
||||
FROM generate_series(0, pg_relation_size($1) / current_setting('block_size')::bigint - 1) AS blkno;
|
||||
$$
|
||||
LANGUAGE SQL;
|
||||
|
||||
|
||||
-- Create views for convenient access.
|
||||
CREATE VIEW pg_freespacemap_pages AS
|
||||
SELECT P.* FROM pg_freespacemap_pages() AS P
|
||||
(reltablespace oid,
|
||||
reldatabase oid,
|
||||
relfilenode oid,
|
||||
relblocknumber bigint,
|
||||
bytes integer);
|
||||
|
||||
CREATE VIEW pg_freespacemap_relations AS
|
||||
SELECT P.* FROM pg_freespacemap_relations() AS P
|
||||
(reltablespace oid,
|
||||
reldatabase oid,
|
||||
relfilenode oid,
|
||||
avgrequest integer,
|
||||
interestingpages integer,
|
||||
storedpages integer,
|
||||
nextpage integer);
|
||||
|
||||
|
||||
-- Don't want these to be available to public.
|
||||
REVOKE ALL ON FUNCTION pg_freespacemap_pages() FROM PUBLIC;
|
||||
REVOKE ALL ON pg_freespacemap_pages FROM PUBLIC;
|
||||
|
||||
REVOKE ALL ON FUNCTION pg_freespacemap_relations() FROM PUBLIC;
|
||||
REVOKE ALL ON pg_freespacemap_relations FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_freespace(regclass, int4) FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION pg_freespace(regclass) FROM PUBLIC;
|
||||
|
Reference in New Issue
Block a user