提交 c5451c22 编写于 作者: T 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.
上级 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 Documentation of the system catalogs, directed toward PostgreSQL developers
--> -->
...@@ -4478,6 +4478,13 @@ ...@@ -4478,6 +4478,13 @@
</para> </para>
</note> </note>
<note>
<para>
<literal>pg_class.relhastriggers</literal>
must be true if a table has any triggers in this catalog.
</para>
</note>
</sect1> </sect1>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -463,10 +463,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
*/ */
if (!vacstmt->vacuum) if (!vacstmt->vacuum)
{ {
vac_update_relstats(RelationGetRelid(onerel), vac_update_relstats(onerel,
RelationGetNumberOfBlocks(onerel), RelationGetNumberOfBlocks(onerel),
totalrows, hasindex, totalrows, hasindex, InvalidTransactionId);
InvalidTransactionId);
for (ind = 0; ind < nindexes; ind++) for (ind = 0; ind < nindexes; ind++)
{ {
...@@ -474,10 +473,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, ...@@ -474,10 +473,9 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt,
double totalindexrows; double totalindexrows;
totalindexrows = ceil(thisdata->tupleFract * totalrows); totalindexrows = ceil(thisdata->tupleFract * totalrows);
vac_update_relstats(RelationGetRelid(Irel[ind]), vac_update_relstats(Irel[ind],
RelationGetNumberOfBlocks(Irel[ind]), RelationGetNumberOfBlocks(Irel[ind]),
totalindexrows, false, totalindexrows, false, InvalidTransactionId);
InvalidTransactionId);
} }
/* report results to the stats collector, too */ /* report results to the stats collector, too */
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -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 * pg_class would've been obsoleted. Of course, this only works for
* fixed-size never-null columns, but these are. * 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 * 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 --- * VACUUM and have PROC_IN_VACUUM set, we mustn't do any updates ---
* somebody vacuuming pg_class might think they could delete a tuple * 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, ...@@ -673,9 +678,11 @@ vacuum_set_xid_limits(int freeze_min_age, bool sharedRel,
* ANALYZE. * ANALYZE.
*/ */
void 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) bool hasindex, TransactionId frozenxid)
{ {
Oid relid = RelationGetRelid(relation);
Relation rd; Relation rd;
HeapTuple ctup; HeapTuple ctup;
Form_pg_class pgcform; Form_pg_class pgcform;
...@@ -724,6 +731,18 @@ vac_update_relstats(Oid relid, BlockNumber num_pages, double num_tuples, ...@@ -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 * relfrozenxid should never go backward. Caller can pass
* InvalidTransactionId if it has no new data. * InvalidTransactionId if it has no new data.
...@@ -1269,9 +1288,9 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt) ...@@ -1269,9 +1288,9 @@ full_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
FreeSpaceMapVacuum(onerel); FreeSpaceMapVacuum(onerel);
/* update statistics in pg_class */ /* update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel), vacrelstats->rel_pages, vac_update_relstats(onerel,
vacrelstats->rel_tuples, vacrelstats->hasindex, vacrelstats->rel_pages, vacrelstats->rel_tuples,
FreezeLimit); vacrelstats->hasindex, FreezeLimit);
/* report results to the stats collector, too */ /* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
...@@ -3315,7 +3334,7 @@ scan_index(Relation indrel, double num_tuples) ...@@ -3315,7 +3334,7 @@ scan_index(Relation indrel, double num_tuples)
return; return;
/* now update statistics in pg_class */ /* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel), vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples, stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId); false, InvalidTransactionId);
...@@ -3385,7 +3404,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel, ...@@ -3385,7 +3404,7 @@ vacuum_index(VacPageList vacpagelist, Relation indrel,
return; return;
/* now update statistics in pg_class */ /* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel), vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples, stats->num_pages, stats->num_index_tuples,
false, InvalidTransactionId); false, InvalidTransactionId);
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* *
* *
* IDENTIFICATION * 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, ...@@ -186,11 +186,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
FreeSpaceMapVacuum(onerel); FreeSpaceMapVacuum(onerel);
/* Update statistics in pg_class */ /* Update statistics in pg_class */
vac_update_relstats(RelationGetRelid(onerel), vac_update_relstats(onerel,
vacrelstats->rel_pages, vacrelstats->rel_pages, vacrelstats->rel_tuples,
vacrelstats->rel_tuples, vacrelstats->hasindex, FreezeLimit);
vacrelstats->hasindex,
FreezeLimit);
/* report results to the stats collector, too */ /* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared, pgstat_report_vacuum(RelationGetRelid(onerel), onerel->rd_rel->relisshared,
...@@ -757,9 +755,8 @@ lazy_cleanup_index(Relation indrel, ...@@ -757,9 +755,8 @@ lazy_cleanup_index(Relation indrel,
return; return;
/* now update statistics in pg_class */ /* now update statistics in pg_class */
vac_update_relstats(RelationGetRelid(indrel), vac_update_relstats(indrel,
stats->num_pages, stats->num_pages, stats->num_index_tuples,
stats->num_index_tuples,
false, InvalidTransactionId); false, InvalidTransactionId);
ereport(elevel, ereport(elevel,
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 @@ ...@@ -22,9 +22,9 @@
#include "catalog/pg_rewrite.h" #include "catalog/pg_rewrite.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "rewrite/rewriteRemove.h" #include "rewrite/rewriteRemove.h"
#include "rewrite/rewriteSupport.h"
#include "utils/acl.h" #include "utils/acl.h"
#include "utils/fmgroids.h" #include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h" #include "utils/lsyscache.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/syscache.h" #include "utils/syscache.h"
...@@ -103,7 +103,6 @@ RemoveRewriteRuleById(Oid ruleOid) ...@@ -103,7 +103,6 @@ RemoveRewriteRuleById(Oid ruleOid)
Relation event_relation; Relation event_relation;
HeapTuple tuple; HeapTuple tuple;
Oid eventRelationOid; Oid eventRelationOid;
bool hasMoreRules;
/* /*
* Open the pg_rewrite relation. * Open the pg_rewrite relation.
...@@ -127,17 +126,13 @@ RemoveRewriteRuleById(Oid ruleOid) ...@@ -127,17 +126,13 @@ RemoveRewriteRuleById(Oid ruleOid)
elog(ERROR, "could not find tuple for rule %u", ruleOid); elog(ERROR, "could not find tuple for rule %u", ruleOid);
/* /*
* We had better grab AccessExclusiveLock so that we know no other rule * We had better grab AccessExclusiveLock to ensure that no queries
* additions/deletions are going on for this relation. Else we cannot set * are going on that might depend on this rule. (Note: a weaker lock
* relhasrules correctly. Besides, we don't want to be changing the * would suffice if it's not an ON SELECT rule.)
* ruleset while queries are executing on the rel.
*/ */
eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class; eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
event_relation = heap_open(eventRelationOid, AccessExclusiveLock); 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 * Now delete the pg_rewrite tuple for the rule
*/ */
...@@ -148,13 +143,10 @@ RemoveRewriteRuleById(Oid ruleOid) ...@@ -148,13 +143,10 @@ RemoveRewriteRuleById(Oid ruleOid)
heap_close(RewriteRelation, RowExclusiveLock); heap_close(RewriteRelation, RowExclusiveLock);
/* /*
* Set pg_class 'relhasrules' field correctly for event relation. * Issue shared-inval notice to force all backends (including me!) to
* * update relcache entries with the new rule set.
* 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!
*/ */
SetRelationRuleStatus(eventRelationOid, hasMoreRules, false); CacheInvalidateRelcache(event_relation);
/* Close rel, but keep lock till commit... */ /* Close rel, but keep lock till commit... */
heap_close(event_relation, NoLock); heap_close(event_relation, NoLock);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -721,6 +721,17 @@ RelationBuildRuleLock(Relation relation)
systable_endscan(rewrite_scan); systable_endscan(rewrite_scan);
heap_close(rewrite_desc, AccessShareLock); 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 * form a RuleLock and insert into relation
*/ */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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, ...@@ -130,7 +130,7 @@ extern void vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
extern void vac_open_indexes(Relation relation, LOCKMODE lockmode, extern void vac_open_indexes(Relation relation, LOCKMODE lockmode,
int *nindexes, Relation **Irel); int *nindexes, Relation **Irel);
extern void vac_close_indexes(int nindexes, Relation *Irel, LOCKMODE lockmode); 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, BlockNumber num_pages,
double num_tuples, double num_tuples,
bool hasindex, bool hasindex,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册