summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorHeikki Linnakangas2008-09-30 10:52:14 +0000
committerHeikki Linnakangas2008-09-30 10:52:14 +0000
commit15c121b3ed7eb2f290e19533e41ccca734d23574 (patch)
treeb60226d720f87b82b5b44647e3d3031081cdfb07 /contrib
parent2dbc0ca937f8ba9c76866a99fd04866232acea95 (diff)
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.
Diffstat (limited to 'contrib')
-rw-r--r--contrib/pageinspect/Makefile4
-rw-r--r--contrib/pageinspect/fsmfuncs.c61
-rw-r--r--contrib/pageinspect/pageinspect.sql.in17
-rw-r--r--contrib/pageinspect/rawpage.c12
-rw-r--r--contrib/pg_freespacemap/pg_freespacemap.sql.in48
5 files changed, 102 insertions, 40 deletions
diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile
index 63da705215d..3a6b729c174 100644
--- a/contrib/pageinspect/Makefile
+++ b/contrib/pageinspect/Makefile
@@ -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
diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c
new file mode 100644
index 00000000000..fb522e5ff5f
--- /dev/null
+++ b/contrib/pageinspect/fsmfuncs.c
@@ -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));
+}
diff --git a/contrib/pageinspect/pageinspect.sql.in b/contrib/pageinspect/pageinspect.sql.in
index 1af59f70f46..49fea9eb51f 100644
--- a/contrib/pageinspect/pageinspect.sql.in
+++ b/contrib/pageinspect/pageinspect.sql.in
@@ -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;
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index 0bc6bdc0174..51c6ee179f4 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -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);
diff --git a/contrib/pg_freespacemap/pg_freespacemap.sql.in b/contrib/pg_freespacemap/pg_freespacemap.sql.in
index e950d9a1128..0ab5e1d1eae 100644
--- a/contrib/pg_freespacemap/pg_freespacemap.sql.in
+++ b/contrib/pg_freespacemap/pg_freespacemap.sql.in
@@ -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;