Commit c5451c22 authored by Tom Lane's avatar Tom Lane

Make relhasrules and relhastriggers work like relhasindex, namely we let

VACUUM reset them to false rather than trying to clean 'em up during DROP.
parent e4718f2c
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.181 2008/11/09 21:24:32 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.182 2008/11/10 00:49:36 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
......@@ -4478,6 +4478,13 @@
</para>
</note>
<note>
<para>
<literal>pg_class.relhastriggers</literal>
must be true if a table has any triggers in this catalog.
</para>
</note>
</sect1>
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.127 2008/11/02 01:45:27 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.128 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -463,10 +463,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
*/
if (!vacstmt->vacuum)
{
vac_update_relstats(RelationGetRelid(onerel),
vac_update_relstats(onerel,
RelationGetNumberOfBlocks(onerel),
totalrows, hasindex,
InvalidTransactionId);
totalrows, hasindex, InvalidTransactionId);
for (ind = 0; ind < nindexes; ind++)
{
......@@ -474,10 +473,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
double totalindexrows;
totalindexrows = ceil(thisdata->tupleFract * totalrows);
vac_update_relstats(RelationGetRelid(Irel[ind]),
vac_update_relstats(Irel[ind],
RelationGetNumberOfBlocks(Irel[ind]),
totalindexrows, false,
InvalidTransactionId);
totalindexrows, false, InvalidTransactionId);
}
/* report results to the stats collector, too */
......
......@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.379 2008/10/31 15:05:00 heikki Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.380 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -664,6 +664,11 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
* pg_class would've been obsoleted. Of course, this only works for
* fixed-size never-null columns, but these are.
*
* Note another assumption: that two VACUUMs/ANALYZEs on a table can't
* run in parallel, nor can VACUUM/ANALYZE run in parallel with a
* schema alteration such as adding an index, rule, or trigger. Otherwise
* our updates of relhasindex etc might overwrite uncommitted updates.
*
* Another reason for doing it this way is that when we are in a lazy
* VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
* somebody vacuuming pg_class might think they could delete a tuple
......@@ -673,9 +678,11 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
* ANALYZE.
*/
void
vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
vac_update_relstats(Relation relation,
BlockNumber num_pages, double num_tuples,
bool hasindex, TransactionId frozenxid)
{
Oid relid = RelationGetRelid(relation);
Relation rd;
HeapTuple ctup;
Form_pg_class pgcform;
......@@ -724,6 +731,18 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples,
}
}
/* We also clear relhasrules and relhastriggers if needed */
if (pgcform->relhasrules && relation->rd_rules == NULL)
{
pgcform->relhasrules = false;
dirty = true;
}
if (pgcform->relhastriggers && relation->trigdesc == NULL)
{
pgcform->relhastriggers = false;
dirty = true;
}
/*
* relfrozenxid should never go backward. Caller can pass
* InvalidTransactionId if it has no new data.
......@@ -1269,9 +1288,9 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
FreeSpaceMapVacuum(onerel);
/* update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages,
vacrelstats->rel_tuples, vacrelstats->hasindex,
FreezeLimit);
vac_update_relstats(onerel,
vacrelstats->rel_pages, vacrelstats->rel_tuples,
vacrelstats->hasindex, FreezeLimit);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
......@@ -3315,7 +3334,7 @@ scan_index(Relation indrel, double num_tuples)
return;
/* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel),
vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
......@@ -3385,7 +3404,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
return;
/* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel),
vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
......
......@@ -29,7 +29,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.109 2008/10/31 15:05:00 heikki Exp $
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.110 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -186,11 +186,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
FreeSpaceMapVacuum(onerel);
/* Update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel),
vacrelstats->rel_pages,
vacrelstats->rel_tuples,
vacrelstats->hasindex,
FreezeLimit);
vac_update_relstats(onerel,
vacrelstats->rel_pages, vacrelstats->rel_tuples,
vacrelstats->hasindex, FreezeLimit);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
......@@ -757,9 +755,8 @@ lazy_cleanup_index(Relation indrel,
return;
/* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel),
stats->num_pages,
stats->num_index_tuples,
vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId);
ereport(elevel,
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.73 2008/06/19 00:46:05 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteRemove.c,v 1.74 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -22,9 +22,9 @@
#include "catalog/pg_rewrite.h"
#include "miscadmin.h"
#include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "utils/acl.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
......@@ -103,7 +103,6 @@ RemoveRewriteRuleById(Oid ruleOid)
Relation event_relation;
HeapTuple tuple;
Oid eventRelationOid;
bool hasMoreRules;
/*
* Open the pg_rewrite relation.
......@@ -127,17 +126,13 @@ RemoveRewriteRuleById(Oid ruleOid)
elog(ERROR, "could not find tuple for rule %u", ruleOid);
/*
* We had better grab AccessExclusiveLock so that we know no other rule
* additions/deletions are going on for this relation. Else we cannot set
* relhasrules correctly. Besides, we don't want to be changing the
* ruleset while queries are executing on the rel.
* We had better grab AccessExclusiveLock to ensure that no queries
* are going on that might depend on this rule. (Note: a weaker lock
* would suffice if it's not an ON SELECT rule.)
*/
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
event_relation = heap_open(eventRelationOid, AccessExclusiveLock);
hasMoreRules = event_relation->rd_rules != NULL &&
event_relation->rd_rules->numLocks > 1;
/*
* Now delete the pg_rewrite tuple for the rule
*/
......@@ -148,13 +143,10 @@ RemoveRewriteRuleById(Oid ruleOid)
heap_close(RewriteRelation, RowExclusiveLock);
/*
* Set pg_class 'relhasrules' field correctly for event relation.
*
* Important side effect: an SI notice is broadcast to force all backends
* (including me!) to update relcache entries with the new rule set.
* Therefore, must do this even if relhasrules is still true!
* Issue shared-inval notice to force all backends (including me!) to
* update relcache entries with the new rule set.
*/
SetRelationRuleStatus(eventRelationOid, hasMoreRules, false);
CacheInvalidateRelcache(event_relation);
/* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.275 2008/11/09 21:24:32 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.276 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -721,6 +721,17 @@ RelationBuildRuleLock(Relation relation)
systable_endscan(rewrite_scan);
heap_close(rewrite_desc, AccessShareLock);
/*
* there might not be any rules (if relhasrules is out-of-date)
*/
if (numlocks == 0)
{
relation->rd_rules = NULL;
relation->rd_rulescxt = NULL;
MemoryContextDelete(rulescxt);
return;
}
/*
* form a RuleLock and insert into relation
*/
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.80 2008/08/13 00:07:50 alvherre Exp $
* $PostgreSQL: pgsql/src/include/commands/vacuum.h,v 1.81 2008/11/10 00:49:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -130,7 +130,7 @@ extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel);
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode);
extern void vac_update_relstats(Oid relid,
extern void vac_update_relstats(Relation relation,
BlockNumber num_pages,
double num_tuples,
bool hasindex,
......
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