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
- Ensure every sharded table referenced by the statement has at least one actual data node in a shared data source (overlap the actualDataNodes expressions).
- If tables intentionally live in disjoint data sources, route the query to a federation/data-source solution or query the tables separately.
- 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
- Design table placement so tables used together share at least one data source.
- When scaling out data sources, update all related sharding rules together.
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.