Content-Length: 568949 | pFad | http://github.com/postgrespro/postgres/commit/fcf0246b2c58d4b7e480ccb11e1bdaeef023a4f6

CA Test IsInTransactionChain, not IsTransactionBlock, in vac_update_rels… · postgrespro/postgres@fcf0246 · GitHub
Skip to content

Commit fcf0246

Browse files
committed
Test IsInTransactionChain, not IsTransactionBlock, in vac_update_relstats.
As noted by Noah Misch, my initial cut at fixing bug #11638 didn't cover all cases where ANALYZE might be invoked in an unsafe context. We need to test the result of IsInTransactionChain not IsTransactionBlock; which is notationally a pain because IsInTransactionChain requires an isTopLevel flag, which would have to be passed down through several levels of callers. I chose to pass in_outer_xact (ie, the result of IsInTransactionChain) rather than isTopLevel per se, as that seemed marginally more apropos for the intermediate functions to know about.
1 parent 6ec1c3e commit fcf0246

File tree

4 files changed

+36
-20
lines changed

4 files changed

+36
-20
lines changed

src/backend/commands/analyze.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ static MemoryContext anl_context = NULL;
8484
static BufferAccessStrategy vac_strategy;
8585

8686

87-
static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh);
87+
static void do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
88+
bool inh, bool in_outer_xact);
8889
static void BlockSampler_Init(BlockSampler bs, BlockNumber nblocks,
8990
int samplesize);
9091
static bool BlockSampler_HasMore(BlockSampler bs);
@@ -116,7 +117,8 @@ static bool std_typanalyze(VacAttrStats *stats);
116117
* analyze_rel() -- analyze one relation
117118
*/
118119
void
119-
analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
120+
analyze_rel(Oid relid, VacuumStmt *vacstmt,
121+
bool in_outer_xact, BufferAccessStrategy bstrategy)
120122
{
121123
Relation onerel;
122124

@@ -228,13 +230,13 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
228230
/*
229231
* Do the normal non-recursive ANALYZE.
230232
*/
231-
do_analyze_rel(onerel, vacstmt, false);
233+
do_analyze_rel(onerel, vacstmt, false, in_outer_xact);
232234

233235
/*
234236
* If there are child tables, do recursive ANALYZE.
235237
*/
236238
if (onerel->rd_rel->relhassubclass)
237-
do_analyze_rel(onerel, vacstmt, true);
239+
do_analyze_rel(onerel, vacstmt, true, in_outer_xact);
238240

239241
/*
240242
* Close source relation now, but keep lock so that no one deletes it
@@ -257,7 +259,8 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
257259
* do_analyze_rel() -- analyze one relation, recursively or not
258260
*/
259261
static void
260-
do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh)
262+
do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
263+
bool inh, bool in_outer_xact)
261264
{
262265
int attr_cnt,
263266
tcnt,
@@ -534,7 +537,10 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh)
534537
if (!inh)
535538
vac_update_relstats(onerel,
536539
RelationGetNumberOfBlocks(onerel),
537-
totalrows, hasindex, InvalidTransactionId);
540+
totalrows,
541+
hasindex,
542+
InvalidTransactionId,
543+
in_outer_xact);
538544

