apache/shardingsphere · error · DataSourceIntersectionNotFoundException

37

37

Error message

Can not find actual data source intersection for logic tables '%s'.

What it means

DataSourceIntersectionNotFoundException is thrown by ShardingUnicastRouteEngine when a unicast statement (one that only needs any single data node, e.g. metadata queries/SHOW-like routing) references multiple sharded tables whose actual data source sets have no common data source. The engine intersects the data source names of each involved table's actualDataNodes and requires a non-empty intersection to pick one node; empty intersection means no single database contains all referenced tables.

Source

Thrown at features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/route/engine/type/unicast/ShardingUnicastRouteEngine.java:108

    private void routeWithMultipleTables(final RouteContext routeContext, final ShardingRule shardingRule) {
        List<RouteMapper> tableMappers = new ArrayList<>(logicTables.size());
        Set<String> availableDataSourceNames = Collections.emptySet();
        boolean first = true;
        for (String each : logicTables) {
            ShardingTable shardingTable = shardingRule.getShardingTable(each);
            DataNode dataNode = shardingTable.getActualDataNodes().get(0);
            tableMappers.add(new RouteMapper(each, dataNode.getTableName()));
            Set<String> currentDataSourceNames = shardingTable.getActualDataNodes().stream().map(DataNode::getDataSourceName).collect(
                    Collectors.toCollection(() -> new LinkedHashSet<>(shardingTable.getActualDataSourceNames().size(), 1F)));
            if (first) {
                availableDataSourceNames = currentDataSourceNames;
                first = false;
            } else {
                availableDataSourceNames = Sets.intersection(availableDataSourceNames, currentDataSourceNames);
            }
        }
        if (availableDataSourceNames.isEmpty()) {
            throw new DataSourceIntersectionNotFoundException(logicTables);
        }
        String dataSourceName = getDataSourceName(availableDataSourceNames);
        routeContext.getRouteUnits().add(new RouteUnit(new RouteMapper(dataSourceName, dataSourceName), tableMappers));
    }
    
    private String getRandomDataSourceName(final Collection<String> dataSourceNames) {
        Collection<String> usedDataSourceNames = connectionContext.getUsedDataSourceNames();
        List<String> availableDataSourceNames = new ArrayList<>(usedDataSourceNames.isEmpty() ? dataSourceNames : usedDataSourceNames);
        return availableDataSourceNames.get(ThreadLocalRandom.current().nextInt(availableDataSourceNames.size()));
    }
}

View on GitHub (pinned to e952770a21)

Solutions

  1. Ensure every sharded table referenced by the statement has at least one actual data node in a shared data source (overlap the actualDataNodes expressions).
  2. If tables intentionally live in disjoint data sources, route the query to a federation/data-source solution or query the tables separately.
  3. Fix actualDataNodes typos: verify with SHOW SHARDING TABLE RULES that each table's data sources are as intended.

Example fix

# before: disjoint data sources
t_order:      actualDataNodes: ds_${0..1}.t_order_${0..3}
t_inventory:  actualDataNodes: ds_${2..3}.t_inventory

# after: shared data source overlap
t_order:      actualDataNodes: ds_${0..1}.t_order_${0..3}
t_inventory:  actualDataNodes: ds_${0..1}.t_inventory
Defensive patterns

Strategy: validation

Validate before calling

// For unicast-routed statements, assert a shared data source exists
Set<String> dsOf(ShardingTable t) { return t.getActualDataNodes().stream().map(DataNode::getDataSourceName).collect(Collectors.toSet()); }
Set<String> intersection = new HashSet<>(dsOf(tableA));
intersection.retainAll(dsOf(tableB));
if (intersection.isEmpty()) { throw new IllegalStateException("No common data source for unicast query"); }

Try / catch

try {
    rs = stmt.executeQuery(sql);
} catch (final DataSourceIntersectionNotFoundException ex) {
    // split the statement per data source or fix rule overlap
}

Prevention

When it happens

Trigger: A statement routed unicast touching >=2 sharding tables where table A's actualDataNodes live only in ds_0/ds_1 and table B's only in ds_2/ds_3 — Sets.intersection across the per-table data source sets yields an empty set.

Common situations: Tables sharded to disjoint data source pools (per-tenant or per-region datasources); misconfigured actualDataNodes where one table's expressions omit a data source; growing a cluster by adding a new data source to some tables only.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/2a4ac1c6d0ef6a0b. Report an issue: GitHub.