diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index c09ca7e..f1e447d 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -584,7 +584,8 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
 							visibilitymap_count(onerel),
 							hasindex,
 							InvalidTransactionId,
-							InvalidMultiXactId);
+							InvalidMultiXactId,
+							!(vacstmt->options & VACOPT_VACUUM));
 
 	/*
 	 * Same for indexes. Vacuum always scans all indexes, so if we're part of
@@ -605,7 +606,8 @@ do_analyze_rel(Relation onerel, VacuumStmt *vacstmt,
 								0,
 								false,
 								InvalidTransactionId,
-								InvalidMultiXactId);
+								InvalidMultiXactId,
+								!(vacstmt->options & VACOPT_VACUUM));
 		}
 	}
 
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index e5fefa3..6f05a74 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -672,7 +672,7 @@ vac_update_relstats(Relation relation,
 					BlockNumber num_pages, double num_tuples,
 					BlockNumber num_all_visible_pages,
 					bool hasindex, TransactionId frozenxid,
-					MultiXactId minmulti)
+					MultiXactId minmulti, bool is_vacuum)
 {
 	Oid			relid = RelationGetRelid(relation);
 	Relation	rd;
@@ -768,9 +768,21 @@ vac_update_relstats(Relation relation,
 		dirty = true;
 	}
 
-	/* If anything changed, write out the tuple. */
+	/*
+	 * If anything changed, write out the tuple. For ANALYZE, this change
+	 * needs to be transactional as this query can be run in a transaction
+	 * block.
+	 */
 	if (dirty)
-		heap_inplace_update(rd, ctup);
+	{
+		if (is_vacuum)
+		{
+			simple_heap_update(rd, &ctup->t_self, ctup);
+			CatalogUpdateIndexes(rd, ctup);
+		}
+		else
+			heap_inplace_update(rd, ctup);
+	}
 
 	heap_close(rd, RowExclusiveLock);
 }
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 5d6d031..3778d9d 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -309,7 +309,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
 						new_rel_allvisible,
 						vacrelstats->hasindex,
 						new_frozen_xid,
-						new_min_multi);
+						new_min_multi,
+						false);
 
 	/* report results to the stats collector, too */
 	new_live_tuples = new_rel_tuples - vacrelstats->new_dead_tuples;
@@ -1377,7 +1378,8 @@ lazy_cleanup_index(Relation indrel,
 							0,
 							false,
 							InvalidTransactionId,
-							InvalidMultiXactId);
+							InvalidMultiXactId,
+							false);
 
 	ereport(elevel,
 			(errmsg("index \"%s\" now contains %.0f row versions in %u pages",
diff --git a/src/include/commands/vacuum.h b/src/include/commands/vacuum.h
index d33552a..9781926 100644
--- a/src/include/commands/vacuum.h
+++ b/src/include/commands/vacuum.h
@@ -156,7 +156,8 @@ extern void vac_update_relstats(Relation relation,
 					BlockNumber num_all_visible_pages,
 					bool hasindex,
 					TransactionId frozenxid,
-					MultiXactId minmulti);
+					MultiXactId minmulti,
+					bool is_vacuum);
 extern void vacuum_set_xid_limits(Relation rel,
 					  int freeze_min_age, int freeze_table_age,
 					  int multixact_freeze_min_age,