539545
/*
540546
* Same for indexes. Vacuum always scans all indexes, so if we're part of
@@ -551,7 +557,10 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt, bool inh)
551557
totalindexrows = ceil(thisdata->tupleFract * totalrows);
552558
vac_update_relstats(Irel[ind],
553559
RelationGetNumberOfBlocks(Irel[ind]),
554-
totalindexrows, false, InvalidTransactionId);
560+
totalindexrows,
561+
false,
562+
InvalidTransactionId,
563+
in_outer_xact);
555564
}
556565
}
557566

src/backend/commands/vacuum.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
199199
*/
200200
if (use_own_xacts)
201201
{
202+
Assert(!in_outer_xact);
203+
202204
/* ActiveSnapshot is not set by autovacuum */
203205
if (ActiveSnapshotSet())
204206
PopActiveSnapshot();
@@ -241,7 +243,7 @@ vacuum(VacuumStmt *vacstmt, Oid relid, bool do_toast,
241243
PushActiveSnapshot(GetTransactionSnapshot());
242244
}
243245

244-
analyze_rel(relid, vacstmt, vac_strategy);
246+
analyze_rel(relid, vacstmt, in_outer_xact, vac_strategy);
245247

246248
if (use_own_xacts)
247249
{
@@ -555,20 +557,21 @@ vac_estimate_reltuples(Relation relation, bool is_analyze,
555557
* DDL flags such as relhasindex, by clearing them if no longer correct.
556558
* It's safe to do this in VACUUM, which can't run in parallel with
557559
* CREATE INDEX/RULE/TRIGGER and can't be part of a transaction block.
558-
* However, it's *not* safe to do it in an ANALYZE that's within a
559-
* transaction block, because for example the current transaction might
560+
* However, it's *not* safe to do it in an ANALYZE that's within an
561+
* outer transaction, because for example the current transaction might
560562
* have dropped the last index; then we'd think relhasindex should be
561563
* cleared, but if the transaction later rolls back this would be wrong.
562-
* So we refrain from updating the DDL flags if we're inside a
563-
* transaction block. This is OK since postponing the flag maintenance
564-
* is always allowable.
564+
* So we refrain from updating the DDL flags if we're inside an outer
565+
* transaction. This is OK since postponing the flag maintenance is
566+
* always allowable.
565567
*
566568
* This routine is shared by VACUUM and ANALYZE.
567569
*/
568570
void
569571
vac_update_relstats(Relation relation,
570572
BlockNumber num_pages, double num_tuples,
571-
bool hasindex, TransactionId frozenxid)
573+
bool hasindex, TransactionId frozenxid,
574+
bool in_outer_xact)
572575
{
573576
Oid relid = RelationGetRelid(relation);
574577
Relation rd;
@@ -599,9 +602,9 @@ vac_update_relstats(Relation relation,
599602
dirty = true;
600603
}
601604

602-
/* Apply DDL updates, but not inside a transaction block (see above) */
605+
/* Apply DDL updates, but not inside an outer transaction (see above) */
603606

604-
if (!IsTransactionBlock())
607+
if (!in_outer_xact)
605608
{
606609
/*
607610
* If we didn't find any indexes, reset relhasindex.

src/backend/commands/vacuumlazy.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
266266
vac_update_relstats(onerel,
267267
new_rel_pages, new_rel_tuples,
268268
vacrelstats->hasindex,
269-
new_frozen_xid);
269+
new_frozen_xid,
270+
false);
270271

271272
/* report results to the stats collector, too */
272273
pgstat_report_vacuum(RelationGetRelid(onerel),
@@ -1091,7 +1092,9 @@ lazy_cleanup_index(Relation indrel,
10911092
if (!stats->estimated_count)
10921093
vac_update_relstats(indrel,
10931094
stats->num_pages, stats->num_index_tuples,
1094-
false, InvalidTransactionId);
1095+
false,
1096+
InvalidTransactionId,
1097+
false);
10951098

10961099
ereport(elevel,
10971100
(errmsg("index \"%s\" now contains %.0f row versions in %u pages",

src/include/commands/vacuum.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ extern void vac_update_relstats(Relation relation,
150150
BlockNumber num_pages,
151151
double num_tuples,
152152
bool hasindex,
153-
TransactionId frozenxid);
153+
TransactionId frozenxid,
154+
bool in_outer_xact);
154155
extern void vacuum_set_xid_limits(int freeze_min_age, int freeze_table_age,
155156
bool sharedRel,
156157
TransactionId *oldestXmin,
@@ -165,6 +166,6 @@ extern void lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
165166

166167
/* in commands/analyze.c */
167168
extern void analyze_rel(Oid relid, VacuumStmt *vacstmt,
168-
BufferAccessStrategy bstrategy);
169+
bool in_outer_xact, BufferAccessStrategy bstrategy);
169170

170171
#endif /* VACUUM_H */

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/postgrespro/postgres/commit/fcf0246b2c58d4b7e480ccb11e1bdaeef023a4f6

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy