Skip to content

Commit 82b1f10

Browse files
SNAPSHOT+TESTS: Rem. Mock Atomic Writes Randomness (#37011)
* Randomly doing non-atomic writes causes rare 0 byte reads from `index-N` files in tests * Removing this randomness fixes these random failures and is valid because it does not reproduce a real-world failure-mode: * Cloud-based Blob stores (S3, GCS, and Azure) do not have inconsistent partial reads of a blob, either you read a complete blob or nothing on them * For file system based blob stores the atomic move we do (to atomically write a file) by setting `java.nio.file.StandardCopyOption#ATOMIC_MOVE` would throw if the file system does not provide for atomic moves * Closes #37005
1 parent edb4832 commit 82b1f10

File tree

2 files changed

+10
-22
lines changed

2 files changed

+10
-22
lines changed

server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3179,7 +3179,6 @@ public void testGetSnapshotsRequest() throws Exception {
31793179
*
31803180
* See https://github.com/elastic/elasticsearch/issues/20876
31813181
*/
3182-
@AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/37005")
31833182
public void testSnapshotCanceledOnRemovedShard() throws Exception {
31843183
final int numPrimaries = 1;
31853184
final int numReplicas = 1;
@@ -3244,7 +3243,6 @@ public void testSnapshotSucceedsAfterSnapshotFailure() throws Exception {
32443243
.put("location", repoPath)
32453244
.put("random_control_io_exception_rate", randomIntBetween(5, 20) / 100f)
32463245
// test that we can take a snapshot after a failed one, even if a partial index-N was written
3247-
.put("allow_atomic_operations", false)
32483246
.put("random", randomAlphaOfLength(10))));
32493247

32503248
logger.info("--> indexing some data");

server/src/test/java/org/elasticsearch/snapshots/mockstore/MockRepository.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,6 @@ public long getFailureCount() {
110110
/** Allows blocking on writing the snapshot file at the end of snapshot creation to simulate a died master node */
111111
private volatile boolean blockAndFailOnWriteSnapFile;
112112

113-
private volatile boolean allowAtomicOperations;
114-
115113
private volatile boolean blocked = false;
116114

117115
public MockRepository(RepositoryMetaData metadata, Environment environment,
@@ -127,7 +125,6 @@ public MockRepository(RepositoryMetaData metadata, Environment environment,
127125
blockAndFailOnWriteSnapFile = metadata.settings().getAsBoolean("block_on_snap", false);
128126
randomPrefix = metadata.settings().get("random", "default");
129127
waitAfterUnblock = metadata.settings().getAsLong("wait_after_unblock", 0L);
130-
allowAtomicOperations = metadata.settings().getAsBoolean("allow_atomic_operations", true);
131128
logger.info("starting mock repository with random prefix {}", randomPrefix);
132129
}
133130

@@ -361,25 +358,18 @@ public void writeBlob(String blobName, InputStream inputStream, long blobSize, b
361358
public void writeBlobAtomic(final String blobName, final InputStream inputStream, final long blobSize,
362359
final boolean failIfAlreadyExists) throws IOException {
363360
final Random random = RandomizedContext.current().getRandom();
364-
if (allowAtomicOperations && random.nextBoolean()) {
365-
if ((delegate() instanceof FsBlobContainer) && (random.nextBoolean())) {
366-
// Simulate a failure between the write and move operation in FsBlobContainer
367-
final String tempBlobName = FsBlobContainer.tempBlobName(blobName);
368-
super.writeBlob(tempBlobName, inputStream, blobSize, failIfAlreadyExists);
369-
maybeIOExceptionOrBlock(blobName);
370-
final FsBlobContainer fsBlobContainer = (FsBlobContainer) delegate();
371-
fsBlobContainer.moveBlobAtomic(tempBlobName, blobName, failIfAlreadyExists);
372-
} else {
373-
// Atomic write since it is potentially supported
374-
// by the delegating blob container
375-
maybeIOExceptionOrBlock(blobName);
376-
super.writeBlobAtomic(blobName, inputStream, blobSize, failIfAlreadyExists);
377-
}
361+
if ((delegate() instanceof FsBlobContainer) && (random.nextBoolean())) {
362+
// Simulate a failure between the write and move operation in FsBlobContainer
363+
final String tempBlobName = FsBlobContainer.tempBlobName(blobName);
364+
super.writeBlob(tempBlobName, inputStream, blobSize, failIfAlreadyExists);
365+
maybeIOExceptionOrBlock(blobName);
366+
final FsBlobContainer fsBlobContainer = (FsBlobContainer) delegate();
367+
fsBlobContainer.moveBlobAtomic(tempBlobName, blobName, failIfAlreadyExists);
378368
} else {
379-
// Simulate a non-atomic write since many blob container
380-
// implementations does not support atomic write
369+
// Atomic write since it is potentially supported
370+
// by the delegating blob container
381371
maybeIOExceptionOrBlock(blobName);
382-
super.writeBlob(blobName, inputStream, blobSize, failIfAlreadyExists);
372+
super.writeBlobAtomic(blobName, inputStream, blobSize, failIfAlreadyExists);
383373
}
384374
}
385375
}

0 commit comments

Comments
 (0)