terrymanu commented on issue #37081:
URL:
https://github.com/apache/shardingsphere/issues/37081#issuecomment-3531208378
After carefully analyzing your configuration and problem description, I
confirm this is a design flaw in the ShardingSphere framework when handling
combined sharding + shadow rule scenarios.
Root Cause
The current data source mapping logic in the
ShadowRouteEngine.decorateRouteContext() method has issues:
// Current problematic code logic
String actualName = each.getDataSourceMapper().getActualName();
String sourceDataSourceName =
shadowRule.getSourceDataSourceName(actualName);
String shadowDataSourceName =
shadowRule.getShadowDataSourceMappings().get(sourceDataSourceName);
The problem is that the actualName after sharding routing may have been
modified by the framework, causing getSourceDataSourceName() to fail to
correctly reverse-resolve to the original production data source name,
ultimately resulting in shadowDataSourceName being null.
Fix Design Solutions
I suggest adopting one of the following approaches to fix this issue:
Solution 1: Enhanced Data Source Name Tracking Mechanism
// Add original data source tracking in RouteUnit
public final class RouteUnit {
private final String originalDataSourceName; // Preserve original data
source name
private final DataSourceMapper dataSourceMapper;
public RouteUnit(final String originalDataSourceName, final
DataSourceMapper dataSourceMapper) {
this.originalDataSourceName = originalDataSourceName;
this.dataSourceMapper = dataSourceMapper;
}
public String getOriginalDataSourceName() {
return originalDataSourceName;
}
}
Solution 2: Improved Reverse Mapping Algorithm
// Enhance getSourceDataSourceName method in ShadowRule
public String getSourceDataSourceName(String routedDataSourceName) {
// Exact match
if (shadowDataSourceMappings.containsKey(routedDataSourceName)) {
return routedDataSourceName;
}
// Fuzzy matching for sharding scenarios
for (String dataSourceName : shadowDataSourceMappings.keySet()) {
if (routedDataSourceName.startsWith(dataSourceName) ||
routedDataSourceName.contains(dataSourceName)) {
return dataSourceName;
}
}
return null;
}
Solution 3: Use Route Context to Pass Mapping Relationships
// Maintain data source name mapping in RouteContext
public final class RouteContext {
private final Map<String, String> dataSourceNameMapping = new
LinkedHashMap<>();
public void addDataSourceMapping(String original, String routed) {
dataSourceNameMapping.put(routed, original);
}
public String getOriginalDataSourceName(String routedName) {
return dataSourceNameMapping.getOrDefault(routedName, routedName);
}
}
Invitation to Participate
If you're interested in fixing this issue, we'd very much welcome you to
submit a PR to complete this improvement! This is a great opportunity to
contribute.
Suggested fix steps:
1. Choose one of the solutions above (I recommend Solution 1 as the
clearest approach)
2. Implement the changes in your local branch
3. Write comprehensive unit tests covering various scenarios
4. Ensure existing test cases pass
5. Submit a PR and describe your fix approach
Your fix will help many developers using the combined sharding + shadow
rules functionality. If you have any questions about implementation details,
feel free to discuss in the PR, and we'll assist with code review and
merging.
Thank you for your contribution to the ShardingSphere project!
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]