MyCATApache/Mycat-Server · error · SQLNonTransientException

can't suport district table + tableName + schema: +…

Error message

can't suport district table  + tableName +  schema: + schema.getName() +  for mutiple dataNode  + dataNodes

What it means

A district (dist) table must map to exactly one data node in this routing path; RouterUtil reads tableConfig.getDataNodes() and throws SQLNonTransientException when more than one dataNode is configured, since it picks dataNodes.get(0) and cannot distribute.

Solutions

  1. Configure exactly one dataNode for the dist table in schema.xml (dataNode="dn1") and reload
  2. Use multiple dist tables (orders$0, orders$1) each on its own dataNode instead of one table on many nodes
  3. Route as a normal sharded table (with rule/partition column) if multi-node distribution is actually needed

Example fix

// before (schema.xml)
<table name="orders" distTables="orders$0" dataNode="dn1,dn2"/>
// after
<table name="orders" distTables="orders$0" dataNode="dn1"/>
Defensive patterns

Strategy: validation

Validate before calling

// validate config: dist tables must map to exactly one dataNode
// parse schema.xml before deploy
for (TableDef t : distTables) {
    if (t.dataNodes.size() != 1)
        throw new IllegalStateException("Dist table " + t.name + " must have exactly one dataNode, got " + t.dataNodes);
}

Try / catch

try {
    execute(sql);
} catch (SQLNonTransientException e) {
    if (e.getMessage().contains("for mutiple dataNode"))
        throw new IllegalStateException("Fix schema.xml: dist table needs a single dataNode", e);
    throw e;
}

Prevention

When it happens

Trigger: Routing a dist table whose <table> declaration in schema.xml lists multiple dataNodes (dataNodes.size()>1), e.g. dataNode="dn1,dn2".

Common situations: Copy-pasted sharded table config applied to a dist table; schema.xml edited to scale out nodes without realizing dist-table routing requires a single node per dist table; mixing sharded-table and dist-table semantics.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/a999532002aa0adb. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:1453

            String msg = "can't find table define in schema " + tableName + " schema:" + schema.getName();
            LOGGER.warn(msg);
            throw new SQLNonTransientException(msg);
        }
        if(tableConfig.isGlobalTable()){
            String msg = "can't suport district table  " + tableName + " schema:" + schema.getName() + " for global table ";
            LOGGER.warn(msg);
            throw new SQLNonTransientException(msg);
        }
        String partionCol = tableConfig.getPartitionColumn();
    //  String primaryKey = tableConfig.getPrimaryKey();
        //boolean isLoadData=false;
    
        Set<String> tablesRouteSet = new HashSet<String>();
    
        List<String> dataNodes = tableConfig.getDataNodes();
        if(dataNodes.size()>1){
            String msg = "can't suport district table  " + tableName + " schema:" + schema.getName() + " for mutiple dataNode " + dataNodes;
            LOGGER.warn(msg);
            throw new SQLNonTransientException(msg);
        }
        String dataNode = dataNodes.get(0);
    
        RouteResultsetNode[] nodes = null;
        //主键查找缓存暂时不实现
        if(tablesAndConditions.isEmpty()){
            List<String> subTables = tableConfig.getDistTables();
            tablesRouteSet.addAll(subTables);
    
            nodes = getNode(rrs, orgSql, tablesRouteSet, dataNode, false, tableName);
        } else {
            if (entry == null) {
                for(Map.Entry<String, Map<String, Set<ColumnRoutePair>>> entry1 : tablesAndConditions.entrySet()) {
                    //boolean isFoundPartitionValue = partionCol != null && entry.getValue().get(partionCol) != null;
                    setNodes(rrs, tableConfig, partionCol, tablesRouteSet, entry1);
                }
            } else {

View on GitHub (pinned to 65f8d8beb7)