Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
1afb69e
bck
original-brownbear Dec 14, 2019
24a9e1e
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Dec 16, 2019
4d5685c
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Dec 17, 2019
94d4c3a
bck
original-brownbear Dec 17, 2019
15aa01c
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Dec 17, 2019
e994881
works some more
original-brownbear Dec 17, 2019
e939e55
bck
original-brownbear Dec 17, 2019
083874d
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Dec 17, 2019
aa2f463
bck
original-brownbear Dec 17, 2019
4b898c3
TODO
original-brownbear Dec 17, 2019
69bf0fe
better
original-brownbear Dec 17, 2019
dae25c4
fix test
original-brownbear Dec 18, 2019
96dad34
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Dec 18, 2019
8fbdd9f
javadoc
original-brownbear Dec 18, 2019
b1af8ee
add comment
original-brownbear Dec 18, 2019
fecb413
drop obsolete TODO
original-brownbear Dec 18, 2019
f747e90
add test to show better incrementality
original-brownbear Dec 18, 2019
2f46ec3
new tests + equals + hashcode
original-brownbear Dec 18, 2019
8db076d
toString
original-brownbear Dec 18, 2019
0e10f2f
Merge branch 'master' of https://github.com/elastic/elasticsearch int…
original-brownbear Dec 18, 2019
775228f
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 2, 2020
059e884
bck
original-brownbear Jan 2, 2020
701513d
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 2, 2020
9fa0232
much better hashing indexMetaData
original-brownbear Jan 2, 2020
a595645
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 2, 2020
0c7ff87
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 8, 2020
ddd4bcf
shorter + more doc
original-brownbear Jan 8, 2020
0e345b8
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 9, 2020
13c7a12
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 10, 2020
49a20c1
better
original-brownbear Jan 10, 2020
d48dcf0
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jan 20, 2020
c240fa2
fix stuff
original-brownbear Jan 20, 2020
cf64179
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 6, 2020
dcc706f
works
original-brownbear Feb 6, 2020
557ed6c
resolve conflicts and dry stuff up
original-brownbear Feb 6, 2020
c3609ae
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 6, 2020
f79923d
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 7, 2020
c507bf1
fix javadoc
original-brownbear Feb 7, 2020
cb317cd
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 17, 2020
f4ad476
shorter diff
original-brownbear Feb 17, 2020
48f94f5
nicer
original-brownbear Feb 17, 2020
1c37b12
fix bwc test
original-brownbear Feb 17, 2020
280d521
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 18, 2020
e877513
hash -> identifier
original-brownbear Feb 18, 2020
edffedb
renaming
original-brownbear Feb 18, 2020
0794f29
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Feb 21, 2020
0c23a12
write correct min version + renaming var
original-brownbear Feb 21, 2020
72ee151
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Mar 22, 2020
19b5c4b
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Apr 27, 2020
31f27c4
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear May 18, 2020
b8c7845
fix
original-brownbear May 18, 2020
478e316
actually be efficient now that we can
original-brownbear May 18, 2020
de37e85
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear May 25, 2020
85d7d13
add use of history uuid
original-brownbear May 25, 2020
d154bde
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear May 25, 2020
179654f
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear May 29, 2020
bf095d9
Merge remote-tracking branch 'elastic/master' into deduplicate-index-…
original-brownbear Jun 5, 2020
c9ab2fc
CR: comments
original-brownbear Jun 5, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ public void testEnforcedCooldownPeriod() throws IOException {
final RepositoryData repositoryData = getRepositoryData(repository);
final RepositoryData modifiedRepositoryData = repositoryData.withVersions(Collections.singletonMap(fakeOldSnapshot,
SnapshotsService.SHARD_GEN_IN_REPO_DATA_VERSION.minimumCompatibilityVersion()));
final BytesReference serialized =
BytesReference.bytes(modifiedRepositoryData.snapshotsToXContent(XContentFactory.jsonBuilder(), false));
final BytesReference serialized = BytesReference.bytes(modifiedRepositoryData.snapshotsToXContent(XContentFactory.jsonBuilder(),
SnapshotsService.OLD_SNAPSHOT_FORMAT));
PlainActionFuture.get(f -> repository.threadPool().generic().execute(ActionRunnable.run(f, () -> {
try (InputStream stream = serialized.streamInput()) {
repository.blobStore().blobContainer(repository.basePath()).writeBlobAtomic(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public void testUpgradeMovesRepoToNewMetaVersion() throws IOException {
ensureSnapshotRestoreWorks(client, repoName, "snapshot-2", shards);
}
} else {
if (SnapshotsService.useShardGenerations(minimumNodeVersion()) == false) {
if (SnapshotsService.useIndexGenerations(minimumNodeVersion()) == false) {
assertThat(TEST_STEP, is(TestStep.STEP3_OLD_CLUSTER));
final List<Class<? extends Exception>> expectedExceptions =
List.of(ResponseException.class, ElasticsearchStatusException.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.repositories.IndexMetaDataGenerations;
import org.elasticsearch.repositories.RepositoriesService;
import org.elasticsearch.repositories.Repository;
import org.elasticsearch.repositories.RepositoryData;
Expand Down Expand Up @@ -232,11 +233,12 @@ public void testHandlingMissingRootLevelSnapshotMetadata() throws Exception {
SnapshotId::getUUID, Function.identity())),
repositoryData.getSnapshotIds().stream().collect(Collectors.toMap(
SnapshotId::getUUID, repositoryData::getSnapshotState)),
Collections.emptyMap(), Collections.emptyMap(), ShardGenerations.EMPTY);
Collections.emptyMap(), Collections.emptyMap(), ShardGenerations.EMPTY, IndexMetaDataGenerations.EMPTY);

Files.write(repo.resolve(BlobStoreRepository.INDEX_FILE_PREFIX + withoutVersions.getGenId()),
BytesReference.toBytes(BytesReference.bytes(withoutVersions.snapshotsToXContent(XContentFactory.jsonBuilder(),
true))), StandardOpenOption.TRUNCATE_EXISTING);
BytesReference.toBytes(BytesReference.bytes(
withoutVersions.snapshotsToXContent(XContentFactory.jsonBuilder(), Version.CURRENT))),
StandardOpenOption.TRUNCATE_EXISTING);

logger.info("--> verify that repo is assumed in old metadata format");
final SnapshotsService snapshotsService = internalCluster().getCurrentMasterNodeInstance(SnapshotsService.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.elasticsearch.node.Node;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.repositories.RepositoryMissingException;
import org.elasticsearch.repositories.blobstore.BlobStoreRepository;
import org.elasticsearch.rest.AbstractRestChannel;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.rest.RestResponse;
Expand Down Expand Up @@ -1110,6 +1111,8 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException {

SnapshotStats stats = snapshots.get(0).getStats();

final List<Path> snapshot0IndexMetaFiles = findRepoMetaBlobs(repoPath);
assertThat(snapshot0IndexMetaFiles, hasSize(1)); // snapshotting a single index
assertThat(stats.getTotalFileCount(), greaterThanOrEqualTo(snapshot0FileCount));
assertThat(stats.getTotalSize(), greaterThanOrEqualTo(snapshot0FileSize));

Expand Down Expand Up @@ -1142,6 +1145,10 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException {
.get();

final List<Path> snapshot1Files = scanSnapshotFolder(repoPath);
final List<Path> snapshot1IndexMetaFiles = findRepoMetaBlobs(repoPath);

// The IndexMetadata did not change between snapshots, verify that no new redundant IndexMetaData was written to the repository
assertThat(snapshot1IndexMetaFiles, is(snapshot0IndexMetaFiles));

final int snapshot1FileCount = snapshot1Files.size();
final long snapshot1FileSize = calculateTotalFilesSize(snapshot1Files);
Expand All @@ -1166,6 +1173,65 @@ public void testSnapshotTotalAndIncrementalSizes() throws IOException {
assertThat(anotherStats.getTotalSize(), greaterThanOrEqualTo(snapshot1FileSize));
}

public void testDeduplicateIndexMetadata() throws Exception {
final String indexName = "test-blocks-1";
final String repositoryName = "repo-" + indexName;
final String snapshot0 = "snapshot-0";
final String snapshot1 = "snapshot-1";
final String snapshot2 = "snapshot-2";

createIndex(indexName);

int docs = between(10, 100);
for (int i = 0; i < docs; i++) {
client().prepareIndex(indexName).setSource("test", "init").execute().actionGet();
}

final Path repoPath = randomRepoPath();
createRepository(repositoryName, "fs", repoPath);

logger.info("--> create a snapshot");
client().admin().cluster().prepareCreateSnapshot(repositoryName, snapshot0)
.setIncludeGlobalState(true)
.setWaitForCompletion(true)
.get();

final List<Path> snapshot0IndexMetaFiles = findRepoMetaBlobs(repoPath);
assertThat(snapshot0IndexMetaFiles, hasSize(1)); // snapshotting a single index

docs = between(1, 5);
for (int i = 0; i < docs; i++) {
client().prepareIndex(indexName).setSource("test", "test" + i).execute().actionGet();
}

logger.info("--> restart random data node and add new data node to change index allocation");
internalCluster().restartRandomDataNode();
internalCluster().startDataOnlyNode();
ensureGreen(indexName);

assertThat(client().admin().cluster().prepareCreateSnapshot(repositoryName, snapshot1).setWaitForCompletion(true).get().status(),
equalTo(RestStatus.OK));

final List<Path> snapshot1IndexMetaFiles = findRepoMetaBlobs(repoPath);

// The IndexMetadata did not change between snapshots, verify that no new redundant IndexMetaData was written to the repository
assertThat(snapshot1IndexMetaFiles, is(snapshot0IndexMetaFiles));

// index to some other field to trigger a change in index metadata
for (int i = 0; i < docs; i++) {
client().prepareIndex(indexName).setSource("new_field", "test" + i).execute().actionGet();
}
assertThat(client().admin().cluster().prepareCreateSnapshot(repositoryName, snapshot2).setWaitForCompletion(true).get().status(),
equalTo(RestStatus.OK));

final List<Path> snapshot2IndexMetaFiles = findRepoMetaBlobs(repoPath);
assertThat(snapshot2IndexMetaFiles, hasSize(2)); // should have created one new metadata blob

assertAcked(client().admin().cluster().prepareDeleteSnapshot(repositoryName, snapshot0, snapshot1).get());
final List<Path> snapshot3IndexMetaFiles = findRepoMetaBlobs(repoPath);
assertThat(snapshot3IndexMetaFiles, hasSize(1)); // should have deleted the metadata blob referenced by the first two snapshots
}

public void testDataNodeRestartWithBusyMasterDuringSnapshot() throws Exception {
logger.info("--> starting a master node and two data nodes");
internalCluster().startMasterOnlyNode();
Expand Down Expand Up @@ -1345,6 +1411,22 @@ private long calculateTotalFilesSize(List<Path> files) {
}).sum();
}

private static List<Path> findRepoMetaBlobs(Path repoPath) throws IOException {
List<Path> files = new ArrayList<>();
Files.walkFileTree(repoPath.resolve("indices"), new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
final String fileName = file.getFileName().toString();
if (fileName.startsWith(BlobStoreRepository.METADATA_PREFIX) && fileName.endsWith(".dat")) {
files.add(file);
}
return super.visitFile(file, attrs);
}
}
);
return files;
}

private List<Path> scanSnapshotFolder(Path repoPath) throws IOException {
List<Path> files = new ArrayList<>();
Files.walkFileTree(repoPath, new SimpleFileVisitor<Path>(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse;
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusResponse;
import org.elasticsearch.action.support.PlainActionFuture;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.RepositoryMetadata;
Expand All @@ -33,6 +34,7 @@
import org.elasticsearch.repositories.IndexId;
import org.elasticsearch.repositories.RepositoriesService;
import org.elasticsearch.repositories.Repository;
import org.elasticsearch.repositories.RepositoryData;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.snapshots.mockstore.MockRepository;

Expand Down Expand Up @@ -193,9 +195,10 @@ public Metadata getSnapshotGlobalMetadata(SnapshotId snapshotId) {
}

@Override
public IndexMetadata getSnapshotIndexMetadata(SnapshotId snapshotId, IndexId indexId) throws IOException {
public IndexMetadata getSnapshotIndexMetaData(RepositoryData repositoryData, SnapshotId snapshotId,
IndexId indexId) throws IOException {
indicesMetadata.computeIfAbsent(key(snapshotId.getName(), indexId.getName()), (s) -> new AtomicInteger(0)).incrementAndGet();
return super.getSnapshotIndexMetadata(snapshotId, indexId);
return super.getSnapshotIndexMetaData(PlainActionFuture.get(this::getRepositoryData), snapshotId, indexId);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2888,7 +2888,8 @@ public void testRestoreSnapshotWithCorruptedIndexMetadata() throws Exception {
final IndexId corruptedIndex = randomFrom(indexIds.values());
final Path indexMetadataPath = repo.resolve("indices")
.resolve(corruptedIndex.getId())
.resolve("meta-" + snapshotInfo.snapshotId().getUUID() + ".dat");
.resolve(
"meta-" + repositoryData.indexMetaDataGenerations().indexMetaBlobId(snapshotInfo.snapshotId(), corruptedIndex) + ".dat");

// Truncate the index metadata file
try(SeekableByteChannel outChan = Files.newByteChannel(indexMetadataPath, StandardOpenOption.WRITE)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ private Map<ShardId, IndexShardSnapshotStatus> snapshotShards(final String repos
final Map<ShardId, IndexShardSnapshotStatus> shardStatus = new HashMap<>();
for (String index : snapshotInfo.indices()) {
IndexId indexId = repositoryData.resolveIndexId(index);
IndexMetadata indexMetadata = repository.getSnapshotIndexMetadata(snapshotInfo.snapshotId(), indexId);
IndexMetadata indexMetadata = repository.getSnapshotIndexMetaData(repositoryData, snapshotInfo.snapshotId(), indexId);
if (indexMetadata != null) {
int numberOfShards = indexMetadata.getNumberOfShards();
for (int i = 0; i < numberOfShards; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ public Metadata getSnapshotGlobalMetadata(SnapshotId snapshotId) {
}

@Override
public IndexMetadata getSnapshotIndexMetadata(SnapshotId snapshotId, IndexId index) throws IOException {
return in.getSnapshotIndexMetadata(snapshotId, index);
public IndexMetadata getSnapshotIndexMetaData(RepositoryData repositoryData, SnapshotId snapshotId, IndexId index) throws IOException {
return in.getSnapshotIndexMetaData(repositoryData, snapshotId, index);
}

@Override
Expand Down
Loading