Skip to content

Commit 7be55a2

Browse files
authored
Avoid atomic overwrite tests on FS repositories (#70483)
Today we leniently permit overwrites of blobs in a repository not to be atomic, since they are not in shared filesystem repositories. In fact it's worse, on Windows overwrites do not even work if there is a concurrent reader. In practice this isn't very important, we do almost no overwrites and almost never read the file that's being overwritten, but we do still test for atomic overwrites in the repository analyzer. With this commit we suppress the atomic overwrite checks in the repository analyzer for FS repositories, and remove the lenience since all other repositories should implement atomic overwrites correctly. Closes #70303
1 parent f89dc7a commit 7be55a2

File tree

5 files changed

+25
-3
lines changed

5 files changed

+25
-3
lines changed

server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,6 +2740,15 @@ public boolean supportURLRepo() {
27402740
return supportURLRepo;
27412741
}
27422742

2743+
/**
2744+
* @return whether this repository performs overwrites atomically. In practice we only overwrite the `index.latest` blob so this
2745+
* is not very important, but the repository analyzer does test that overwrites happen atomically. It will skip those tests if the
2746+
* repository overrides this method to indicate that it does not support atomic overwrites.
2747+
*/
2748+
public boolean hasAtomicOverwrites() {
2749+
return true;
2750+
}
2751+
27432752
/**
27442753
* The result of removing a snapshot from a shard folder in the repository.
27452754
*/

server/src/main/java/org/elasticsearch/repositories/fs/FsRepository.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,11 @@ protected BlobStore createBlobStore() throws Exception {
103103
protected ByteSizeValue chunkSize() {
104104
return chunkSize;
105105
}
106+
107+
@Override
108+
public boolean hasAtomicOverwrites() {
109+
// We overwrite a file by deleting the old file and then renaming the new file into place, which is not atomic.
110+
// Also on Windows the overwrite may fail if the file is opened for reading at the time.
111+
return false;
112+
}
106113
}

x-pack/plugin/repository-encrypted/src/main/java/org/elasticsearch/repositories/encrypted/EncryptedRepository.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,11 @@ private void validateLocalRepositorySecret(Map<String, Object> snapshotUserMetad
379379
}
380380
}
381381

382+
@Override
383+
public boolean hasAtomicOverwrites() {
384+
return delegatedRepository.hasAtomicOverwrites();
385+
}
386+
382387
// pkg-private for tests
383388
static final class EncryptedBlobStore implements BlobStore {
384389
private final BlobStore delegatedBlobStore;

x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/BlobAnalyzeAction.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,6 @@ private void onReadsComplete(Collection<NodeResponse> responses, WriteDetails wr
486486
if (response.isNotFound()) {
487487
if (request.readEarly) {
488488
nodeFailure = null; // "not found" is legitimate iff we tried to read it before the write completed
489-
} else if (request.writeAndOverwrite) {
490-
nodeFailure = null; // overwrites surprisingly not necessarily atomic, e.g. in a FsBlobContainer
491489
} else {
492490
nodeFailure = new RepositoryVerificationException(
493491
request.getRepositoryName(),

x-pack/plugin/snapshot-repo-test-kit/src/main/java/org/elasticsearch/repositories/blobstore/testkit/RepositoryAnalyzeAction.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,10 @@ public void run() {
465465
request.getReadNodeCount(),
466466
request.getEarlyReadNodeCount(),
467467
smallBlob && random.nextDouble() < request.getRareActionProbability(),
468-
repository.supportURLRepo() && smallBlob && random.nextDouble() < request.getRareActionProbability()
468+
repository.supportURLRepo()
469+
&& repository.hasAtomicOverwrites()
470+
&& smallBlob
471+
&& random.nextDouble() < request.getRareActionProbability()
469472
)
470473
);
471474
queue.add(verifyBlobTask);

0 commit comments

Comments
 (0)