static BufferAccessStrategy vac_strategy;
-static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh);
+static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
+ bool inh, bool in_outer_xact);
static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
int samplesize);
static bool BlockSampler_HasMore(BlockSampler bs);
* analyze_rel() -- analyze one relation
*/
void
-analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
+analyze_rel(Oid relid, VacuumStmt *vacstmt,
+ bool in_outer_xact, BufferAccessStrategy bstrategy)
{
Relation onerel;
/*
* Do the normal non-recursive ANALYZE.
*/
- do_analyze_rel(onerel, vacstmt, false);
+ do_analyze_rel(onerel, vacstmt, false, in_outer_xact);
/*
* If there are child tables, do recursive ANALYZE.
*/
if (onerel->rd_rel->relhassubclass)
- do_analyze_rel(onerel, vacstmt, true);
+ do_analyze_rel(onerel, vacstmt, true, in_outer_xact);
/*
* Close source relation now, but keep lock so that no one deletes it
* do_analyze_rel() -- analyze one relation, recursively or not
*/
static void
-do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh)
+do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
+ bool inh, bool in_outer_xact)
{
int attr_cnt,
tcnt,
if (!inh)
vac_update_relstats(onerel,
RelationGetNumberOfBlocks(onerel),
- totalrows, hasindex, InvalidTransactionId);
+ totalrows,
+ hasindex,
+ InvalidTransactionId,
+ in_outer_xact);
/*
* Same for indexes. Vacuum always scans all indexes, so if we're part of
totalindexrows = ceil(thisdata->tupleFract * totalrows);
vac_update_relstats(Irel[ind],
RelationGetNumberOfBlocks(Irel[ind]),
- totalindexrows, false, InvalidTransactionId);
+ totalindexrows,
+ false,
+ InvalidTransactionId,
+ in_outer_xact);
}
}
*/
if (use_own_xacts)
{
+ Assert(!in_outer_xact);
+
/* ActiveSnapshot is not set by autovacuum */
if (ActiveSnapshotSet())
PopActiveSnapshot();
PushActiveSnapshot(GetTransactionSnapshot());
}
- analyze_rel(relid, vacstmt, vac_strategy);
+ analyze_rel(relid, vacstmt, in_outer_xact, vac_strategy);
if (use_own_xacts)
{
* DDL flags such as relhasindex, by clearing them if no longer correct.
* It's safe to do this in VACUUM, which can't run in parallel with
* CREATE INDEX/RULE/TRIGGER and can't be part of a transaction block.
- * However, it's *not* safe to do it in an ANALYZE that's within a
- * transaction block, because for example the current transaction might
+ * However, it's *not* safe to do it in an ANALYZE that's within an
+ * outer transaction, because for example the current transaction might
* have dropped the last index; then we'd think relhasindex should be
* cleared, but if the transaction later rolls back this would be wrong.
- * So we refrain from updating the DDL flags if we're inside a
- * transaction block. This is OK since postponing the flag maintenance
- * is always allowable.
+ * So we refrain from updating the DDL flags if we're inside an outer
+ * transaction. This is OK since postponing the flag maintenance is
+ * always allowable.
*
* This routine is shared by VACUUM and ANALYZE.
*/
void
vac_update_relstats(Relation relation,
BlockNumber num_pages, double num_tuples,
- bool hasindex, TransactionId frozenxid)
+ bool hasindex, TransactionId frozenxid,
+ bool in_outer_xact)
{
Oid relid = RelationGetRelid(relation);
Relation rd;
dirty = true;
}
- /* Apply DDL updates, but not inside a transaction block (see above) */
+ /* Apply DDL updates, but not inside an outer transaction (see above) */
- if (!IsTransactionBlock())
+ if (!in_outer_xact)
{
/*
* If we didn't find any indexes, reset relhasindex.
vac_update_relstats(onerel,
new_rel_pages, new_rel_tuples,
vacrelstats->hasindex,
- new_frozen_xid);
+ new_frozen_xid,
+ false);
/* report results to the stats collector, too */
pgstat_report_vacuum(RelationGetRelid(onerel),
if (!stats->estimated_count)
vac_update_relstats(indrel,
stats->num_pages, stats->num_index_tuples,
- false, InvalidTransactionId);
+ false,
+ InvalidTransactionId,
+ false);
ereport(elevel,
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
BlockNumber num_pages,
double num_tuples,
bool hasindex,
- TransactionId frozenxid);
+ TransactionId frozenxid,
+ bool in_outer_xact);
extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age,
bool sharedRel,
TransactionId *oldestXmin,
/* in commands/analyze.c */
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt,
- BufferAccessStrategy bstrategy);
+ bool in_outer_xact, BufferAccessStrategy bstrategy);
#endif /* VACUUM_H */