Uh oh!
There was an error while loading. Please reload this page.
SOLR-18413: Handle deleted MIGRATE routing targets - #4862
Conversation
dsmiley
left a comment
There was a problem hiding this comment.
Nice! I love your detailed explanation.
Note that you kept referring to "replica" in a way that meant to imply a "follower replica" (instead of the "leader replica"). Basically, the leader is a replica too!
Needs a changelog (see writeChangelog task). I'm not sure this is a bug, maybe it's just a "changed" (improvement). Assuming a user could repair the situation on their own with the HTTP API. If they delete the collection, they ought to first undo the migration. If they can't, then I'm more sympathetic to this being a bug.
| } | ||
| try { | ||
| if (ruleExpiryLock.tryLock(10, TimeUnit.MILLISECONDS)) { | ||
| log.info("Going to remove routing rule"); |
There was a problem hiding this comment.
Let's be clearer. I suggest "Removing shard update routing rule because the target collection ____ doesn't exist".
JIRA: SOLR-18413
Description
A SolrCloud
MIGRATEadds a temporary routing rule to the source slice so that matching updates are also forwarded to the target collection.For example, migrating route key
a!fromsourcetotargetcreates state similar to:The routing rule stores the target collection name as a string. Deleting
targetdoes not remove routing rules in other collections that refer to it, so the source can retain an unexpired rule whose target is no longer present inClusterState.A subsequent matching update, such as adding
id=a!2tosource, is first applied locally on the source shard leader.DistributedZkUpdateProcessor.doDistribAdd()then resolves routing-rule destinations before distributing the update to the source shard replicas:getNodesByRoutingRules()previously resolved the target using:If the target had been deleted, this threw:
Because the source leader had already applied the update, but the exception occurred before source-replica distribution, the request could leave the shard in this state:
No request was sent to the source replica, so
SolrCmdDistributordid not record a replica failure and this update did not trigger term demotion or recovery. Queries can then return different results depending on which replica serves them. If leadership subsequently moves to a replica that never received the update, the document is lost.Solution
Resolve the routing-rule target with
getCollectionOrNull():When the target collection no longer exists, the routing rule is treated as invalid. The existing routing-rule removal logic used for expired rules was extracted into
removeRoutingRule(). Expired rules and rules with missing targets now share the same cleanup path. The cleanup remains guarded by the core's routing-rule lock.The behavior for a target collection that exists but has no active slices is unchanged. That condition may be temporary and continues to produce an error rather than permanently removing the routing rule.
Tests
Added:
MigrateRouteKeyTest.updateSucceedsAfterMigrateTargetIsDeletedThe test uses a real two-node
MiniSolrCloudClusterand performs this sequence:sourcecollection.targetcollection.id=a!1to the source.a!from the source to the target.ClusterState.id=a!2to the source and commits.distrib=false.a!2.Without the fix, the add in step 7 fails with: