MyCATApache/Mycat-Server · critical · RuntimeException
${e}
Error message
${e} What it means
loadColumn queries INFORMATION_SCHEMA.COLUMNS to map a table's column ordinals during migration. Any SQLException (connection failure, bad credentials, missing table/schema, SQL syntax) is wrapped in a RuntimeException, so the original JDBC error surfaces as an opaque '${e}' message. It aborts binlog replay because column metadata is mandatory.
Solutions
- Verify the MySQL host, port, username and password used by the migration task are correct and the server is reachable (mysql -h ... -P ...).
- Confirm the table and database names in the migration task exist on the source node.
- Grant the migration user SELECT on INFORMATION_SCHEMA and the target schema.
- Unwrap the cause ('Caused by' in the stack trace) to see the actual SQLException and fix accordingly.
Example fix
// before
list = executeQuery(con, "select COLUMN_NAME ... where table_name='" + table + "' and TABLE_SCHEMA='" + database + "'");
// after
// use parameter binding / verify identifiers first
if (!tableExists(con, database, table)) {
throw new IllegalStateException("Table " + database + "." + table + " not found on source node");
} Defensive patterns
Strategy: try-catch
Validate before calling
// before migration
try (Connection c = DriverManager.getConnection(url, user, pass)) {
ResultSet rs = c.createStatement().executeQuery(
"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + table + "' AND TABLE_SCHEMA='" + db + "'");
rs.next();
if (rs.getInt(1) == 0) throw new IllegalStateException("table/columns missing on source");
} Try / catch
try { migrationStep(); } catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof SQLException) { /* reconnect / fix creds / retry */ }
throw e;
} Prevention
- Pre-validate JDBC connectivity and credentials before starting migration
- Confirm the table exists in the source schema before binlog replay
- Grant the migration account SELECT on INFORMATION_SCHEMA
- Always log e.getCause() to see the real SQLException
When it happens
Trigger: DriverManager.getConnection to jdbc:mysql://hostname:port fails; the table or database name is wrong so INFORMATION_SCHEMA returns nothing useful; MySQL rejects the query due to privileges or connectivity loss mid-migration.
Common situations: Wrong MySQL host/port/credentials in migration config; the migrated table was dropped or renamed; network/firewall blocks the data node; user lacks privileges on INFORMATION_SCHEMA for that schema.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- ${e}
- global seq and share join and special…
- fetching sequence can not support the db driver
- CallableStatement not supported
- Unexpected exception
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/37421931d3ae8557.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/migrate/BinlogStream.java:193
private final Map<Long, TableMapEventData> tablesById = new HashMap<Long, TableMapEventData>();
private final Map<String, Map<Integer, Map<String, Object>>> tablesColumnMap = new HashMap<>();
private boolean transactionInProgress;
private String binlogFilename;
//当发现ddl语句时 需要更新重新取列名
private Map<Integer, Map<String, Object>> loadColumn(String database, String table) {
Map<Integer, Map<String, Object>> rtn = new HashMap<>();
List<Map<String, Object>> list = null;
Connection con = null;
try {
con = DriverManager.getConnection("jdbc:mysql://" + hostname + ":" + port, username, password);
list = executeQuery(con, "select COLUMN_NAME, ORDINAL_POSITION, DATA_TYPE, CHARACTER_SET_NAME from INFORMATION_SCHEMA.COLUMNS where table_name='" + table + "' and TABLE_SCHEMA='" + database + "'");
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.close(con);
}
for (Map<String, Object> stringObjectMap : list) {
BigInteger pos = (BigInteger) stringObjectMap.get("ORDINAL_POSITION");
rtn.put(pos.intValue(), stringObjectMap);
}
return rtn;
}
@Override
public void onEvent(Event event) {
logger.debug("----->migrate binlog event:" + event.toString());
EventType eventType = event.getHeader().getEventType();
switch (eventType) {
case TABLE_MAP:
TableMapEventData tableMapEventData = event.getData();
tablesById.put(tableMapEventData.getTableId(), tableMapEventData);View on GitHub (pinned to 65f8d8beb7)