Browse Source

Hold store reference in InternalEngine#performActionWithDirectoryReader(...) (#123010)

This method gets called from `InternalEngine#resolveDocVersion(...)`, which gets during indexing (via `InternalEngine.index(...)`).

When `InternalEngine.index(...)` gets invoked, the InternalEngine only ensures that it holds a ref to the engine via Engine#acquireEnsureOpenRef(), but this doesn't ensure whether it holds a reference to the store.

Closes #122974

* Update docs/changelog/123010.yaml
Martijn van Groningen 8 months ago
parent
commit
8d1f5d3223

+ 6 - 0
docs/changelog/123010.yaml

@@ -0,0 +1,6 @@
+pr: 123010
+summary: Hold store reference in `InternalEngine#performActionWithDirectoryReader(...)`
+area: Engine
+type: bug
+issues:
+ - 122974

+ 0 - 3
muted-tests.yml

@@ -314,9 +314,6 @@ tests:
   issue: https://github.com/elastic/elasticsearch/issues/122913
 - class: org.elasticsearch.xpack.search.AsyncSearchSecurityIT
   issue: https://github.com/elastic/elasticsearch/issues/122940
-- class: org.elasticsearch.action.admin.indices.create.ShrinkIndexIT
-  method: testShrinkIndexPrimaryTerm
-  issue: https://github.com/elastic/elasticsearch/issues/122974
 - class: org.elasticsearch.test.apmintegration.TracesApmIT
   method: testApmIntegration
   issue: https://github.com/elastic/elasticsearch/issues/122129

+ 5 - 1
server/src/main/java/org/elasticsearch/index/engine/InternalEngine.java

@@ -3470,7 +3470,9 @@ public class InternalEngine extends Engine {
     <T> T performActionWithDirectoryReader(SearcherScope scope, CheckedFunction<DirectoryReader, T, IOException> action)
         throws EngineException {
         assert scope == SearcherScope.INTERNAL : "performActionWithDirectoryReader(...) isn't prepared for external usage";
-        assert store.hasReferences();
+        if (store.tryIncRef() == false) {
+            throw new AlreadyClosedException(shardId + " store is closed", failedEngine.get());
+        }
         try {
             ReferenceManager<ElasticsearchDirectoryReader> referenceManager = getReferenceManager(scope);
             ElasticsearchDirectoryReader acquire = referenceManager.acquire();
@@ -3486,6 +3488,8 @@ public class InternalEngine extends Engine {
             ensureOpen(ex); // throw EngineCloseException here if we are already closed
             logger.error("failed to perform action with directory reader", ex);
             throw new EngineException(shardId, "failed to perform action with directory reader", ex);
+        } finally {
+            store.decRef();
         }
     }
 }