Jerry Chung created SOLR-18560:
----------------------------------

             Summary: RecoveryStrategy.commitOnLeader triggers a 
collection-wide commit; should be scoped to the shard
                 Key: SOLR-18560
                 URL: https://issues.apache.org/jira/browse/SOLR-18560
             Project: Solr
          Issue Type: Bug
          Components: SolrCloud
    Affects Versions: 10.0
            Reporter: Jerry Chung


When a replica recovers, RecoveryStrategy.commitOnLeader sends a plain hard 
commit (commit=true, openSearcher=false, waitSearcher=true) to the shard 
leader's /update endpoint. It sets no distribution parameters.

In DistributedZkUpdateProcessor.processCommit, a request without 
commit_end_point is treated as a client commit. The receiving leader calls 
getCollectionUrls(collection) and sends the commit to the leader of every shard 
in the collection (commit_end_point=leaders). Each of those leaders then 
commits and forwards the commit to its own replicas.

Recovery only needs the one leader to flush its pending changes so it can 
replicate a commit point. Commits on every other shard serve no purpose for it.

Impact

In a collection with hundreds of shards, each recovering replica causes a 
commit on every shard. During a mass recovery this gets worse, because each 
replica does the same. A single slow or unresponsive node then blocks 
recoveries across unrelated shards, because the commit chain waits on it.

Observed in production (10.0.0):
- A replica was stuck in a recovery loop, at attempt 191–195, over about 45 
minutes. Each attempt ended in SolrServerException: Timeout occurred while 
waiting response from server at: …/update from RecoveryStrategy.commitOnLeader, 
exactly 10:00 after it started (the default distribUpdateSoTimeout of 600000 
ms).
- On the leader, the commit fanned out to the leaders of shard428 through 
shard460. The leader logged SolrCmdDistributor found 3 errors with Total 
timeout 600000 ms elapsed against another node, which was itself waiting on a 
replica on a third node.
- Raising distribUpdateSoTimeout doesn't help, because the dependency chain 
doesn't resolve.

Evidence (anonymized)
- Stack trace from the recovering node (commitOnLeader at 
RecoveryStrategy.java:306, called from replicate at line 236).
- Leader log lines such as path=/update 
params=\{update.distrib=TOLEADER&waitSearcher=true&openSearcher=false&commit=true&softCommit=false&distrib.from=…&commit_end_point=leaders…}
 for dozens of different shards within the same second.

Proposed fix

Make commitOnLeader scope the commit to the shard by setting commit_end_point 
on the request, so the leader skips the collection-wide fan-out and only 
commits locally and on its own replicas:

ureq.getParams().set(UpdateParams.COMMIT_END_POINT, "leaders");

(Untested. I haven't verified the exact constant location in UpdateParams vs 
DistributedUpdateProcessor.) The method also has commented-out lines that 
suggest this was considered and disabled in SOLR-3126 and SOLR-10233, and I 
haven't found why. A test should check that a recovery commit reaches only the 
leader's shard.

Open questions
- Why was the COMMIT_END_POINT line commented out originally?
- Does forwarding the commit to the shard's own replicas have side effects? In 
our logs, a replica in BUFFERING ignores it (Ignoring commit while not ACTIVE).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to