apache/shardingsphere · error · InUsedRuleException

3

3

Error message

Sharding rules '%s' in database '%s' are still in used by sharding table reference.

What it means

InUsedRuleException thrown by DropShardingTableRuleExecutor.checkBindingTables when a DROP SHARDING TABLE RULE statement names tables that still appear in a sharding binding table group (rule configuration's bindingTableGroups references, split by comma). ShardingSphere refuses to drop rules that other configuration still references, to avoid leaving dangling binding-table entries.

Source

Thrown at features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropShardingTableRuleExecutor.java:82

        ShardingSpherePreconditions.checkMustEmpty(notExistedTableNames, () -> new MissingRequiredRuleException("sharding", database.getName(), notExistedTableNames));
    }
    
    private Collection<String> getToBeDroppedShardingTableNames(final DropShardingTableRuleStatement sqlStatement) {
        return sqlStatement.getTableNames().stream().map(each -> each.getIdentifier().getValue()).collect(Collectors.toList());
    }
    
    private Collection<String> getCurrentShardingTableNames() {
        Collection<String> result = new CaseInsensitiveSet<>();
        result.addAll(rule.getConfiguration().getTables().stream().map(ShardingTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
        result.addAll(rule.getConfiguration().getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toList()));
        return result;
    }
    
    private void checkBindingTables(final DropShardingTableRuleStatement sqlStatement) {
        Collection<String> bindingTables = getBindingTables();
        Collection<String> usedTableNames = getToBeDroppedShardingTableNames(sqlStatement).stream().filter(bindingTables::contains).collect(Collectors.toList());
        if (!usedTableNames.isEmpty()) {
            throw new InUsedRuleException("Sharding", database.getName(), usedTableNames, "sharding table reference");
        }
    }
    
    private Collection<String> getBindingTables() {
        Collection<String> result = new CaseInsensitiveSet<>();
        rule.getConfiguration().getBindingTableGroups().forEach(each -> result.addAll(Splitter.on(",").splitToList(each.getReference())));
        return result;
    }
    
    @Override
    public boolean hasAnyOneToBeDropped(final DropShardingTableRuleStatement sqlStatement) {
        Collection<String> currentTableNames = new LinkedList<>();
        currentTableNames.addAll(rule.getConfiguration().getTables().stream().map(ShardingTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
        currentTableNames.addAll(rule.getConfiguration().getAutoTables().stream().map(ShardingAutoTableRuleConfiguration::getLogicTable).collect(Collectors.toSet()));
        return !Collections.disjoint(currentTableNames, sqlStatement.getTableNames().stream().map(each -> each.getIdentifier().getValue()).collect(Collectors.toSet()));
    }
    
    @Override

View on GitHub (pinned to e952770a21)

Solutions

  1. Drop or rewrite the binding rule first: ALTER SHARDING BINDING TABLE RULES without the affected table (or DROP SHARDING BINDING TABLE RULES), then re-run the DROP SHARDING TABLE RULE.
  2. If dropping the whole group, drop all member tables' rules together with the binding rule.
  3. Inspect current references first with SHOW SHARDING BINDING TABLE RULES.

Example fix

-- before: drop rejected while binding exists
DROP SHARDING TABLE RULE t_order;

-- after: remove from binding group, then drop
ALTER SHARDING BINDING TABLE RULES ();
DROP SHARDING TABLE RULE t_order;
Defensive patterns

Strategy: validation

Validate before calling

-- Check binding references before dropping
SHOW SHARDING BINDING TABLE RULES;
-- if the target appears in any reference list, first run:
--   ALTER SHARDING BINDING TABLE RULES (...) without it, or DROP SHARDING BINDING TABLE RULES

Try / catch

try {
    executeDistSql("DROP SHARDING TABLE RULE t_order");
} catch (final InUsedRuleException ex) {
    // remove the table from binding groups first, then retry the drop
}

Prevention

When it happens

Trigger: DROP SHARDING TABLE RULE t_order while a binding group like 't_order,t_order_item' exists: the to-be-dropped names intersect getBindingTables(), so the drop is rejected listing the still-used table names.

Common situations: Decommissioning or migrating one table of a binding group; cleanup scripts that drop sharding rules but forget binding groups; re-sharding a table that participates in a binding relationship.

Related errors


AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14). Data as JSON: /api/errors/5712fa0d49fb736e. Report an issue: GitHub.