MyCATApache/Mycat-Server · error · java.lang.RuntimeException

dataHost: do not config the salveIDs field

Error message

dataHost:${dbNode.getDbPool().getHostName()} do not config the salveIDs field

What it means

Before migrating data, MigrateHandler must get a slave ID for the dataHost (to restrict migration reads to a replica). getSlaveIdFromZKForDataNode reads dbPool.getSlaveIDs(); when that field is null/empty (Strings.isNullOrEmpty) it throws RuntimeException that the dataHost has no salveIDs configured.

Solutions

  1. Add a slaveIDs entry for the dataHost in schema.xml (e.g. <dataHost ...><readHost .../></dataHost> or slaveIDs="2") and reload
  2. If migrating via ZooKeeper mode, update the ZK dataHost config to include slaveIDs and sync to Mycat
  3. Configure at least one read host/replica whose serverId can be used as the migration slave
  4. If no replica exists, use a migration method that does not require slave-based throttling

Example fix

// before (schema.xml)
<dataHost name="host1" ...><writeHost host="m1" url="..."/></dataHost>
// after
<dataHost name="host1" ...>
  <writeHost host="m1" url="...">
    <readHost host="s1" url="..." weight="0"/>
  </writeHost>
</dataHost> <!-- gives slaveIDs -->
Defensive patterns

Strategy: validation

Validate before calling

// Before running migrate, verify every involved dataHost has slaveIDs configured
for (String dn : dataNodes) {
    String slaveIDs = config.getDataNodes().get(dn).getDbPool().getSlaveIDs();
    if (slaveIDs == null || slaveIDs.isEmpty()) throw new IllegalStateException(dn + "'s dataHost lacks slaveIDs");
}

Try / catch

catch (RuntimeException e) { if (e.getMessage().contains("do not config the salveIDs field")) { /* add readHost/slaveIDs to schema.xml and reload */ } throw e; }

Prevention

When it happens

Trigger: Running a migrate/schedule command where the target dataNode's PhysicalDBPool was created without the slaveIDs property set (hostM not listing slaveIDs in schema.xml/server.xml or ZooKeeper config).

Common situations: Environments without read replicas where slaveIDs was never configured; partial migration from schema.xml to ZooKeeper so the field is lost; typo'd property name; single-node dev setups trying production migration tooling.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/server/handler/MigrateHandler.java:369

        Map<String, List<MigrateTask>> taskMap = new HashMap<>();
        for (MigrateTask migrateTask : migrateTaskList) {
            String dataHost = getDataHostNameFromNode(migrateTask.getFrom());
            if (taskMap.containsKey(dataHost)) {
                taskMap.get(dataHost).add(migrateTask);
            } else {
                taskMap.put(dataHost, Lists.newArrayList(migrateTask));
            }
        }


        return taskMap;
    }

    private static int getSlaveIdFromZKForDataNode(String dataNode) {
        PhysicalDBNode dbNode = MycatServer.getInstance().getConfig().getDataNodes().get(dataNode);
        String slaveIDs = dbNode.getDbPool().getSlaveIDs();
        if (Strings.isNullOrEmpty(slaveIDs))
            throw new RuntimeException("dataHost:" + dbNode.getDbPool().getHostName() + " do not config the salveIDs field");

        List<Integer> allSlaveIDList = parseSlaveIDs(slaveIDs);

        String taskPath = ZKUtils.getZKBasePath() + "slaveIDs/" + dbNode.getDbPool().getHostName();
        try {
            slaveIDsLock.acquire(30, TimeUnit.SECONDS);
            Set<Integer> zkSlaveIdsSet = new HashSet<>();
            if (ZKUtils.getConnection().checkExists().forPath(taskPath) != null) {
                List<String> zkHasSlaveIDs = ZKUtils.getConnection().getChildren().forPath(taskPath);
                for (String zkHasSlaveID : zkHasSlaveIDs) {
                    zkSlaveIdsSet.add(Integer.parseInt(zkHasSlaveID));
                }
            }
            for (Integer integer : allSlaveIDList) {
                if (!zkSlaveIdsSet.contains(integer)) {
                    ZKUtils.getConnection().create().creatingParentsIfNeeded().forPath(taskPath + "/" + integer);
                    return integer;
                }

View on GitHub (pinned to 65f8d8beb7)