From 83ffe5cb6f136866c0a0e53a8dff7d0a162f08d1 Mon Sep 17 00:00:00 2001 From: Tanguy Leroux Date: Fri, 23 Jun 2023 15:45:48 +0200 Subject: [PATCH] rework --- ...SnapshotRecoveryStateIntegrationTests.java | 1 - .../store/SearchableSnapshotDirectory.java | 24 +++++++++++++++---- .../input/CachedBlobContainerIndexInput.java | 7 ++++++ 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java index 34b64da82dedf..5b31549dbd42f 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/recovery/SearchableSnapshotRecoveryStateIntegrationTests.java @@ -61,7 +61,6 @@ protected Collection> nodePlugins() { return CollectionUtils.appendToCopy(super.nodePlugins(), TestRepositoryPlugin.class); } - @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/95994") public void testRecoveryStateRecoveredBytesMatchPhysicalCacheState() throws Exception { final String fsRepoName = randomAlphaOfLength(10); final String indexName = randomAlphaOfLength(10).toLowerCase(Locale.ROOT); diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java index 3434dfd0b8064..b25a6316105b9 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/SearchableSnapshotDirectory.java @@ -506,16 +506,32 @@ private void prewarmCache(ActionListener listener, Supplier cance final AtomicLong prefetchedBytes = new AtomicLong(0L); try (var fileListener = new RefCountingListener(ActionListener.runBefore(completionListener.acquire().map(v -> { - // we can't report a file as being partially recovered from disk and partially from the blob store, but this is - // something that can happen for fully mounted searchable snapshots. So we make a choice here: if less than 50% - // of the file is prewarmed from the blob store then it is marked as reused from cache. - if ((prefetchedBytes.get() / (double) file.length()) < 0.5d) { + // we don't support files to be reported as partially recovered from disk and partially from the blob store, but + // this is something that can happen for fully mounted searchable snapshots. It is possible that prewarming + // prefetched nothing if a concurrent search was executing (and cached the data) or if the data were fetched from + // the blob cache system index. + if (prefetchedBytes.get() == 0L) { recoveryState.markIndexFileAsReused(file.physicalName()); } else { recoveryState.getIndex().addRecoveredFromSnapshotBytesToFile(file.physicalName(), file.length()); } return v; }), () -> IOUtils.closeWhileHandlingException(input)))) { + + if (input instanceof CachedBlobContainerIndexInput cachedIndexInput) { + if (cachedIndexInput.getPersistentCacheInitialLength() == file.length()) { + logger.trace( + () -> format( + "%s file [%s] is already available in cache (%d bytes)", + shardId, + file.physicalName(), + file.length() + ) + ); + return; + } + } + for (int p = 0; p < file.numberOfParts(); p++) { final int part = p; prewarmTaskRunner.enqueueTask(fileListener.acquire().map(releasable -> { diff --git a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/CachedBlobContainerIndexInput.java b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/CachedBlobContainerIndexInput.java index 456fa82cd3ef3..5aedc1e18b161 100644 --- a/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/CachedBlobContainerIndexInput.java +++ b/x-pack/plugin/searchable-snapshots/src/main/java/org/elasticsearch/xpack/searchablesnapshots/store/input/CachedBlobContainerIndexInput.java @@ -122,6 +122,13 @@ protected void readWithoutBlobCache(ByteBuffer b) throws Exception { assert bytesRead == length : bytesRead + " vs " + length; } + /** + * @return Returns the number of bytes already cached for the file in the cold persistent cache + */ + public long getPersistentCacheInitialLength() throws Exception { + return cacheFileReference.get().getInitialLength(); + } + /** * Prefetches a complete part and writes it in cache. This method is used to prewarm the cache. *