MyCATApache/Mycat-Server · error · SQLNonTransientException

global table is not supported in multi table related update

Error message

global table is not supported in multi table related update 

What it means

Mycat rejects an UPDATE on a global table when the statement's routing conditions involve more than one table. Global tables are replicated identically on every node, and a multi-table related update makes it ambiguous which node copy should be modified. The message names the offending global table.

Solutions

  1. Issue the update on the global table alone, in its own single-table UPDATE statement
  2. Remove global="true" from the table config if the table is not truly a replicated reference table
  3. Restructure the SQL so conditions on other tables are resolved first and the global-table update is issued separately

Example fix

// before
UPDATE dict d JOIN orders o ON d.id=o.dict_id SET d.label='x';
// after
UPDATE dict SET label='x' WHERE id IN (SELECT dict_id FROM orders);
-- or run the single-table update separately
Defensive patterns

Strategy: validation

Validate before calling

TableConfig tc = schema.getTables().get(tableName);
if (tc != null && tc.isGlobalTable() && ctx.getRouteCalculateUnit().getTablesAndConditions().size() > 1) {
    throw new SQLNonTransientException("global table in multi-table update: " + tableName);
}

Try / catch

try { router.route(...) } catch (SQLNonTransientException e) { if (e.getMessage().startsWith("global table is not supported")) { splitIntoSingleTableUpdates(); } }

Prevention

When it happens

Trigger: statementParse on an UPDATE where schema.getTables().get(tableName).isGlobalTable() is true AND ctx.getRouteCalculateUnit().getTablesAndConditions() contains more than one table — i.e. a multi-table UPDATE that includes a global table.

Common situations: Updating a dictionary/reference table (configured with global="true") inside a joined UPDATE; mis-marking a large sharded table as global; legacy SQL ported from single-node MySQL.

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


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

Appendix: source

Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidUpdateParser.java:72


        confirmShardColumnNotUpdated(update, schema, tableName, partitionColumn, joinKey, rrs);

//		if(ctx.getTablesAndConditions().size() > 0) {
//			Map<String, Set<ColumnRoutePair>> map = ctx.getTablesAndConditions().get(tableName);
//			if(map != null) {
//				for(Map.Entry<String, Set<ColumnRoutePair>> entry : map.entrySet()) {
//					String column = entry.getKey();
//					Set<ColumnRoutePair> value = entry.getValue();
//					if(column.toUpperCase().equals(anObject))
//				}
//			}
//			
//		}
//		System.out.println();

        if (schema.getTables().get(tableName).isGlobalTable() && ctx.getRouteCalculateUnit().getTablesAndConditions().size() > 1) {
            throw new SQLNonTransientException("global table is not supported in multi table related update " + tableName);
        }

        //在解析SQL时清空该表的主键缓存
        TableConfig tableConfig = schema.getTables().get(tableName);
        if (tableConfig != null && !tableConfig.primaryKeyIsPartionKey()) {
            String cacheName = schema.getName() +"_" + tableName;
            cacheName = cacheName.toUpperCase();
            for (CachePool value : MycatServer.getInstance().getCacheService().getAllCachePools().values()) {
                value.clearCache(cacheName);
                value.getCacheStatic().reset();
            }
        }
    }
    
    /**
     * 获取更新的表数
     * @author lian
     * @date 2016年11月2日

View on GitHub (pinned to 65f8d8beb7)