SOLR-10159: When DBQ is reordered with an in-place update, upon whose updated value the DBQ is based on, the DBQ fails due to excessive caching in DeleteByQueryWrapper

This commit is contained in:
Ishan Chattopadhyaya 2017-02-19 07:12:28 +05:30
parent 46ef9256b4
commit 82f598d895
4 changed files with 54 additions and 0 deletions

View File

@ -56,6 +56,8 @@ Bug Fixes
* SOLR-10114: Reordered delete-by-query causes inconsistenties between shards that have
child documents (Mano Kovacs, Mihaly Toth, yonik)
* SOLR-10159: When DBQ is reordered with an in-place update, upon whose updated value the DBQ is based
on, the DBQ fails due to excessive caching in DeleteByQueryWrapper (Ishan Chattopadhyaya)
Optimizations
----------------------

View File

@ -68,6 +68,7 @@ final class DeleteByQueryWrapper extends Query {
public Weight createWeight(IndexSearcher searcher, boolean needsScores, float boost) throws IOException {
final LeafReader wrapped = wrap((LeafReader) searcher.getIndexReader());
final IndexSearcher privateContext = new IndexSearcher(wrapped);
privateContext.setQueryCache(searcher.getQueryCache());
final Weight inner = in.createWeight(privateContext, needsScores, boost);
return new Weight(DeleteByQueryWrapper.this) {
@Override

View File

@ -328,6 +328,9 @@ public class DirectUpdateHandler2 extends UpdateHandler implements SolrCoreState
synchronized (solrCoreState.getUpdateLock()) {
updateDocOrDocValues(cmd, writer, idTerm);
if (cmd.isInPlaceUpdate() && ulog != null) {
ulog.openRealtimeSearcher(); // This is needed due to LUCENE-7344.
}
for (Query q : dbqList) {
writer.deleteDocuments(new DeleteByQueryWrapper(q, core.getLatestSchema()));
}

View File

@ -136,6 +136,7 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
"docValues",Boolean.TRUE));
// Do the tests now:
reorderedDBQIndividualReplicaTest();
testDBQUsingUpdatedFieldFromDroppedUpdate();
outOfOrderDBQsTest();
docValuesUpdateTest();
@ -245,6 +246,53 @@ public class TestInPlaceUpdatesDistrib extends AbstractFullDistribZkTestBase {
commit();
}
private void reorderedDBQIndividualReplicaTest() throws Exception {
clearIndex();
commit();
// put replica out of sync
float newinplace_updatable_float = 100;
long version0 = 2000;
List<UpdateRequest> updates = new ArrayList<>();
updates.add(simulatedUpdateRequest(null, "id", 0, "title_s", "title0_new", "inplace_updatable_float",
newinplace_updatable_float, "_version_", version0 + 1)); // full update
updates.add(simulatedUpdateRequest(version0 + 1, "id", 0, "inplace_updatable_float",
newinplace_updatable_float + 1, "_version_", version0 + 2)); // inplace_updatable_float=101
updates.add(simulatedDeleteRequest("inplace_updatable_float:"+(newinplace_updatable_float + 1), version0 + 3));
// Reordering needs to happen using parallel threads
ExecutorService threadpool =
ExecutorUtil.newMDCAwareFixedThreadPool(updates.size() + 1, new DefaultSolrThreadFactory(getTestName()));
// re-order the updates by swapping the last two
List<UpdateRequest> reorderedUpdates = new ArrayList<>(updates);
reorderedUpdates.set(1, updates.get(2));
reorderedUpdates.set(2, updates.get(1));
List<Future<UpdateResponse>> updateResponses = new ArrayList<>();
for (UpdateRequest update : reorderedUpdates) {
AsyncUpdateWithRandomCommit task = new AsyncUpdateWithRandomCommit(update, NONLEADERS.get(0), random().nextLong());
updateResponses.add(threadpool.submit(task));
// while we can't guarantee/trust what order the updates are executed in, since multiple threads
// are involved, but we're trying to bias the thread scheduling to run them in the order submitted
Thread.sleep(100);
}
threadpool.shutdown();
assertTrue("Thread pool didn't terminate within 10 secs", threadpool.awaitTermination(10, TimeUnit.SECONDS));
// assert all requests were successful
for (Future<UpdateResponse> resp: updateResponses) {
assertEquals(0, resp.get().getStatus());
}
SolrDocument doc = NONLEADERS.get(0).getById(String.valueOf(0), params("distrib", "false"));
assertNull("This doc was supposed to have been deleted, but was: " + doc, doc);
clearIndex();
commit();
}
private void docValuesUpdateTest() throws Exception {
clearIndex();
commit();