Commit
c89ea7fe8d1686c78a31781449342ca2e056caea disabled running ANALYZE on
remote coordinators when done inside a transaction block. But per report from
Virendra Kumar, this has also affected ANALYZE outside transaction blocks
because the existing code was using own transactions only either for autovacuum
processes or when more than one tables are analyzed at the same time.
Work-around this by always using own transaction except when ANALYZE is
triggered by REFRESH MATERIALIZED VIEW, which doesn't like closing the current
transaction.
get_namespace_name(RelationGetNamespace(tempRel)),
RelationGetRelationName(tempRel), -1);
stmt->relation = rv;
- stmt->options = VACOPT_ANALYZE;
+ stmt->options = VACOPT_ANALYZE | VACOPT_USE_OUTERXACT;
ExecVacuum(stmt, true);
}
#endif
VacuumStmt *stmt = makeNode(VacuumStmt);
RangeVar *rv = makeRangeVar(tempschema, diffname, -1);
stmt->relation = rv;
- stmt->options = VACOPT_ANALYZE;
+ stmt->options = VACOPT_ANALYZE | VACOPT_USE_OUTERXACT;
ExecVacuum(stmt, true);
}
#endif
* problematic.)
*
* For ANALYZE (no VACUUM): if inside a transaction block, we cannot
- * start/commit our own transactions. Also, there's no need to do so if
- * only processing one relation. For multiple relations when not within a
- * transaction block, and also in an autovacuum worker, use own
+ * start/commit our own transactions. For multiple relations when not
+ * within a transaction block, and also in an autovacuum worker, use own
* transactions so we can release locks sooner.
+ *
+ * XL: We use own transactions even for a single relation case since that
+ * allows us to safely analyze the remote coordinators too. We make
+ * exception while running implicit ANALYZE as part of REFRESH MATERIALIZED
+ * VIEW since that case demands that we must not close the current
+ * transaction.
*/
if (options & VACOPT_VACUUM)
use_own_xacts = true;
use_own_xacts = false;
else if (list_length(relations) > 1)
use_own_xacts = true;
- else
+ else if (options & VACOPT_USE_OUTERXACT)
use_own_xacts = false;
+ else
+ use_own_xacts = true;
+
}
/*
VACOPT_NOWAIT = 1 << 5, /* don't wait to get lock (autovacuum only) */
VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */
VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7, /* don't skip any pages */
- VACOPT_COORDINATOR = 1 << 8 /* don't trigger analyze on the datanodes, but
+ VACOPT_COORDINATOR = 1 << 8,/* don't trigger analyze on the datanodes, but
* just collect existing info and populate
* coordinator side stats.
*/
+ /* do not use our own transactions */
+ VACOPT_USE_OUTERXACT = 1 << 9
} VacuumOption;
typedef struct VacuumStmt