{"record":{"id":"5a02cd74370a5ae1","repo":"MyCATApache/Mycat-Server","slug":"schemaname-tablename-old-new-rule-algorithm","errorCode":null,"errorMessage":"{schemaName}:{tableName} old & new rule Algorithm is not same!","messagePattern":"(.+?):(.+?) old & new rule Algorithm is not same!","errorType":"exception","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/util/dataMigrator/ConfigComparer.java","lineNumber":248,"sourceCode":"\t\t\t\tcurrentWriteHost = writeHosts[Integer.valueOf(dnIndexProps.getProperty(dh.getName()))];\n\t\t\t}\n\t\t\tDataNode dn = new DataNode(name,currentWriteHost.getIp(), currentWriteHost.getPort(), currentWriteHost.getUser(), currentWriteHost.getPassword(), db, dbType,i++);\n\t\t\tdataNodes.add(dn);\n\t\t}\n\t\t\n\t\treturn dataNodes;\n\t}\n\t\n\t//校验前后路由规则是否一致\n\tprivate void checkRuleConfig(RuleConfig oldRC,RuleConfig newRC,String schemaName,String tableName){\n\t\tif(!oldRC.getColumn().equalsIgnoreCase(newRC.getColumn())){\n\t\t\tthrow new ConfigException(schemaName+\":\"+tableName+\" old & new partition column is not same!\");\n\t\t}\n\t\tAbstractPartitionAlgorithm oldAlg = oldRC.getRuleAlgorithm();\n\t\tAbstractPartitionAlgorithm newAlg = newRC.getRuleAlgorithm();\n\t\t//判断路由算法前后是否一致\n\t\tif(!oldAlg.getClass().isAssignableFrom(newAlg.getClass())){\n\t\t\tthrow new ConfigException(schemaName+\":\"+tableName+\" old & new rule Algorithm is not same!\");\n\t\t}\n\t}\n\t\n\tprivate Properties loadDnIndexProps() {\n\t\tProperties prop = new Properties();\n\t\tInputStream is = null;\n\t\ttry {\n\t\t\tis = ConfigComparer.class.getResourceAsStream(DN_INDEX_FILE);\n\t\t\tprop.load(is);\n\t\t} catch (Exception e) {\n\t\t\tthrow new ConfigException(\"please check file \\\"dnindex.properties\\\" \"+e.getMessage());\n\t\t} finally {\n\t\t\ttry {\n\t\t\t\tif(is !=null){\n\t\t\t\t\tis.close();\n\t\t\t\t}\n\t\t\t} catch (IOException e) {\n\t\t\t\tthrow new ConfigException(e.getMessage());","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/util/dataMigrator/ConfigComparer.java#L230-L266","documentation":"checkRuleConfig requires the partitioning algorithm class to be identical (assignable) before and after migration. If the old rule's algorithm and the new rule's algorithm are different classes, redistribution semantics change and the migrator throws a ConfigException.","triggerScenarios":"Changing the <algorithm> (function) used by a table's rule between old and new configs — e.g. switching from PartitionByMod to PartitionByHash or from auto-partition to a long-based partitioner.","commonSituations":"Upgrading sharding strategy (mod -> range/hash); rule.xml's function name remapped to a different class in the new config; table rule referencing a newly added algorithm function.","solutions":["Set the new rule's algorithm class to the same class as the old one for this table.","If the algorithm must change, redistribute data outside this tool or adjust the tool constraints deliberately.","Check the function definitions in rule.xml so both configs' rules resolve to the same AbstractPartitionAlgorithm subclass.","Rerun the comparison after aligning algorithm classes."],"exampleFix":"// before: new rule.xml\n<function name=\"func1\" class=\"io.mycat.route.function.PartitionByHash\">\n// after (same class as old)\n<function name=\"func1\" class=\"io.mycat.route.function.PartitionByMod\">","handlingStrategy":"validation","validationCode":"Class<?> oldAlg = oldTable.getRule().getRuleAlgorithm().getClass();\nClass<?> newAlg = newTable.getRule().getRuleAlgorithm().getClass();\nif (!oldAlg.equals(newAlg)) {\n    throw new IllegalArgumentException(\"algorithm class changed for \" + tableName\n        + \": \" + oldAlg.getName() + \" -> \" + newAlg.getName());\n}","typeGuard":null,"tryCatchPattern":"try {\n    comparer.compare();\n} catch (ConfigException e) {\n    if (e.getMessage().contains(\"rule Algorithm is not same\")) {\n        // point the new rule's function at the same algorithm class as the old one\n    }\n    throw e;\n}","preventionTips":["Keep the same algorithm class per table across migration configs","Plan algorithm changes as a separate dump/reload migration, not via data migrator","Add a config-diff checklist item for rule.xml function classes"],"tags":["java","data-migration","sharding","configuration"],"backgroundTag":"conflicting-config-options","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}