prestodb/presto · error · PrestoException

MV_MISSING_TOO_MUCH_DATA

MV_MISSING_TOO_MUCH_DATA

Error message

%s misses too many partitions or is never refreshed and may incur high cost. Consider refreshing with predicates first.

What it means

Presto throws this while executing REFRESH MATERIALIZED VIEW when the materialized view is missing too many of its source partitions (or has never been refreshed at all) and the session does not allow a full refresh. A full refresh in that state would rebuild the entire view, which can be extremely expensive. The engine refuses and suggests running a partitioned (predicated) refresh instead.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:1072

        private Map<SchemaTableName, Expression> analyzeAutoRefreshMaterializedView(
                RefreshMaterializedView node,
                QualifiedObjectName viewName)
        {
            MaterializedViewStatus viewStatus = session.getRuntimeStats().recordWallTime(
                    RuntimeMetricName.GET_MATERIALIZED_VIEW_STATUS_TIME_NANOS,
                    () -> metadataResolver.getMaterializedViewStatus(viewName, TupleDomain.all()));
            Map<SchemaTableName, MaterializedViewStatus.MaterializedDataPredicates> missingPartitionsPerTable =
                    viewStatus.getPartitionsFromBaseTables();

            if (viewStatus.isFullyMaterialized() || missingPartitionsPerTable.isEmpty()) {
                warningCollector.add(new PrestoWarning(SEMANTIC_WARNING,
                        format("Materialized view %s is already fully refreshed", viewName)));
                return ImmutableMap.of();
            }
            if ((viewStatus.isNotMaterialized() || viewStatus.isTooManyPartitionsMissing()) &&
                    !SystemSessionProperties.isMaterializedViewAllowFullRefreshEnabled(session)) {
                throw new PrestoException(MV_MISSING_TOO_MUCH_DATA,
                        format("%s misses too many partitions or is never refreshed and may incur high cost. " +
                                "Consider refreshing with predicates first.", viewName.toString()));
            }

            return MaterializedViewUtils.generatePredicatesForMissingPartitions(missingPartitionsPerTable, metadata);
        }

        private Optional<RelationType> analyzeBaseTableForRefreshMaterializedView(Table baseTable, Optional<Scope> scope)
        {
            checkState(analysis.getStatement() instanceof RefreshMaterializedView, "Not analyzing RefreshMaterializedView statement");

            RefreshMaterializedView refreshMaterializedView = (RefreshMaterializedView) analysis.getStatement();
            QualifiedObjectName viewName = createQualifiedObjectName(session, refreshMaterializedView.getTarget(), refreshMaterializedView.getTarget().getName(), metadata);

            // Use AllowAllAccessControl; otherwise Analyzer will check SELECT permission on the materialized view, which is not necessary.
            StatementAnalyzer viewAnalyzer = new StatementAnalyzer(analysis, metadata, sqlParser, new AllowAllAccessControl(), session, warningCollector);
            Scope viewScope = viewAnalyzer.analyze(refreshMaterializedView.getTarget(), scope);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Run a refresh with predicates over subsets of partitions: REFRESH MATERIALIZED VIEW mv WHERE <partition column> BETWEEN ... and iterate until fully caught up.
  2. Set the session property SET SESSION allow_full_refresh_for_materialized_view = true (or the equivalent SystemSessionProperties flag) if a full refresh is acceptable.
  3. Schedule regular incremental refreshes so the missing-partition count never crosses the threshold.
  4. Verify the connector's staleness/partition-missing reporting is correct (e.g., stale partition metadata) if the view is actually fresh.

Example fix

// before
REFRESH MATERIALIZED VIEW sales_mv;
// after
REFRESH MATERIALIZED VIEW sales_mv WHERE day >= DATE '2026-08-01';
-- or enable full refresh for this session:
SET SESSION allow_full_refresh_for_materialized_view = true;
REFRESH MATERIALIZED VIEW sales_mv;
Defensive patterns

Strategy: validation

Validate before calling

// Check staleness before refreshing
Row stale = query("SELECT count(*) FROM " + mvStatusTable + " WHERE missing_partitions > threshold");
boolean needsPredicatedRefresh = stale.count > 0 && !session.getAllowFullRefresh();

Try / catch

try {
    refreshMaterializedView(mv);
} catch (PrestoException e) {
    if ("MV_MISSING_TOO_MUCH_DATA".equals(e.getErrorCode().getName())) {
        refreshWithPartitionPredicates(mv); // incremental fallback
    } else throw e;
}

Prevention

When it happens

Trigger: Running REFRESH MATERIALIZED VIEW on a view whose connector-reported status returns isNotMaterialized() or isTooManyPartitionsMissing(), while SystemSessionProperties.isMaterializedViewAllowFullRefreshEnabled(session) is false.

Common situations: First-ever refresh of a newly created materialized view whose base tables are large; a view that has not been refreshed for a long time so most partitions became stale/missing; clusters where the allow-full-refresh session property is deliberately disabled to protect resources.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/34a32f93d594a23a. Report an issue: GitHub.