Commit b9b8831a authored by Tom Lane's avatar Tom Lane

Create a "relation mapping" infrastructure to support changing the relfilenodes

of shared or nailed system catalogs.  This has two key benefits:

* The new CLUSTER-based VACUUM FULL can be applied safely to all catalogs.

* We no longer have to use an unsafe reindex-in-place approach for reindexing
  shared catalogs.

CLUSTER on nailed catalogs now works too, although I left it disabled on
shared catalogs because the resulting pg_index.indisclustered update would
only be visible in one database.

Since reindexing shared system catalogs is now fully transactional and
crash-safe, the former special cases in REINDEX behavior have been removed;
shared catalogs are treated the same as non-shared.

This commit does not do anything about the recently-discussed problem of
deadlocks between VACUUM FULL/CLUSTER on a system catalog and other
concurrent queries; will address that in a separate patch.  As a stopgap,
parallel_schedule has been tweaked to run vacuum.sql by itself, to avoid
such failures during the regression tests.
parent 7fc30c48
No related merge requests found
......@@ -5,7 +5,7 @@
* Originally by
* B. Palmer, bpalmer@crimelabs.net 1-17-2001
*
* $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.36 2009/06/11 14:48:51 momjian Exp $
* $PostgreSQL: pgsql/contrib/oid2name/oid2name.c,v 1.37 2010/02/07 20:48:08 tgl Exp $
*/
#include "postgres_fe.h"
......@@ -440,7 +440,7 @@ sql_exec_dumpalldbs(PGconn *conn, struct options * opts)
/* get the oid and database name from the system pg_database table */
snprintf(todo, sizeof(todo),
"SELECT d.oid AS \"Oid\", datname AS \"Database Name\", "
"spcname AS \"Tablespace\" FROM pg_database d JOIN pg_tablespace t ON "
"spcname AS \"Tablespace\" FROM pg_catalog.pg_database d JOIN pg_catalog.pg_tablespace t ON "
"(dattablespace = t.oid) ORDER BY 2");
sql_exec(conn, todo, opts->quiet);
......@@ -456,10 +456,10 @@ sql_exec_dumpalltables(PGconn *conn, struct options * opts)
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
snprintf(todo, sizeof(todo),
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s "
"SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s "
"FROM pg_class c "
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace "
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),"
" LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),"
" pg_catalog.pg_tablespace t "
"WHERE relkind IN ('r'%s%s) AND "
" %s"
......@@ -477,7 +477,7 @@ sql_exec_dumpalltables(PGconn *conn, struct options * opts)
}
/*
* Show oid, relfilenode, name, schema and tablespace for each of the
* Show oid, filenode, name, schema and tablespace for each of the
* given objects in the current database.
*/
void
......@@ -492,7 +492,7 @@ sql_exec_searchtables(PGconn *conn, struct options * opts)
bool written = false;
char *addfields = ",c.oid AS \"Oid\", nspname AS \"Schema\", spcname as \"Tablespace\" ";
/* get tables qualifiers, whether names, relfilenodes, or OIDs */
/* get tables qualifiers, whether names, filenodes, or OIDs */
comma_oids = get_comma_elts(opts->oids);
comma_tables = get_comma_elts(opts->tables);
comma_filenodes = get_comma_elts(opts->filenodes);
......@@ -511,7 +511,7 @@ sql_exec_searchtables(PGconn *conn, struct options * opts)
{
if (written)
ptr += sprintf(ptr, " OR ");
ptr += sprintf(ptr, "c.relfilenode IN (%s)", comma_filenodes);
ptr += sprintf(ptr, "pg_catalog.pg_relation_filenode(c.oid) IN (%s)", comma_filenodes);
written = true;
}
if (opts->tables->num > 0)
......@@ -527,10 +527,10 @@ sql_exec_searchtables(PGconn *conn, struct options * opts)
/* now build the query */
todo = (char *) myalloc(650 + strlen(qualifiers));
snprintf(todo, 650 + strlen(qualifiers),
"SELECT relfilenode as \"Filenode\", relname as \"Table Name\" %s\n"
"FROM pg_class c \n"
"SELECT pg_catalog.pg_relation_filenode(c.oid) as \"Filenode\", relname as \"Table Name\" %s\n"
"FROM pg_catalog.pg_class c \n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n"
" LEFT JOIN pg_catalog.pg_database d ON d.datname = current_database(),\n"
" LEFT JOIN pg_catalog.pg_database d ON d.datname = pg_catalog.current_database(),\n"
" pg_catalog.pg_tablespace t \n"
"WHERE relkind IN ('r', 'i', 'S', 't') AND \n"
" t.oid = CASE\n"
......@@ -554,7 +554,7 @@ sql_exec_dumpalltbspc(PGconn *conn, struct options * opts)
snprintf(todo, sizeof(todo),
"SELECT oid AS \"Oid\", spcname as \"Tablespace Name\"\n"
"FROM pg_tablespace");
"FROM pg_catalog.pg_tablespace");
sql_exec(conn, todo, opts->quiet);
}
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.220 2010/02/03 17:25:05 momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.221 2010/02/07 20:48:09 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
......@@ -1473,7 +1473,9 @@
<entry><structfield>relfilenode</structfield></entry>
<entry><type>oid</type></entry>
<entry></entry>
<entry>Name of the on-disk file of this relation; 0 if none</entry>
<entry>Name of the on-disk file of this relation; zero means this
is a <quote>mapped</> relation whose disk file name is determined
by low-level state</entry>
</row>
<row>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/diskusage.sgml,v 1.19 2010/02/03 17:25:05 momjian Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/diskusage.sgml,v 1.20 2010/02/07 20:48:09 tgl Exp $ -->
<chapter id="diskusage">
<title>Monitoring Disk Usage</title>
......@@ -29,30 +29,31 @@
</para>
<para>
You can monitor disk space three ways: using
SQL functions listed in <xref linkend="functions-admin-dbsize">,
using <command>VACUUM</> information, and from the command line
using the tools in <filename>contrib/oid2name</>. The SQL functions
are the easiest to use and report information about tables, tables with
indexes and long value storage (TOAST), databases, and tablespaces.
You can monitor disk space in three ways:
using the SQL functions listed in <xref linkend="functions-admin-dbsize">,
using the tools in <filename>contrib/oid2name</>, or
using manual inspection of the system catalogs.
The SQL functions are the easiest to use and are generally recommended.
<filename>contrib/oid2name</> is described in <xref linkend="oid2name">.
The remainder of this section shows how to do it by inspection of the
system catalogs.
</para>
<para>
Using <application>psql</> on a recently vacuumed or analyzed database,
you can issue queries to see the disk usage of any table:
<programlisting>
SELECT relfilenode, relpages FROM pg_class WHERE relname = 'customer';
SELECT pg_relation_filepath(oid), relpages FROM pg_class WHERE relname = 'customer';
relfilenode | relpages
-------------+----------
16806 | 60
pg_relation_filepath | relpages
----------------------+----------
base/16384/16806 | 60
(1 row)
</programlisting>
Each page is typically 8 kilobytes. (Remember, <structfield>relpages</>
is only updated by <command>VACUUM</>, <command>ANALYZE</>, and
a few DDL commands such as <command>CREATE INDEX</>.) The
<structfield>relfilenode</> value is of interest if you want to examine
the table's disk file directly.
a few DDL commands such as <command>CREATE INDEX</>.) The file pathname
is of interest if you want to examine the table's disk file directly.
</para>
<para>
......@@ -107,11 +108,6 @@ ORDER BY relpages DESC;
customer | 3144
</programlisting>
</para>
<para>
You can also use <filename>contrib/oid2name</> to show disk usage; see
<xref linkend="oid2name"> for more details and examples.
</para>
</sect1>
<sect1 id="disk-full">
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.500 2010/02/01 15:38:21 rhaas Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.501 2010/02/07 20:48:09 tgl Exp $ -->
<chapter id="functions">
<title>Functions and Operators</title>
......@@ -13434,6 +13434,68 @@ postgres=# SELECT * FROM pg_xlogfile_name_offset(pg_stop_backup());
appropriate.
</para>
<para>
The functions shown in <xref linkend="functions-admin-dblocation"> assist
in identifying the specific disk files associated with database objects.
</para>
<indexterm>
<primary>pg_relation_filenode</primary>
</indexterm>
<indexterm>
<primary>pg_relation_filepath</primary>
</indexterm>
<table id="functions-admin-dblocation">
<title>Database Object Location Functions</title>
<tgroup cols="3">
<thead>
<row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<literal><function>pg_relation_filenode</function>(<parameter>relation</parameter> <type>regclass</type>)</literal>
</entry>
<entry><type>oid</type></entry>
<entry>
Filenode number of the relation with the specified OID or name
</entry>
</row>
<row>
<entry>
<literal><function>pg_relation_filepath</function>(<parameter>relation</parameter> <type>regclass</type>)</literal>
</entry>
<entry><type>text</type></entry>
<entry>
File path name of the relation with the specified OID or name
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
<function>pg_relation_filenode</> accepts the OID or name of a table,
index, sequence, or toast table, and returns the <quote>filenode</> number
currently assigned to it. The filenode is the base component of the file
name(s) used for the relation (see <xref linkend="storage-file-layout">
for more information). For most tables the result is the same as
<structname>pg_class</>.<structfield>relfilenode</>, but for certain
system catalogs <structfield>relfilenode</> is zero and this function must
be used to get the correct value. The function returns NULL if passed
a relation that does not have storage, such as a view.
</para>
<para>
<function>pg_relation_filepath</> is similar to
<function>pg_relation_filenode</>, but it returns the entire file pathname
(relative to the database cluster's data directory <varname>PGDATA</>) of
the relation.
</para>
<para>
The functions shown in <xref
linkend="functions-admin-genfile"> provide native access to
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbuffercache.sgml,v 2.5 2009/05/18 11:08:24 petere Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/pgbuffercache.sgml,v 2.6 2010/02/07 20:48:09 tgl Exp $ -->
<sect1 id="pgbuffercache">
<title>pg_buffercache</title>
......@@ -56,7 +56,7 @@
<entry><structfield>relfilenode</structfield></entry>
<entry><type>oid</type></entry>
<entry><literal>pg_class.relfilenode</literal></entry>
<entry>Relfilenode of the relation</entry>
<entry>Filenode number of the relation</entry>
</row>
<row>
......@@ -137,7 +137,7 @@
<programlisting>
regression=# SELECT c.relname, count(*) AS buffers
FROM pg_buffercache b INNER JOIN pg_class c
ON b.relfilenode = c.relfilenode AND
ON b.relfilenode = pg_relation_filenode(c.oid) AND
b.reldatabase IN (0, (SELECT oid FROM pg_database
WHERE datname = current_database()))
GROUP BY c.relname
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/cluster.sgml,v 1.47 2009/09/19 10:23:26 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/cluster.sgml,v 1.48 2010/02/07 20:48:09 tgl Exp $
PostgreSQL documentation
-->
......@@ -30,12 +30,12 @@ CLUSTER [VERBOSE]
<title>Description</title>
<para>
<command>CLUSTER</command> instructs <productname>PostgreSQL</productname>
<command>CLUSTER</command> instructs <productname>PostgreSQL</productname>
to cluster the table specified
by <replaceable class="parameter">table_name</replaceable>
based on the index specified by
<replaceable class="parameter">index_name</replaceable>. The index must
already have been defined on
already have been defined on
<replaceable class="parameter">table_name</replaceable>.
</para>
......@@ -46,9 +46,9 @@ CLUSTER [VERBOSE]
not clustered. That is, no attempt is made to store new or
updated rows according to their index order. (If one wishes, one can
periodically recluster by issuing the command again. Also, setting
the table's <literal>FILLFACTOR</literal> storage parameter to less than 100% can aid
in preserving cluster ordering during updates, since updated rows
are preferentially kept on the same page.)
the table's <literal>FILLFACTOR</literal> storage parameter to less than
100% can aid in preserving cluster ordering during updates, since updated
rows are kept on the same page if enough space is available there.)
</para>
<para>
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/reindex.sgml,v 1.38 2008/11/14 10:22:47 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/reindex.sgml,v 1.39 2010/02/07 20:48:09 tgl Exp $
PostgreSQL documentation
-->
......@@ -77,7 +77,7 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
</itemizedlist>
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
......@@ -106,9 +106,9 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
<listitem>
<para>
Recreate all indexes within the current database.
Indexes on shared system catalogs are skipped except in stand-alone mode
(see below). This form of <command>REINDEX</command> cannot be executed
inside a transaction block.
Indexes on shared system catalogs are also processed.
This form of <command>REINDEX</command> cannot be executed inside a
transaction block.
</para>
</listitem>
</varlistentry>
......@@ -118,8 +118,8 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
<listitem>
<para>
Recreate all indexes on system catalogs within the current database.
Indexes on user tables are not processed. Also, indexes on shared
system catalogs are skipped except in stand-alone mode (see below).
Indexes on shared system catalogs are included.
Indexes on user tables are not processed.
This form of <command>REINDEX</command> cannot be executed inside a
transaction block.
</para>
......@@ -134,7 +134,7 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
reindexed. Index and table names can be schema-qualified.
Presently, <command>REINDEX DATABASE</> and <command>REINDEX SYSTEM</>
can only reindex the current database, so their parameter must match
the current database's name.
the current database's name.
</para>
</listitem>
</varlistentry>
......@@ -156,7 +156,7 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
<para>
If you suspect corruption of an index on a user table, you can
simply rebuild that index, or all indexes on the table, using
<command>REINDEX INDEX</command> or <command>REINDEX TABLE</command>.
<command>REINDEX INDEX</command> or <command>REINDEX TABLE</command>.
</para>
<para>
......@@ -197,30 +197,6 @@ REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">nam
have been completed.
</para>
<para>
If corruption is suspected in the indexes of any of the shared
system catalogs (which are <structname>pg_authid</structname>,
<structname>pg_auth_members</structname>,
<structname>pg_database</structname>,
<structname>pg_pltemplate</structname>,
<structname>pg_shdepend</structname>,
<structname>pg_shdescription</structname>, and
<structname>pg_tablespace</structname>), then a standalone server
must be used to repair it. <command>REINDEX</> will not process
shared catalogs in multiuser mode.
</para>
<para>
For all indexes except the shared system catalogs, <command>REINDEX</>
is crash-safe and transaction-safe. <command>REINDEX</> is not
crash-safe for shared indexes, which is why this case is disallowed
during normal operation. If a failure occurs while reindexing one
of these catalogs in standalone mode, it will not be possible to
restart the regular server until the problem is rectified. (The
typical symptom of a partially rebuilt shared index is <quote>index is not
a btree</> errors.)
</para>
<para>
<command>REINDEX</command> is similar to a drop and recreate of the index
in that the index contents are rebuilt from scratch. However, the locking
......@@ -290,7 +266,7 @@ broken_db=&gt; \q
</programlisting>
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
......
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.30 2009/07/22 01:21:22 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/storage.sgml,v 1.31 2010/02/07 20:48:09 tgl Exp $ -->
<chapter id="storage">
......@@ -147,6 +147,11 @@ Note that while a table's filenode often matches its OID, this is
<command>TRUNCATE</>, <command>REINDEX</>, <command>CLUSTER</> and some forms
of <command>ALTER TABLE</>, can change the filenode while preserving the OID.
Avoid assuming that filenode and table OID are the same.
Also, for certain system catalogs including <structname>pg_class</> itself,
<structname>pg_class</>.<structfield>relfilenode</> contains zero. The
actual filenode number of these catalogs is stored in a lower-level data
structure, and can be obtained using the <function>pg_relation_filenode()</>
function.
</para>
</caution>
......@@ -188,6 +193,16 @@ tablespace is not accessed through <filename>pg_tblspc</>, but corresponds to
<varname>PGDATA</><filename>/global</>.
</para>
<para>
The <function>pg_relation_filepath()</> function shows the entire path
(relative to <varname>PGDATA</>) of any relation. It is often useful
as a substitute for remembering many of the above rules. But keep in
mind that this function just gives the name of the first segment of the
main fork of the relation &mdash; you may need to append a segment number
and/or <literal>_fsm</> or <literal>_vm</> to find all the files associated
with the relation.
</para>
<para>
Temporary files (for operations such as sorting more data than can fit in
memory) are created within <varname>PGDATA</><filename>/base/pgsql_tmp</>,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.79 2010/01/02 16:57:35 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.80 2010/02/07 20:48:09 tgl Exp $
*
* NOTES
* many of the old access method routines have been turned into
......@@ -21,6 +21,7 @@
#include "access/relscan.h"
#include "access/transam.h"
#include "catalog/index.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/bufmgr.h"
......@@ -419,7 +420,7 @@ systable_beginscan_ordered(Relation heapRelation,
/* REINDEX can probably be a hard error here ... */
if (ReindexIsProcessingIndex(RelationGetRelid(indexRelation)))
elog(ERROR, "cannot do ordered scan on index \"%s\", because it is the current REINDEX target",
elog(ERROR, "cannot do ordered scan on index \"%s\", because it is being reindexed",
RelationGetRelationName(indexRelation));
/* ... but we only throw a warning about violating IgnoreSystemIndexes */
if (IgnoreSystemIndexes)
......
......@@ -3,7 +3,7 @@
*
* Resource managers definition
*
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.28 2009/12/19 01:32:33 sriggs Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/rmgr.c,v 1.29 2010/02/07 20:48:09 tgl Exp $
*/
#include "postgres.h"
......@@ -22,6 +22,7 @@
#include "commands/tablespace.h"
#include "storage/freespace.h"
#include "storage/standby.h"
#include "utils/relmapper.h"
const RmgrData RmgrTable[RM_MAX_ID + 1] = {
......@@ -32,7 +33,7 @@ const RmgrData RmgrTable[RM_MAX_ID + 1] = {
{"Database", dbase_redo, dbase_desc, NULL, NULL, NULL},
{"Tablespace", tblspc_redo, tblspc_desc, NULL, NULL, NULL},
{"MultiXact", multixact_redo, multixact_desc, NULL, NULL, NULL},
{"Reserved 7", NULL, NULL, NULL, NULL, NULL},
{"RelMap", relmap_redo, relmap_desc, NULL, NULL, NULL},
{"Standby", standby_redo, standby_desc, NULL, NULL, NULL},
{"Heap2", heap2_redo, heap2_desc, NULL, NULL, NULL},
{"Heap", heap_redo, heap_desc, NULL, NULL, NULL},
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.282 2010/01/24 21:49:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.283 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -48,6 +48,7 @@
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/relcache.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "pg_trace.h"
......@@ -250,7 +251,7 @@ static void AbortTransaction(void);
static void AtAbort_Memory(void);
static void AtCleanup_Memory(void);
static void AtAbort_ResourceOwner(void);
static void AtCommit_LocalCache(void);
static void AtCCI_LocalCache(void);
static void AtCommit_Memory(void);
static void AtStart_Cache(void);
static void AtStart_Memory(void);
......@@ -703,7 +704,7 @@ CommandCounterIncrement(void)
* read-only command. (But see hacks in inval.c to make real sure we
* don't think a command that queued inval messages was read-only.)
*/
AtCommit_LocalCache();
AtCCI_LocalCache();
}
/*
......@@ -1095,11 +1096,19 @@ cleanup:
/*
* AtCommit_LocalCache
* AtCCI_LocalCache
*/
static void
AtCommit_LocalCache(void)
AtCCI_LocalCache(void)
{
/*
* Make any pending relation map changes visible. We must do this
* before processing local sinval messages, so that the map changes
* will get reflected into the relcache when relcache invals are
* processed.
*/
AtCCI_RelationMap();
/*
* Make catalog changes visible to me for the next command.
*/
......@@ -1734,6 +1743,9 @@ CommitTransaction(void)
/* Prevent cancel/die interrupt while cleaning up */
HOLD_INTERRUPTS();
/* Commit updates to the relation map --- do this as late as possible */
AtEOXact_RelationMap(true);
/*
* set the current transaction state information appropriately during
* commit processing
......@@ -1980,6 +1992,7 @@ PrepareTransaction(void)
AtPrepare_Locks();
AtPrepare_PgStat();
AtPrepare_MultiXact();
AtPrepare_RelationMap();
/*
* Here is where we really truly prepare.
......@@ -2148,10 +2161,11 @@ AbortTransaction(void)
/*
* do abort processing
*/
AfterTriggerEndXact(false);
AfterTriggerEndXact(false); /* 'false' means it's abort */
AtAbort_Portals();
AtEOXact_LargeObject(false); /* 'false' means it's abort */
AtEOXact_LargeObject(false);
AtAbort_Notify();
AtEOXact_RelationMap(false);
/*
* Advertise the fact that we aborted in pg_clog (assuming that we got as
......@@ -4625,11 +4639,18 @@ xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
SharedInvalidationMessage *msg = &msgs[i];
if (msg->id >= 0)
appendStringInfo(buf, "catcache id%d ", msg->id);
appendStringInfo(buf, " catcache %d", msg->id);
else if (msg->id == SHAREDINVALCATALOG_ID)
appendStringInfo(buf, " catalog %u", msg->cat.catId);
else if (msg->id == SHAREDINVALRELCACHE_ID)
appendStringInfo(buf, "relcache ");
appendStringInfo(buf, " relcache %u", msg->rc.relId);
/* remaining cases not expected, but print something anyway */
else if (msg->id == SHAREDINVALSMGR_ID)
appendStringInfo(buf, "smgr ");
appendStringInfo(buf, " smgr");
else if (msg->id == SHAREDINVALRELMAP_ID)
appendStringInfo(buf, " relmap");
else
appendStringInfo(buf, " unknown id %d", msg->id);
}
}
}
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.366 2010/02/01 13:40:28 sriggs Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.367 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,7 @@
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "pg_trace.h"
......@@ -7123,6 +7124,7 @@ CheckPointGuts(XLogRecPtr checkPointRedo, int flags)
CheckPointCLOG();
CheckPointSUBTRANS();
CheckPointMultiXact();
CheckPointRelationMap();
CheckPointBuffers(flags); /* performs all required fsyncs */
/* We deliberately delay 2PC checkpointing as long as possible */
CheckPointTwoPhase(checkPointRedo);
......
......@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.104 2010/01/28 23:21:11 petere Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.105 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -185,11 +185,26 @@ Boot_CreateStmt:
RPAREN
{
TupleDesc tupdesc;
bool shared_relation;
bool mapped_relation;
do_start();
tupdesc = CreateTupleDesc(numattr, !($6), attrtypes);
shared_relation = $5;
/*
* The catalogs that use the relation mapper are the
* bootstrap catalogs plus the shared catalogs. If this
* ever gets more complicated, we should invent a BKI
* keyword to mark the mapped catalogs, but for now a
* quick hack seems the most appropriate thing. Note in
* particular that all "nailed" heap rels (see formrdesc
* in relcache.c) must be mapped.
*/
mapped_relation = ($4 || shared_relation);
if ($4)
{
if (boot_reldesc)
......@@ -200,11 +215,12 @@ Boot_CreateStmt:
boot_reldesc = heap_create($2,
PG_CATALOG_NAMESPACE,
$5 ? GLOBALTABLESPACE_OID : 0,
shared_relation ? GLOBALTABLESPACE_OID : 0,
$3,
tupdesc,
RELKIND_RELATION,
$5,
shared_relation,
mapped_relation,
true);
elog(DEBUG4, "bootstrap relation created");
}
......@@ -214,7 +230,7 @@ Boot_CreateStmt:
id = heap_create_with_catalog($2,
PG_CATALOG_NAMESPACE,
$5 ? GLOBALTABLESPACE_OID : 0,
shared_relation ? GLOBALTABLESPACE_OID : 0,
$3,
$7,
InvalidOid,
......@@ -222,7 +238,8 @@ Boot_CreateStmt:
tupdesc,
NIL,
RELKIND_RELATION,
$5,
shared_relation,
mapped_relation,
true,
0,
ONCOMMIT_NOOP,
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.258 2010/01/22 16:40:18 rhaas Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.259 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -42,6 +42,7 @@
#include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/relmapper.h"
#include "utils/tqual.h"
extern int optind;
......@@ -491,6 +492,12 @@ BootstrapModeMain(void)
*/
boot_yyparse();
/*
* We should now know about all mapped relations, so it's okay to
* write out the initial relation mapping files.
*/
RelationMapFinishBootstrap();
/* Perform a checkpoint to ensure everything's down to disk */
SetProcessingMode(NormalProcessing);
CreateCheckPoint(CHECKPOINT_IS_SHUTDOWN | CHECKPOINT_IMMEDIATE);
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.87 2010/01/12 02:42:51 momjian Exp $
* $PostgreSQL: pgsql/src/backend/catalog/catalog.c,v 1.88 2010/02/07 20:48:09 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -460,16 +460,16 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
* created by bootstrap have preassigned OIDs, so there's no need.
*/
Oid
GetNewRelFileNode(Oid reltablespace, bool relisshared, Relation pg_class)
GetNewRelFileNode(Oid reltablespace, Relation pg_class)
{
RelFileNode rnode;
char *rpath;
int fd;
bool collides;
/* This should match RelationInitPhysicalAddr */
/* This logic should match RelationInitPhysicalAddr */
rnode.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
rnode.dbNode = relisshared ? InvalidOid : MyDatabaseId;
rnode.dbNode = (rnode.spcNode == GLOBALTABLESPACE_OID) ? InvalidOid : MyDatabaseId;
do
{
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.369 2010/02/03 01:14:16 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.370 2010/02/07 20:48:09 tgl Exp $
*
*
* INTERFACE ROUTINES
......@@ -237,6 +237,7 @@ heap_create(const char *relname,
TupleDesc tupDesc,
char relkind,
bool shared_relation,
bool mapped_relation,
bool allow_system_table_mods)
{
bool create_storage;
......@@ -307,7 +308,8 @@ heap_create(const char *relname,
tupDesc,
relid,
reltablespace,
shared_relation);
shared_relation,
mapped_relation);
/*
* Have the storage manager create the relation's disk file, if needed.
......@@ -364,7 +366,8 @@ heap_create(const char *relname,
* --------------------------------
*/
void
CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind)
CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
bool allow_system_table_mods)
{
int i;
int j;
......@@ -418,7 +421,8 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind)
for (i = 0; i < natts; i++)
{
CheckAttributeType(NameStr(tupdesc->attrs[i]->attname),
tupdesc->attrs[i]->atttypid);
tupdesc->attrs[i]->atttypid,
allow_system_table_mods);
}
}
......@@ -431,7 +435,8 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind)
* --------------------------------
*/
void
CheckAttributeType(const char *attname, Oid atttypid)
CheckAttributeType(const char *attname, Oid atttypid,
bool allow_system_table_mods)
{
char att_typtype = get_typtype(atttypid);
......@@ -450,9 +455,11 @@ CheckAttributeType(const char *attname, Oid atttypid)
{
/*
* Refuse any attempt to create a pseudo-type column, except for a
* special hack for pg_statistic: allow ANYARRAY during initdb
* special hack for pg_statistic: allow ANYARRAY when modifying
* system catalogs (this allows creating pg_statistic and cloning it
* during VACUUM FULL)
*/
if (atttypid != ANYARRAYOID || IsUnderPostmaster)
if (atttypid != ANYARRAYOID || !allow_system_table_mods)
ereport(ERROR,
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
errmsg("column \"%s\" has pseudo-type %s",
......@@ -479,7 +486,8 @@ CheckAttributeType(const char *attname, Oid atttypid)
if (attr->attisdropped)
continue;
CheckAttributeType(NameStr(attr->attname), attr->atttypid);
CheckAttributeType(NameStr(attr->attname), attr->atttypid,
allow_system_table_mods);
}
relation_close(relation, AccessShareLock);
......@@ -865,6 +873,7 @@ AddNewRelationType(const char *typeName,
* cooked_constraints: list of precooked check constraints and defaults
* relkind: relkind for new rel
* shared_relation: TRUE if it's to be a shared relation
* mapped_relation: TRUE if the relation will use the relfilenode map
* oidislocal: TRUE if oid column (if any) should be marked attislocal
* oidinhcount: attinhcount to assign to oid column (if any)
* oncommit: ON COMMIT marking (only relevant if it's a temp table)
......@@ -888,6 +897,7 @@ heap_create_with_catalog(const char *relname,
List *cooked_constraints,
char relkind,
bool shared_relation,
bool mapped_relation,
bool oidislocal,
int oidinhcount,
OnCommitAction oncommit,
......@@ -909,7 +919,7 @@ heap_create_with_catalog(const char *relname,
*/
Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());
CheckAttributeNamesTypes(tupdesc, relkind);
CheckAttributeNamesTypes(tupdesc, relkind, allow_system_table_mods);
if (get_relname_relid(relname, relnamespace))
ereport(ERROR,
......@@ -938,23 +948,10 @@ heap_create_with_catalog(const char *relname,
}
/*
* Validate shared/non-shared tablespace (must check this before doing
* GetNewRelFileNode, to prevent Assert therein)
* Shared relations must be in pg_global (last-ditch check)
*/
if (shared_relation)
{
if (reltablespace != GLOBALTABLESPACE_OID)
/* elog since this is not a user-facing error */
elog(ERROR,
"shared relations must be placed in pg_global tablespace");
}
else
{
if (reltablespace == GLOBALTABLESPACE_OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("only shared relations can be placed in pg_global tablespace")));
}
if (shared_relation && reltablespace != GLOBALTABLESPACE_OID)
elog(ERROR, "shared relations must be placed in pg_global tablespace");
/*
* Allocate an OID for the relation, unless we were told what to use.
......@@ -979,8 +976,7 @@ heap_create_with_catalog(const char *relname,
binary_upgrade_next_toast_relfilenode = InvalidOid;
}
else
relid = GetNewRelFileNode(reltablespace, shared_relation,
pg_class_desc);
relid = GetNewRelFileNode(reltablespace, pg_class_desc);
}
/*
......@@ -1019,6 +1015,7 @@ heap_create_with_catalog(const char *relname,
tupdesc,
relkind,
shared_relation,
mapped_relation,
allow_system_table_mods);
Assert(relid == RelationGetRelid(new_rel_desc));
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/storage.c,v 1.7 2010/01/02 16:57:36 momjian Exp $
* $PostgreSQL: pgsql/src/backend/catalog/storage.c,v 1.8 2010/02/07 20:48:09 tgl Exp $
*
* NOTES
* Some of this code used to be in storage/smgr/smgr.c, and the
......@@ -109,8 +109,7 @@ RelationCreateStorage(RelFileNode rnode, bool istemp)
if (!istemp)
{
/*
* Make an XLOG entry showing the file creation. If we abort, the
* file will be dropped at abort time.
* Make an XLOG entry reporting the file creation.
*/
xlrec.rnode = rnode;
......@@ -165,6 +164,52 @@ RelationDropStorage(Relation rel)
RelationCloseSmgr(rel);
}
/*
* RelationPreserveStorage
* Mark a relation as not to be deleted after all.
*
* We need this function because relation mapping changes are committed
* separately from commit of the whole transaction, so it's still possible
* for the transaction to abort after the mapping update is done.
* When a new physical relation is installed in the map, it would be
* scheduled for delete-on-abort, so we'd delete it, and be in trouble.
* The relation mapper fixes this by telling us to not delete such relations
* after all as part of its commit.
*
* No-op if the relation is not among those scheduled for deletion.
*/
void
RelationPreserveStorage(RelFileNode rnode)
{
PendingRelDelete *pending;
PendingRelDelete *prev;
PendingRelDelete *next;
prev = NULL;
for (pending = pendingDeletes; pending != NULL; pending = next)
{
next = pending->next;
if (RelFileNodeEquals(rnode, pending->relnode))
{
/* we should only find delete-on-abort entries, else trouble */
if (pending->atCommit)
elog(ERROR, "cannot preserve a delete-on-commit relation");
/* unlink and delete list entry */
if (prev)
prev->next = next;
else
pendingDeletes = next;
pfree(pending);
/* prev does not change */
}
else
{
/* unrelated entry, don't touch it */
prev = pending;
}
}
}
/*
* RelationTruncate
* Physically truncate a relation to the specified number of blocks.
......@@ -200,13 +245,13 @@ RelationTruncate(Relation rel, BlockNumber nblocks)
* likely isn't going to succeed in the truncation either, and cause a
* PANIC. It's tempting to put a critical section here, but that cure
* would be worse than the disease. It would turn a usually harmless
* failure to truncate, that could spell trouble at WAL replay, into a
* failure to truncate, that might spell trouble at WAL replay, into a
* certain PANIC.
*/
if (!rel->rd_istemp)
{
/*
* Make an XLOG entry showing the file truncation.
* Make an XLOG entry reporting the file truncation.
*/
XLogRecPtr lsn;
XLogRecData rdata;
......@@ -270,10 +315,8 @@ smgrDoPendingDeletes(bool isCommit)
/* do deletion if called for */
if (pending->atCommit == isCommit)
{
int i;
/* schedule unlinking old files */
SMgrRelation srel;
int i;
srel = smgropen(pending->relnode);
for (i = 0; i <= MAX_FORKNUM; i++)
......@@ -440,7 +483,6 @@ smgr_redo(XLogRecPtr lsn, XLogRecord *record)
FreeSpaceMapTruncateRel(rel, xlrec->blkno);
FreeFakeRelcacheEntry(rel);
}
}
else
elog(PANIC, "smgr_redo: unknown op code %u", info);
......
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.29 2010/02/03 01:14:16 tgl Exp $
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.30 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -114,6 +114,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
HeapTuple reltup;
TupleDesc tupdesc;
bool shared_relation;
bool mapped_relation;
Relation class_rel;
Oid toast_relid;
Oid toast_idxid;
......@@ -139,6 +140,9 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("shared tables cannot be toasted after initdb")));
/* It's mapped if and only if its parent is, too */
mapped_relation = RelationIsMapped(rel);
/*
* Is it already toasted?
*/
......@@ -148,7 +152,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
/*
* Check to see whether the table actually needs a TOAST table.
*
* If an update-in-place relfilenode is specified, force toast file
* If an update-in-place toast relfilenode is specified, force toast file
* creation even if it seems not to need one.
*/
if (!needs_toast_table(rel) &&
......@@ -213,6 +217,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptio
NIL,
RELKIND_TOASTVALUE,
shared_relation,
mapped_relation,
true,
0,
ONCOMMIT_NOOP,
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.190 2010/01/02 16:57:37 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.191 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -244,10 +244,15 @@ DefineIndex(RangeVar *heapRelation,
/*
* Force shared indexes into the pg_global tablespace. This is a bit of a
* hack but seems simpler than marking them in the BKI commands.
* hack but seems simpler than marking them in the BKI commands. On the
* other hand, if it's not shared, don't allow it to be placed there.
*/
if (rel->rd_rel->relisshared)
tablespaceId = GLOBALTABLESPACE_OID;
else if (tablespaceId == GLOBALTABLESPACE_OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("only shared relations can be placed in pg_global tablespace")));
/*
* Choose the index column names.
......@@ -1615,16 +1620,9 @@ ReindexTable(RangeVar *relation)
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
relation->relname);
/* Can't reindex shared tables except in standalone mode */
if (((Form_pg_class) GETSTRUCT(tuple))->relisshared && IsUnderPostmaster)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("shared table \"%s\" can only be reindexed in stand-alone mode",
relation->relname)));
ReleaseSysCache(tuple);
if (!reindex_relation(heapOid, true))
if (!reindex_relation(heapOid, true, false))
ereport(NOTICE,
(errmsg("table \"%s\" has no indexes",
relation->relname)));
......@@ -1717,12 +1715,6 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
continue;
}
if (IsUnderPostmaster) /* silently ignore shared tables */
{
if (classtuple->relisshared)
continue;
}
if (HeapTupleGetOid(tuple) == RelationRelationId)
continue; /* got it already */
......@@ -1743,7 +1735,7 @@ ReindexDatabase(const char *databaseName, bool do_system, bool do_user)
StartTransactionCommand();
/* functions in indexes may want a snapshot set */
PushActiveSnapshot(GetTransactionSnapshot());
if (reindex_relation(relid, true))
if (reindex_relation(relid, true, false))
ereport(NOTICE,
(errmsg("table \"%s\" was reindexed",
get_rel_name(relid))));
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.324 2010/02/04 00:09:14 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.325 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -436,6 +436,12 @@ DefineRelation(CreateStmt *stmt, char relkind)
get_tablespace_name(tablespaceId));
}
/* In all cases disallow placing user relations in pg_global */
if (tablespaceId == GLOBALTABLESPACE_OID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("only shared relations can be placed in pg_global tablespace")));
/*
* Parse and validate reloptions, if any.
*/
......@@ -534,6 +540,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
old_constraints),
relkind,
false,
false,
localHasOids,
parentOidCount,
stmt->oncommit,
......@@ -1014,7 +1021,7 @@ ExecuteTruncate(TruncateStmt *stmt)
/*
* Reconstruct the indexes to match, and we're done.
*/
reindex_relation(heap_relid, true);
reindex_relation(heap_relid, true, false);
}
}
......@@ -1091,16 +1098,6 @@ truncate_check_rel(Relation rel)
errmsg("permission denied: \"%s\" is a system catalog",
RelationGetRelationName(rel))));
/*
* We can never allow truncation of shared or nailed-in-cache relations,
* because we can't support changing their relfilenode values.
*/
if (rel->rd_rel->relisshared || rel->rd_isnailed)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot truncate system relation \"%s\"",
RelationGetRelationName(rel))));
/*
* Don't allow truncate on temp tables of other backends ... their local
* buffer manager is not going to cope.
......@@ -2873,11 +2870,11 @@ ATRewriteTables(List **wqueue)
OldHeap = heap_open(tab->relid, NoLock);
/*
* We can never allow rewriting of shared or nailed-in-cache
* relations, because we can't support changing their relfilenode
* values.
* We don't support rewriting of system catalogs; there are
* too many corner cases and too little benefit. In particular
* this is certainly not going to work for mapped catalogs.
*/
if (OldHeap->rd_rel->relisshared || OldHeap->rd_isnailed)
if (IsSystemRelation(OldHeap))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot rewrite system relation \"%s\"",
......@@ -2914,17 +2911,14 @@ ATRewriteTables(List **wqueue)
ATRewriteTable(tab, OIDNewHeap);
/*
* Swap the physical files of the old and new heaps. Since we are
* generating a new heap, we can use RecentXmin for the table's
* new relfrozenxid because we rewrote all the tuples on
* ATRewriteTable, so no older Xid remains in the table. Also,
* we never try to swap toast tables by content, since we have
* no interest in letting this code work on system catalogs.
* Swap the physical files of the old and new heaps, then rebuild
* indexes and discard the new heap. We can use RecentXmin for
* the table's new relfrozenxid because we rewrote all the tuples
* in ATRewriteTable, so no older Xid remains in the table. Also,
* we never try to swap toast tables by content, since we have no
* interest in letting this code work on system catalogs.
*/
swap_relation_files(tab->relid, OIDNewHeap, false, RecentXmin);
/* Destroy the new heap, removing the old data along with it. */
cleanup_heap_swap(tab->relid, OIDNewHeap, false);
finish_heap_swap(tab->relid, OIDNewHeap, false, false, RecentXmin);
}
else
{
......@@ -3715,7 +3709,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel,
typeOid = HeapTupleGetOid(typeTuple);
/* make sure datatype is legal for a column */
CheckAttributeType(colDef->colname, typeOid);
CheckAttributeType(colDef->colname, typeOid, false);
/* construct new attribute's pg_attribute entry */
attribute.attrelid = myrelid;
......@@ -5825,7 +5819,7 @@ ATPrepAlterColumnType(List **wqueue,
targettype = typenameTypeId(NULL, typeName, &targettypmod);
/* make sure datatype is legal for a column */
CheckAttributeType(colName, targettype);
CheckAttributeType(colName, targettype, false);
/*
* Set up an expression to transform the old data value to the new type.
......@@ -6925,10 +6919,21 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
rel = relation_open(tableOid, AccessExclusiveLock);
/*
* We can never allow moving of shared or nailed-in-cache relations,
* because we can't support changing their reltablespace values.
* No work if no change in tablespace.
*/
oldTableSpace = rel->rd_rel->reltablespace;
if (newTableSpace == oldTableSpace ||
(newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
{
relation_close(rel, NoLock);
return;
}
/*
* We cannot support moving mapped relations into different tablespaces.
* (In particular this eliminates all shared catalogs.)
*/
if (rel->rd_rel->relisshared || rel->rd_isnailed)
if (RelationIsMapped(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot move system relation \"%s\"",
......@@ -6949,17 +6954,6 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot move temporary tables of other sessions")));
/*
* No work if no change in tablespace.
*/
oldTableSpace = rel->rd_rel->reltablespace;
if (newTableSpace == oldTableSpace ||
(newTableSpace == MyDatabaseTableSpace && oldTableSpace == 0))
{
relation_close(rel, NoLock);
return;
}
reltoastrelid = rel->rd_rel->reltoastrelid;
reltoastidxid = rel->rd_rel->reltoastidxid;
......@@ -6985,9 +6979,7 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace)
* Relfilenodes are not unique across tablespaces, so we need to allocate
* a new one in the new tablespace.
*/
newrelfilenode = GetNewRelFileNode(newTableSpace,
rel->rd_rel->relisshared,
NULL);
newrelfilenode = GetNewRelFileNode(newTableSpace, NULL);
/* Open old and new relation */
newrnode = rel->rd_node;
......
......@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.403 2010/01/06 05:31:13 itagaki Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.404 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1183,11 +1183,10 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
/*
* Do the actual work --- either FULL, FULL INPLACE, or "lazy" vacuum.
* We can use only FULL INPLACE vacuum for system relations.
*/
if (!(vacstmt->options & VACOPT_FULL))
heldoff = lazy_vacuum_rel(onerel, vacstmt, vac_strategy, scanned_all);
else if ((vacstmt->options & VACOPT_INPLACE) || IsSystemRelation(onerel))
else if (vacstmt->options & VACOPT_INPLACE)
heldoff = full_vacuum_rel(onerel, vacstmt);
else
{
......@@ -1196,8 +1195,8 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound,
onerel = NULL;
cluster_rel(relid, InvalidOid, false,
(vacstmt->options & VACOPT_VERBOSE) != 0,
vacstmt->freeze_min_age, vacstmt->freeze_table_age);
(vacstmt->options & VACOPT_VERBOSE) != 0,
vacstmt->freeze_min_age, vacstmt->freeze_table_age);
heldoff = false;
}
......
......@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.344 2010/02/03 10:01:30 heikki Exp $
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.345 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2168,6 +2168,7 @@ OpenIntoRel(QueryDesc *queryDesc)
NIL,
RELKIND_RELATION,
false,
false,
true,
0,
into->onCommit,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.195 2010/01/02 16:57:49 momjian Exp $
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.196 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -609,7 +609,7 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
tupdesc = BuildDescFromLists(rte->eref->colnames,
rte->funccoltypes,
rte->funccoltypmods);
CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE);
CheckAttributeNamesTypes(tupdesc, RELKIND_COMPOSITE_TYPE, false);
}
return rte;
......
/*
* dbsize.c
* object size functions
* Database object size functions, and related inquiries
*
* Copyright (c) 2002-2010, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.28 2010/01/23 21:29:00 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/dbsize.c,v 1.29 2010/02/07 20:48:10 tgl Exp $
*
*/
......@@ -25,6 +25,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/rel.h"
#include "utils/relmapper.h"
#include "utils/syscache.h"
......@@ -507,3 +508,121 @@ pg_size_pretty(PG_FUNCTION_ARGS)
PG_RETURN_TEXT_P(cstring_to_text(buf));
}
/*
* Get the filenode of a relation
*
* This is expected to be used in queries like
* SELECT pg_relation_filenode(oid) FROM pg_class;
* That leads to a couple of choices. We work from the pg_class row alone
* rather than actually opening each relation, for efficiency. We don't
* fail if we can't find the relation --- some rows might be visible in
* the query's MVCC snapshot but already dead according to SnapshotNow.
* (Note: we could avoid using the catcache, but there's little point
* because the relation mapper also works "in the now".) We also don't
* fail if the relation doesn't have storage. In all these cases it
* seems better to quietly return NULL.
*/
Datum
pg_relation_filenode(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
Oid result;
HeapTuple tuple;
Form_pg_class relform;
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
PG_RETURN_NULL();
relform = (Form_pg_class) GETSTRUCT(tuple);
switch (relform->relkind)
{
case RELKIND_RELATION:
case RELKIND_INDEX:
case RELKIND_SEQUENCE:
case RELKIND_TOASTVALUE:
/* okay, these have storage */
if (relform->relfilenode)
result = relform->relfilenode;
else /* Consult the relation mapper */
result = RelationMapOidToFilenode(relid,
relform->relisshared);
break;
default:
/* no storage, return NULL */
result = InvalidOid;
break;
}
ReleaseSysCache(tuple);
if (!OidIsValid(result))
PG_RETURN_NULL();
PG_RETURN_OID(result);
}
/*
* Get the pathname (relative to $PGDATA) of a relation
*
* See comments for pg_relation_filenode.
*/
Datum
pg_relation_filepath(PG_FUNCTION_ARGS)
{
Oid relid = PG_GETARG_OID(0);
HeapTuple tuple;
Form_pg_class relform;
RelFileNode rnode;
char *path;
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
PG_RETURN_NULL();
relform = (Form_pg_class) GETSTRUCT(tuple);
switch (relform->relkind)
{
case RELKIND_RELATION:
case RELKIND_INDEX:
case RELKIND_SEQUENCE:
case RELKIND_TOASTVALUE:
/* okay, these have storage */
/* This logic should match RelationInitPhysicalAddr */
if (relform->reltablespace)
rnode.spcNode = relform->reltablespace;
else
rnode.spcNode = MyDatabaseTableSpace;
if (rnode.spcNode == GLOBALTABLESPACE_OID)
rnode.dbNode = InvalidOid;
else
rnode.dbNode = MyDatabaseId;
if (relform->relfilenode)
rnode.relNode = relform->relfilenode;
else /* Consult the relation mapper */
rnode.relNode = RelationMapOidToFilenode(relid,
relform->relisshared);
break;
default:
/* no storage, return NULL */
rnode.relNode = InvalidOid;
break;
}
ReleaseSysCache(tuple);
if (!OidIsValid(rnode.relNode))
PG_RETURN_NULL();
path = relpath(rnode, MAIN_FORKNUM);
PG_RETURN_TEXT_P(cstring_to_text(path));
}
......@@ -4,7 +4,7 @@
# Makefile for utils/cache
#
# IDENTIFICATION
# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.25 2010/01/22 16:40:19 rhaas Exp $
# $PostgreSQL: pgsql/src/backend/utils/cache/Makefile,v 1.26 2010/02/07 20:48:10 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -12,7 +12,7 @@ subdir = src/backend/utils/cache
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = attoptcache.o catcache.o inval.o plancache.o relcache.o \
OBJS = attoptcache.o catcache.o inval.o plancache.o relcache.o relmapper.o \
spccache.o syscache.o lsyscache.o typcache.o ts_cache.o
include $(top_srcdir)/src/backend/common.mk
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.148 2010/01/02 16:57:55 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/catcache.c,v 1.149 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -28,6 +28,7 @@
#endif
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/resowner.h"
......@@ -679,17 +680,6 @@ ResetCatalogCaches(void)
* or a temp table being dropped at end of transaction, or a table created
* during the current transaction that is being dropped because of abort.)
* Remove all cache entries relevant to the specified relation OID.
*
* A special case occurs when relId is itself one of the cacheable system
* tables --- although those'll never be dropped, they can get flushed from
* the relcache (VACUUM causes this, for example). In that case we need
* to flush all cache entries that came from that table. (At one point we
* also tried to force re-execution of CatalogCacheInitializeCache for
* the cache(s) on that table. This is a bad idea since it leads to all
* kinds of trouble if a cache flush occurs while loading cache entries.
* We now avoid the need to do it by copying cc_tupdesc out of the relcache,
* rather than relying on the relcache to keep a tupdesc for us. Of course
* this assumes the tupdesc of a cachable system table will not change...)
*/
void
CatalogCacheFlushRelation(Oid relId)
......@@ -706,14 +696,6 @@ CatalogCacheFlushRelation(Oid relId)
if (cache->cc_tupdesc == NULL)
continue;
/* Does this cache store tuples of the target relation itself? */
if (cache->cc_tupdesc->attrs[0]->attrelid == relId)
{
/* Yes, so flush all its contents */
ResetCatalogCache(cache);
continue;
}
/* Does this cache store tuples associated with relations at all? */
if (cache->cc_reloidattr == 0)
continue; /* nope, leave it alone */
......@@ -775,6 +757,46 @@ CatalogCacheFlushRelation(Oid relId)
CACHE1_elog(DEBUG2, "end of CatalogCacheFlushRelation call");
}
/*
* CatalogCacheFlushCatalog
*
* Flush all catcache entries that came from the specified system catalog.
* This is needed after VACUUM FULL/CLUSTER on the catalog, since the
* tuples very likely now have different TIDs than before. (At one point
* we also tried to force re-execution of CatalogCacheInitializeCache for
* the cache(s) on that catalog. This is a bad idea since it leads to all
* kinds of trouble if a cache flush occurs while loading cache entries.
* We now avoid the need to do it by copying cc_tupdesc out of the relcache,
* rather than relying on the relcache to keep a tupdesc for us. Of course
* this assumes the tupdesc of a cachable system table will not change...)
*/
void
CatalogCacheFlushCatalog(Oid catId)
{
CatCache *cache;
CACHE2_elog(DEBUG2, "CatalogCacheFlushCatalog called for %u", catId);
for (cache = CacheHdr->ch_caches; cache; cache = cache->cc_next)
{
/* We can ignore uninitialized caches, since they must be empty */
if (cache->cc_tupdesc == NULL)
continue;
/* Does this cache store tuples of the target catalog? */
if (cache->cc_tupdesc->attrs[0]->attrelid == catId)
{
/* Yes, so flush all its contents */
ResetCatalogCache(cache);
/* Tell inval.c to call syscache callbacks for this cache */
CallSyscacheCallbacks(cache->id, NULL);
}
}
CACHE1_elog(DEBUG2, "end of CatalogCacheFlushCatalog call");
}
/*
* InitCatCache
*
......
......@@ -80,7 +80,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.93 2010/02/03 01:14:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/inval.c,v 1.94 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -96,6 +96,7 @@
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/relmapper.h"
#include "utils/syscache.h"
......@@ -325,6 +326,21 @@ AddCatcacheInvalidationMessage(InvalidationListHeader *hdr,
AddInvalidationMessage(&hdr->cclist, &msg);
}
/*
* Add a whole-catalog inval entry
*/
static void
AddCatalogInvalidationMessage(InvalidationListHeader *hdr,
Oid dbId, Oid catId)
{
SharedInvalidationMessage msg;
msg.cat.id = SHAREDINVALCATALOG_ID;
msg.cat.dbId = dbId;
msg.cat.catId = catId;
AddInvalidationMessage(&hdr->cclist, &msg);
}
/*
* Add a relcache inval entry
*/
......@@ -406,6 +422,18 @@ RegisterCatcacheInvalidation(int cacheId,
cacheId, hashValue, tuplePtr, dbId);
}
/*
* RegisterCatalogInvalidation
*
* Register an invalidation event for all catcache entries from a catalog.
*/
static void
RegisterCatalogInvalidation(Oid dbId, Oid catId)
{
AddCatalogInvalidationMessage(&transInvalInfo->CurrentCmdInvalidMsgs,
dbId, catId);
}
/*
* RegisterRelcacheInvalidation
*
......@@ -443,30 +471,32 @@ RegisterRelcacheInvalidation(Oid dbId, Oid relId)
static void
LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
{
int i;
if (msg->id >= 0)
{
if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == 0)
if (msg->cc.dbId == MyDatabaseId || msg->cc.dbId == InvalidOid)
{
CatalogCacheIdInvalidate(msg->cc.id,
msg->cc.hashValue,
&msg->cc.tuplePtr);
for (i = 0; i < syscache_callback_count; i++)
{
struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
CallSyscacheCallbacks(msg->cc.id, &msg->cc.tuplePtr);
}
}
else if (msg->id == SHAREDINVALCATALOG_ID)
{
if (msg->cat.dbId == MyDatabaseId || msg->cat.dbId == InvalidOid)
{
CatalogCacheFlushCatalog(msg->cat.catId);
if (ccitem->id == msg->cc.id)
(*ccitem->function) (ccitem->arg,
msg->cc.id, &msg->cc.tuplePtr);
}
/* CatalogCacheFlushCatalog calls CallSyscacheCallbacks as needed */
}
}
else if (msg->id == SHAREDINVALRELCACHE_ID)
{
if (msg->rc.dbId == MyDatabaseId || msg->rc.dbId == InvalidOid)
{
int i;
RelationCacheInvalidateEntry(msg->rc.relId);
for (i = 0; i < relcache_callback_count; i++)
......@@ -485,6 +515,14 @@ LocalExecuteInvalidationMessage(SharedInvalidationMessage *msg)
*/
smgrclosenode(msg->sm.rnode);
}
else if (msg->id == SHAREDINVALRELMAP_ID)
{
/* We only care about our own database and shared catalogs */
if (msg->rm.dbId == InvalidOid)
RelationMapInvalidate(true);
else if (msg->rm.dbId == MyDatabaseId)
RelationMapInvalidate(false);
}
else
elog(FATAL, "unrecognized SI message id: %d", msg->id);
}
......@@ -506,7 +544,7 @@ InvalidateSystemCaches(void)
int i;
ResetCatalogCaches();
RelationCacheInvalidate(); /* gets smgr cache too */
RelationCacheInvalidate(); /* gets smgr and relmap too */
for (i = 0; i < syscache_callback_count; i++)
{
......@@ -874,7 +912,7 @@ ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs,
else
{
/*
* Invalidation message is a SHAREDINVALSMGR_ID
* Invalidation message is a catalog or nontransactional inval,
* which never cause relcache file invalidation,
* so we ignore them, no matter which db they're for.
*/
......@@ -1182,6 +1220,30 @@ CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple)
PrepareForTupleInvalidation(relation, tuple);
}
/*
* CacheInvalidateCatalog
* Register invalidation of the whole content of a system catalog.
*
* This is normally used in VACUUM FULL/CLUSTER, where we haven't so much
* changed any tuples as moved them around. Some uses of catcache entries
* expect their TIDs to be correct, so we have to blow away the entries.
*
* Note: we expect caller to verify that the rel actually is a system
* catalog. If it isn't, no great harm is done, just a wasted sinval message.
*/
void
CacheInvalidateCatalog(Oid catalogId)
{
Oid databaseId;
if (IsSharedRelation(catalogId))
databaseId = InvalidOid;
else
databaseId = MyDatabaseId;
RegisterCatalogInvalidation(databaseId, catalogId);
}
/*
* CacheInvalidateRelcache
* Register invalidation of the specified relation's relcache entry
......@@ -1277,6 +1339,31 @@ CacheInvalidateSmgr(RelFileNode rnode)
SendSharedInvalidMessages(&msg, 1);
}
/*
* CacheInvalidateRelmap
* Register invalidation of the relation mapping for a database,
* or for the shared catalogs if databaseId is zero.
*
* Sending this type of invalidation msg forces other backends to re-read
* the indicated relation mapping file. It is also necessary to send a
* relcache inval for the specific relations whose mapping has been altered,
* else the relcache won't get updated with the new filenode data.
*
* Note: because these messages are nontransactional, they won't be captured
* in commit/abort WAL entries. Instead, calls to CacheInvalidateRelmap()
* should happen in low-level relmapper.c routines, which are executed while
* replaying WAL as well as when creating it.
*/
void
CacheInvalidateRelmap(Oid databaseId)
{
SharedInvalidationMessage msg;
msg.rm.id = SHAREDINVALRELMAP_ID;
msg.rm.dbId = databaseId;
SendSharedInvalidMessages(&msg, 1);
}
/*
* CacheRegisterSyscacheCallback
......@@ -1323,3 +1410,23 @@ CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
++relcache_callback_count;
}
/*
* CallSyscacheCallbacks
*
* This is exported so that CatalogCacheFlushCatalog can call it, saving
* this module from knowing which catcache IDs correspond to which catalogs.
*/
void
CallSyscacheCallbacks(int cacheid, ItemPointer tuplePtr)
{
int i;
for (i = 0; i < syscache_callback_count; i++)
{
struct SYSCACHECALLBACK *ccitem = syscache_callback_list + i;
if (ccitem->id == cacheid)
(*ccitem->function) (ccitem->arg, cacheid, tuplePtr);
}
}
This diff is collapsed.
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.180 2010/01/02 16:57:56 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/miscinit.c,v 1.181 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -64,62 +64,6 @@ static char socketLockFile[MAXPGPATH];
bool IgnoreSystemIndexes = false;
/* ----------------------------------------------------------------
* system index reindexing support
*
* When we are busy reindexing a system index, this code provides support
* for preventing catalog lookups from using that index.
* ----------------------------------------------------------------
*/
static Oid currentlyReindexedHeap = InvalidOid;
static Oid currentlyReindexedIndex = InvalidOid;
/*
* ReindexIsProcessingHeap
* True if heap specified by OID is currently being reindexed.
*/
bool
ReindexIsProcessingHeap(Oid heapOid)
{
return heapOid == currentlyReindexedHeap;
}
/*
* ReindexIsProcessingIndex
* True if index specified by OID is currently being reindexed.
*/
bool
ReindexIsProcessingIndex(Oid indexOid)
{
return indexOid == currentlyReindexedIndex;
}
/*
* SetReindexProcessing
* Set flag that specified heap/index are being reindexed.
*/
void
SetReindexProcessing(Oid heapOid, Oid indexOid)
{
Assert(OidIsValid(heapOid) && OidIsValid(indexOid));
/* Reindexing is not re-entrant. */
if (OidIsValid(currentlyReindexedIndex))
elog(ERROR, "cannot reindex while reindexing");
currentlyReindexedHeap = heapOid;
currentlyReindexedIndex = indexOid;
}
/*
* ResetReindexProcessing
* Unset reindexing status.
*/
void
ResetReindexProcessing(void)
{
currentlyReindexedHeap = InvalidOid;
currentlyReindexedIndex = InvalidOid;
}
/* ----------------------------------------------------------------
* database path / name support stuff
......
......@@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.569 2010/01/28 23:21:12 petere Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.570 2010/02/07 20:48:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2300,6 +2300,12 @@ binary_upgrade_set_relfilenodes(PQExpBuffer upgrade_buffer, Oid pg_class_oid,
Oid pg_class_reltoastrelid;
Oid pg_class_reltoastidxid;
/*
* Note: we don't need to use pg_relation_filenode() here because this
* function is not intended to be used against system catalogs.
* Otherwise we'd have to worry about which versions pg_relation_filenode
* is available in.
*/
appendPQExpBuffer(upgrade_query,
"SELECT c.relfilenode, c.reltoastrelid, t.reltoastidxid "
"FROM pg_catalog.pg_class c LEFT JOIN "
......
......@@ -3,7 +3,7 @@
*
* Resource managers definition
*
* $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.20 2009/12/19 01:32:42 sriggs Exp $
* $PostgreSQL: pgsql/src/include/access/rmgr.h,v 1.21 2010/02/07 20:48:11 tgl Exp $
*/
#ifndef RMGR_H
#define RMGR_H
......@@ -23,6 +23,7 @@ typedef uint8 RmgrId;
#define RM_DBASE_ID 4
#define RM_TBLSPC_ID 5
#define RM_MULTIXACT_ID 6
#define RM_RELMAP_ID 7
#define RM_STANDBY_ID 8
#define RM_HEAP2_ID 9
#define RM_HEAP_ID 10
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.47 2010/01/12 02:42:52 momjian Exp $
* $PostgreSQL: pgsql/src/include/catalog/catalog.h,v 1.48 2010/02/07 20:48:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -45,7 +45,6 @@ extern bool IsSharedRelation(Oid relationId);
extern Oid GetNewOid(Relation relation);
extern Oid GetNewOidWithIndex(Relation relation, Oid indexId,
AttrNumber oidcolumn);
extern Oid GetNewRelFileNode(Oid reltablespace, bool relisshared,
Relation pg_class);
extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class);
#endif /* CATALOG_H */
......@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.582 2010/02/01 03:14:43 itagaki Exp $
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.583 2010/02/07 20:48:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -53,6 +53,6 @@
*/
/* yyyymmddN */
#define CATALOG_VERSION_NO 201002011
#define CATALOG_VERSION_NO 201002071
#endif
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.96 2010/01/28 23:21:12 petere Exp $
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.97 2010/02/07 20:48:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -41,6 +41,7 @@ extern Relation heap_create(const char *relname,
TupleDesc tupDesc,
char relkind,
bool shared_relation,
bool mapped_relation,
bool allow_system_table_mods);
extern Oid heap_create_with_catalog(const char *relname,
......@@ -54,6 +55,7 @@ extern Oid heap_create_with_catalog(const char *relname,
List *cooked_constraints,
char relkind,
bool shared_relation,
bool mapped_relation,
bool oidislocal,
int oidinhcount,
OnCommitAction oncommit,
......@@ -109,8 +111,10 @@ extern Form_pg_attribute SystemAttributeDefinition(AttrNumber attno,
extern Form_pg_attribute SystemAttributeByName(const char *attname,
bool relhasoids);
extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind);
extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
bool allow_system_table_mods);
extern void CheckAttributeType(const char *attname, Oid atttypid);
extern void CheckAttributeType(const char *attname, Oid atttypid,
bool allow_system_table_mods);
#endif /* HEAP_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.81 2010/02/03 01:14:17 tgl Exp $
* $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.82 2010/02/07 20:48:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -71,6 +71,9 @@ extern double IndexBuildHeapScan(Relation heapRelation,
extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
extern void reindex_index(Oid indexId);
extern bool reindex_relation(Oid relid, bool toast_too);
extern bool reindex_relation(Oid relid, bool toast_too, bool heap_rebuilt);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern bool ReindexIsProcessingIndex(Oid indexOid);
#endif /* INDEX_H */
......@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.120 2010/01/28 23:21:12 petere Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.121 2010/02/07 20:48:11 tgl Exp $
*
* NOTES
* the genbki.pl script reads this file and generates .bki
......@@ -38,6 +38,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
Oid relowner; /* class owner */
Oid relam; /* index access method; 0 if not an index */
Oid relfilenode; /* identifier of physical storage file */
/* relfilenode == 0 means it is a "mapped" relation, see relmapper.c */
Oid reltablespace; /* identifier of table space for relation */
int4 relpages; /* # of blocks (not always up-to-date) */
float4 reltuples; /* # of tuples (not always up-to-date) */
......@@ -128,13 +129,13 @@ typedef FormData_pg_class *Form_pg_class;
*/
/* Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId */
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 1247 0 0 0 0 0 f f f r 28 0 t f f f f f 3 _null_ _null_ ));
DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f f r 28 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 1249 0 0 0 0 0 f f f r 19 0 f f f f f f 3 _null_ _null_ ));
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f f r 19 0 f f f f f f 3 _null_ _null_ ));
DESCR("");
DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 1255 0 0 0 0 0 f f f r 25 0 t f f f f f 3 _null_ _null_ ));
DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f f r 25 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 1259 0 0 0 0 0 f f f r 27 0 t f f f f f 3 _null_ _null_ ));
DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f f r 27 0 t f f f f f 3 _null_ _null_ ));
DESCR("");
#define RELKIND_INDEX 'i' /* secondary index */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.567 2010/02/01 03:14:44 itagaki Exp $
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.568 2010/02/07 20:48:11 tgl Exp $
*
* NOTES
* The script catalog/genbki.pl reads this file and generates .bki
......@@ -3741,6 +3741,10 @@ DATA(insert OID = 2997 ( pg_table_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20
DESCR("disk space usage for the specified table, including TOAST, free space and visibility map");
DATA(insert OID = 2998 ( pg_indexes_size PGNSP PGUID 12 1 0 0 f f f t f v 1 0 20 "2205" _null_ _null_ _null_ _null_ pg_indexes_size _null_ _null_ _null_ ));
DESCR("disk space usage for all indexes attached to the specified table");
DATA(insert OID = 2999 ( pg_relation_filenode PGNSP PGUID 12 1 0 0 f f f t f s 1 0 26 "2205" _null_ _null_ _null_ _null_ pg_relation_filenode _null_ _null_ _null_ ));
DESCR("filenode identifier of relation");
DATA(insert OID = 3034 ( pg_relation_filepath PGNSP PGUID 12 1 0 0 f f f t f s 1 0 25 "2205" _null_ _null_ _null_ _null_ pg_relation_filepath _null_ _null_ _null_ ));
DESCR("file path of relation");
DATA(insert OID = 2316 ( postgresql_fdw_validator PGNSP PGUID 12 1 0 0 f f f t f i 2 0 16 "1009 26" _null_ _null_ _null_ _null_ postgresql_fdw_validator _null_ _null_ _null_));
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/catalog/storage.h,v 1.4 2010/01/02 16:58:02 momjian Exp $
* $PostgreSQL: pgsql/src/include/catalog/storage.h,v 1.5 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -22,6 +22,7 @@
extern void RelationCreateStorage(RelFileNode rnode, bool istemp);
extern void RelationDropStorage(Relation rel);
extern void RelationPreserveStorage(RelFileNode rnode);
extern void RelationTruncate(Relation rel, BlockNumber nblocks);
/*
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994-5, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.39 2010/02/04 00:09:14 tgl Exp $
* $PostgreSQL: pgsql/src/include/commands/cluster.h,v 1.40 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -25,9 +25,9 @@ extern void check_index_is_clusterable(Relation OldHeap, Oid indexOid,
extern void mark_index_clustered(Relation rel, Oid indexOid);
extern Oid make_new_heap(Oid OIDOldHeap, Oid NewTableSpace);
extern void swap_relation_files(Oid r1, Oid r2, bool swap_toast_by_content,
TransactionId frozenXid);
extern void cleanup_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
bool swap_toast_by_content);
extern void finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
bool is_system_catalog,
bool swap_toast_by_content,
TransactionId frozenXid);
#endif /* CLUSTER_H */
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.217 2010/01/02 16:58:00 momjian Exp $
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.218 2010/02/07 20:48:13 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to other files.
......@@ -347,10 +347,6 @@ extern PGDLLIMPORT bool process_shared_preload_libraries_in_progress;
extern char *shared_preload_libraries_string;
extern char *local_preload_libraries_string;
extern void SetReindexProcessing(Oid heapOid, Oid indexOid);
extern void ResetReindexProcessing(void);
extern bool ReindexIsProcessingHeap(Oid heapOid);
extern bool ReindexIsProcessingIndex(Oid indexOid);
extern void CreateDataDirLockFile(bool amPostmaster);
extern void CreateSocketLockFile(const char *socketfile, bool amPostmaster);
extern void TouchSocketLockFile(void);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.43 2010/01/02 16:58:08 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.44 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -67,6 +67,7 @@ typedef enum LWLockId
AutovacuumLock,
AutovacuumScheduleLock,
SyncScanLock,
RelationMappingLock,
/* Individual lock IDs end here */
FirstBufMappingLock,
FirstLockMgrLock = FirstBufMappingLock + NUM_BUFFER_PARTITIONS,
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.24 2010/01/02 16:58:08 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/relfilenode.h,v 1.25 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -61,6 +61,10 @@ typedef enum ForkNumber
* identified by pg_database.dattablespace). However this shorthand
* is NOT allowed in RelFileNode structs --- the real tablespace ID
* must be supplied when setting spcNode.
*
* Note: in pg_class, relfilenode can be zero to denote that the relation
* is a "mapped" relation, whose current true filenode number is available
* from relmapper.c. Again, this case is NOT allowed in RelFileNodes.
*/
typedef struct RelFileNode
{
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.56 2010/01/09 16:49:27 sriggs Exp $
* $PostgreSQL: pgsql/src/include/storage/sinval.h,v 1.57 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -19,14 +19,16 @@
/*
* We currently support three types of shared-invalidation messages: one that
* invalidates an entry in a catcache, one that invalidates a relcache entry,
* and one that invalidates an smgr cache entry. More types could be added
* if needed. The message type is identified by the first "int16" field of
* the message struct. Zero or positive means a catcache inval message (and
* also serves as the catcache ID field). -1 means a relcache inval message.
* -2 means an smgr inval message. Other negative values are available to
* identify other inval message types.
* We support several types of shared-invalidation messages:
* * invalidate a specific tuple in a specific catcache
* * invalidate all catcache entries from a given system catalog
* * invalidate a relcache entry for a specific logical relation
* * invalidate an smgr cache entry for a specific physical relation
* * invalidate the mapped-relation mapping for a given database
* More types could be added if needed. The message type is identified by
* the first "int16" field of the message struct. Zero or positive means a
* specific-catcache inval message (and also serves as the catcache ID field).
* Negative values identify the other message types, as per codes below.
*
* Catcache inval events are initially driven by detecting tuple inserts,
* updates and deletions in system catalogs (see CacheInvalidateHeapTuple).
......@@ -46,6 +48,16 @@
* and so that negative cache entries can be recognized with good accuracy.
* (Of course this assumes that all the backends are using identical hashing
* code, but that should be OK.)
*
* Catcache and relcache invalidations are transactional, and so are sent
* to other backends upon commit. Internally to the generating backend,
* they are also processed at CommandCounterIncrement so that later commands
* in the same transaction see the new state. The generating backend also
* has to process them at abort, to flush out any cache state it's loaded
* from no-longer-valid entries.
*
* smgr and relation mapping invalidations are non-transactional: they are
* sent immediately when the underlying file change is made.
*/
typedef struct
......@@ -57,7 +69,16 @@ typedef struct
uint32 hashValue; /* hash value of key for this catcache */
} SharedInvalCatcacheMsg;
#define SHAREDINVALRELCACHE_ID (-1)
#define SHAREDINVALCATALOG_ID (-1)
typedef struct
{
int16 id; /* type field --- must be first */
Oid dbId; /* database ID, or 0 if a shared catalog */
Oid catId; /* ID of catalog whose contents are invalid */
} SharedInvalCatalogMsg;
#define SHAREDINVALRELCACHE_ID (-2)
typedef struct
{
......@@ -66,7 +87,7 @@ typedef struct
Oid relId; /* relation ID */
} SharedInvalRelcacheMsg;
#define SHAREDINVALSMGR_ID (-2)
#define SHAREDINVALSMGR_ID (-3)
typedef struct
{
......@@ -74,12 +95,22 @@ typedef struct
RelFileNode rnode; /* physical file ID */
} SharedInvalSmgrMsg;
#define SHAREDINVALRELMAP_ID (-4)
typedef struct
{
int16 id; /* type field --- must be first */
Oid dbId; /* database ID, or 0 for shared catalogs */
} SharedInvalRelmapMsg;
typedef union
{
int16 id; /* type field --- must be first */
SharedInvalCatcacheMsg cc;
SharedInvalCatalogMsg cat;
SharedInvalRelcacheMsg rc;
SharedInvalSmgrMsg sm;
SharedInvalRelmapMsg rm;
} SharedInvalidationMessage;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.346 2010/02/01 03:14:45 itagaki Exp $
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.347 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -435,6 +435,8 @@ extern Datum pg_total_relation_size(PG_FUNCTION_ARGS);
extern Datum pg_size_pretty(PG_FUNCTION_ARGS);
extern Datum pg_table_size(PG_FUNCTION_ARGS);
extern Datum pg_indexes_size(PG_FUNCTION_ARGS);
extern Datum pg_relation_filenode(PG_FUNCTION_ARGS);
extern Datum pg_relation_filepath(PG_FUNCTION_ARGS);
/* genfile.c */
extern Datum pg_stat_file(PG_FUNCTION_ARGS);
......
......@@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/catcache.h,v 1.69 2010/01/02 16:58:10 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/catcache.h,v 1.70 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -180,6 +180,7 @@ extern void ReleaseCatCacheList(CatCList *list);
extern void ResetCatalogCaches(void);
extern void CatalogCacheFlushRelation(Oid relId);
extern void CatalogCacheFlushCatalog(Oid catId);
extern void CatalogCacheIdInvalidate(int cacheId, uint32 hashValue,
ItemPointer pointer);
extern void PrepareToInvalidateCacheTuple(Relation relation,
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/inval.h,v 1.47 2010/02/03 01:14:17 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/inval.h,v 1.48 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -45,6 +45,8 @@ extern void EndNonTransactionalInvalidation(void);
extern void CacheInvalidateHeapTuple(Relation relation, HeapTuple tuple);
extern void CacheInvalidateCatalog(Oid catalogId);
extern void CacheInvalidateRelcache(Relation relation);
extern void CacheInvalidateRelcacheByTuple(HeapTuple classTuple);
......@@ -53,6 +55,8 @@ extern void CacheInvalidateRelcacheByRelid(Oid relid);
extern void CacheInvalidateSmgr(RelFileNode rnode);
extern void CacheInvalidateRelmap(Oid databaseId);
extern void CacheRegisterSyscacheCallback(int cacheid,
SyscacheCallbackFunction func,
Datum arg);
......@@ -60,6 +64,8 @@ extern void CacheRegisterSyscacheCallback(int cacheid,
extern void CacheRegisterRelcacheCallback(RelcacheCallbackFunction func,
Datum arg);
extern void CallSyscacheCallbacks(int cacheid, ItemPointer tuplePtr);
extern void inval_twophase_postcommit(TransactionId xid, uint16 info,
void *recdata, uint32 len);
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.121 2010/02/04 00:09:14 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.122 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -339,6 +339,16 @@ typedef struct StdRdOptions
#define RelationGetNamespace(relation) \
((relation)->rd_rel->relnamespace)
/*
* RelationIsMapped
* True if the relation uses the relfilenode map.
*
* NB: this is only meaningful for relkinds that have storage, else it
* will misleadingly say "true".
*/
#define RelationIsMapped(relation) \
((relation)->rd_rel->relfilenode == InvalidOid)
/*
* RelationOpenSmgr
* Open the relation at the smgr level, if not already done.
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.67 2010/02/03 01:14:17 tgl Exp $
* $PostgreSQL: pgsql/src/include/utils/relcache.h,v 1.68 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -68,7 +68,8 @@ extern Relation RelationBuildLocalRelation(const char *relname,
TupleDesc tupDesc,
Oid relid,
Oid reltablespace,
bool shared_relation);
bool shared_relation,
bool mapped_relation);
/*
* Routine to manage assignment of new relfilenode to a relation
......@@ -85,6 +86,8 @@ extern void RelationCacheInvalidateEntry(Oid relationId);
extern void RelationCacheInvalidate(void);
extern void RelationCloseSmgrByOid(Oid relationId);
extern void AtEOXact_RelationCache(bool isCommit);
extern void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid,
SubTransactionId parentSubid);
......
/*-------------------------------------------------------------------------
*
* relmapper.h
* Catalog-to-filenode mapping
*
*
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/relmapper.h,v 1.1 2010/02/07 20:48:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RELMAPPER_H
#define RELMAPPER_H
#include "access/xlog.h"
/* ----------------
* relmap-related XLOG entries
* ----------------
*/
#define XLOG_RELMAP_UPDATE 0x00
typedef struct xl_relmap_update
{
Oid dbid; /* database ID, or 0 for shared map */
Oid tsid; /* database's tablespace, or pg_global */
int32 nbytes; /* size of relmap data */
char data[1]; /* VARIABLE LENGTH ARRAY */
} xl_relmap_update;
#define MinSizeOfRelmapUpdate offsetof(xl_relmap_update, data)
extern Oid RelationMapOidToFilenode(Oid relationId, bool shared);
extern void RelationMapUpdateMap(Oid relationId, Oid fileNode, bool shared,
bool immediate);
extern void RelationMapRemoveMapping(Oid relationId);
extern void RelationMapInvalidate(bool shared);
extern void RelationMapInvalidateAll(void);
extern void AtCCI_RelationMap(void);
extern void AtEOXact_RelationMap(bool isCommit);
extern void AtPrepare_RelationMap(void);
extern void CheckPointRelationMap(void);
extern void RelationMapFinishBootstrap(void);
extern void RelationMapInitialize(void);
extern void RelationMapInitializePhase2(void);
extern void RelationMapInitializePhase3(void);
extern void relmap_redo(XLogRecPtr lsn, XLogRecord *record);
extern void relmap_desc(StringInfo buf, uint8 xl_info, char *rec);
#endif /* RELMAPPER_H */
......@@ -108,7 +108,7 @@ SELECT relid,
ORDER BY relid::text;
relid | cluster | full_inplace | full
-------------+---------+--------------+------
pg_am | t | t | t
pg_am | t | t | f
pg_class | t | t | t
pg_database | t | t | t
vaccluster | f | t | f
......
# ----------
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.58 2010/01/28 23:21:13 petere Exp $
# $PostgreSQL: pgsql/src/test/regress/parallel_schedule,v 1.59 2010/02/07 20:48:13 tgl Exp $
#
# By convention, we put no more than twenty tests in any one parallel group;
# this limits the number of connections needed to run the tests.
......@@ -52,7 +52,10 @@ test: copy copyselect
# ----------
# Another group of parallel tests
# ----------
test: constraints triggers create_misc create_aggregate create_operator inherit typed_table vacuum drop_if_exists create_cast
test: constraints triggers create_misc create_aggregate create_operator inherit typed_table drop_if_exists create_cast
# XXX temporarily run this by itself
test: vacuum
# Depends on the above
test: create_index create_view
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment