MyCATApache/Mycat-Server · error · java.sql.SQLNonTransientException
包含不是ER分片的表
Error message
%s包含不是ER分片的表
What it means
In the ER batch-insert routing flow, erFlag is set when the statement mix looks like an ER (global/ER-consistency) insert, but validation finds that the statement set includes tables that are not part of any ER relationship. Mycat cannot guarantee cross-shard consistency for such a mix, so it aborts with SQLNonTransientException '%s包含不是ER分片的表' ('%s contains tables that are not ER-sharded').
Solutions
- Separate statements touching non-ER tables from the ER batch and send them individually
- Declare all related tables in schema.xml as part of the ER relationship (childTable with parentKey/joinKey) if they belong together
- Remove the non-ER table from the batched statement set
- Review how erFlag is set — ensure only genuine ER inserts go through this routing path
Example fix
// before (one batch, mixed tables) INSERT INTO orders(...) VALUES(...); INSERT INTO t_global(...) VALUES(...); // after: send ER insert alone INSERT INTO orders(...) VALUES(...); // then separately INSERT INTO t_global(...) VALUES(...);
Defensive patterns
Strategy: validation
Validate before calling
// Before batching statements, verify every target table is part of an ER relationship
for (String t : targetTables) {
if (!erTables.contains(t)) throw new IllegalStateException("non-ER table " + t + " cannot be in an ER batch");
} Try / catch
catch (SQLNonTransientException e) { if (e.getMessage().endsWith("包含不是ER分片的表")) { /* split batch by ER membership and resend */ } throw e; } Prevention
- Keep ER groups complete in schema.xml — declare every related table as childTable
- Group outbound statements by ER membership before batching
- After schema changes, re-verify which tables participate in ER routing
When it happens
Trigger: routeByER returns true for erFlag, yet one or more tables in the multi-table/batch statement are ordinary (non-childTable, non-ER-group) tables in schema.xml; the check after the per-statement loop throws.
Common situations: Mixed multi-statement batches inserting into both ER and non-ER tables; schema.xml where only some joined tables are declared as childTable; renaming/adding a table to an ER group without updating all related tables; sending several INSERTs in one packet assuming Mycat handles them transactionally as ER.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- ChildTable multi insert not provided
- batch not supported
- A batchSize of: with batchStatsAt of: will overrun the…
- Both batchStartsAt and batchSize must be positive but got…
- The ring buffer cannot accommodate
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/300f0fc24ff214c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:2039
if(processedInsert==false){
RouteResultset executeRrs = RouterUtil.routeToSingleNode(rrs, result, origSQL);
sc.getSession2().execute(executeRrs, ServerParse.INSERT);
}
}
@Override
public void onFailure(Throwable t) {
StringBuilder s = new StringBuilder();
LOGGER.warn(s.append(sc.getSession2()).append(origSQL).toString() +
" err:" + t.getMessage());
sc.writeErrMessage(ErrorCode.ER_PARSE_ERROR, t.getMessage() + " " + s.toString());
}
}, MycatServer.getInstance().
getListeningExecutorService());
} else if(erFlag) {
throw new SQLNonTransientException(String.format("%s包含不是ER分片的表", origSQL));
}
}
return erFlag;
}
/**
* 寻找joinKey的索引
*
* @param columns
* @param joinKey
* @return -1表示没找到,>=0表示找到了
*/
private static int getJoinKeyIndex(List<SQLExpr> columns, String joinKey) {
for (int i = 0; i < columns.size(); i++) {
String col = StringUtil.removeBackquote(columns.get(i).toString()).toUpperCase();
if (col.equals(joinKey)) {
View on GitHub (pinned to 65f8d8beb7)