MyCATApache/Mycat-Server · error · RuntimeException

some slot has not moved to

Error message

some slot has not moved to

What it means

After distributing slots to new nodes, balanceExpand verifies that allMoveList is drained; leftovers mean the algorithm could not place every slot that must move. It throws 'some slot has not moved to' to prevent an inconsistent slot map from being persisted.

Solutions

  1. Check that new dataNode count times newSlotPerNode covers total slots; adjust node count or the expansion plan.
  2. Validate the crc32slot rule file ranges are contiguous and non-overlapping before expansion.
  3. Recalculate the expansion from the original rule file (regenerate it) instead of reusing a partially migrated state.
  4. If reproducible, log allMoveList contents and file a report with the rule file and schema.xml.

Example fix

// before
if (allMoveList.size() > 0) {
    throw new RuntimeException("some slot has not moved to");
}
// after
if (allMoveList.size() > 0) {
    throw new RuntimeException("some slot has not moved to, " + allMoveList.size()
        + " slots remain: " + allMoveList);
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-check slot math
int totalSlots = getTotalSlots(ruleFile);
int nodes = newDataNodes.size();
if (totalSlots % nodes != 0) log.warn("slots won't divide evenly across " + nodes + " nodes");
if (newDataNodes.size() < 1) throw new IllegalStateException("need at least one target node");

Prevention

When it happens

Trigger: needMove computations leave slots unassigned because old/new dataNode lists or newSlotPerNode arithmetic do not cover allMoveList; duplicate or overlapping dataNodes in the new list; gb (granularity/backlog) value produces negative transfer amounts.

Common situations: Scaling out with new nodes whose count or capacity doesn't match the slot math; malformed crc32slot rule file producing extra ranges; running expansion twice with partially applied state.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/io/mycat/migrate/MigrateUtils.java:77

                int hasSlots = getCurTotalSizeForTask(curRangeList);
                int needMove = (i1 == 0) ? newSlotPerNode - hasSlots + gb : newSlotPerNode - hasSlots;
                if (needMove > 0) {
                    List<Range> moveList = getPartAndRemove(allMoveList, needMove);
                    MigrateTask task = new MigrateTask();
                    if (i >= oldDataNodes.size()) {
                        throw new RuntimeException(String.format("crc32slot_%s.properties does not match schema table dataNode.", table.toUpperCase()));
                    }
                    task.setFrom(oldDataNodes.get(i));
                    task.setTo(newDataNode);
                    task.setTable(table);
                    task.setSlots(moveList);
                    curRangeList.add(task);
                    newNodeTask.put(newDataNode, curRangeList);
                }
            }

            if (allMoveList.size() > 0) {
                throw new RuntimeException("some slot has not moved to");
            }
        }
        return newNodeTask;
    }


    private static List<Range> getPartAndRemove(List<Range> rangeList, int size) {
        List<Range> result = new ArrayList<>();

        for (int i = 0; i < rangeList.size(); i++) {

            Range range = rangeList.get(i);
            if (range == null)
                continue;
            if (range.size == size) {
                result.add(new Range(range.start, range.end));
                rangeList.set(i, null);
                break;

View on GitHub (pinned to 65f8d8beb7)