|
7 | 7 |
|
8 | 8 | package org.elasticsearch.xpack.searchablesnapshots;
|
9 | 9 |
|
| 10 | +import org.apache.lucene.index.SegmentInfos; |
10 | 11 | import org.apache.lucene.search.TotalHits;
|
| 12 | +import org.apache.lucene.store.ByteBuffersDirectory; |
| 13 | +import org.apache.lucene.store.Directory; |
| 14 | +import org.apache.lucene.store.FilterDirectory; |
11 | 15 | import org.elasticsearch.ResourceNotFoundException;
|
12 | 16 | import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
|
13 | 17 | import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotIndexShardStatus;
|
|
17 | 21 | import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
18 | 22 | import org.elasticsearch.cluster.metadata.IndexMetadata;
|
19 | 23 | import org.elasticsearch.cluster.node.DiscoveryNode;
|
| 24 | +import org.elasticsearch.cluster.routing.ShardRouting; |
20 | 25 | import org.elasticsearch.cluster.routing.allocation.decider.Decision;
|
21 | 26 | import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
|
22 | 27 | import org.elasticsearch.common.Priority;
|
|
32 | 37 | import org.elasticsearch.index.store.Store;
|
33 | 38 | import org.elasticsearch.index.store.StoreStats;
|
34 | 39 | import org.elasticsearch.indices.IndexClosedException;
|
| 40 | +import org.elasticsearch.indices.IndicesService; |
35 | 41 | import org.elasticsearch.snapshots.SnapshotInfo;
|
36 | 42 | import org.elasticsearch.xpack.cluster.routing.allocation.DataTierAllocationDecider;
|
37 | 43 | import org.elasticsearch.xpack.core.DataTier;
|
|
54 | 60 | import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshots.getDataTiersPreference;
|
55 | 61 | import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsConstants.SNAPSHOT_DIRECTORY_FACTORY_KEY;
|
56 | 62 | import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsConstants.SNAPSHOT_RECOVERY_STATE_FACTORY_KEY;
|
| 63 | +import static org.hamcrest.Matchers.arrayWithSize; |
57 | 64 | import static org.hamcrest.Matchers.equalTo;
|
58 | 65 | import static org.hamcrest.Matchers.greaterThan;
|
59 |
| -import static org.hamcrest.Matchers.greaterThanOrEqualTo; |
60 |
| -import static org.hamcrest.Matchers.lessThan; |
| 66 | +import static org.hamcrest.Matchers.instanceOf; |
| 67 | +import static org.hamcrest.Matchers.notNullValue; |
61 | 68 | import static org.hamcrest.Matchers.oneOf;
|
62 | 69 | import static org.hamcrest.Matchers.sameInstance;
|
63 | 70 |
|
@@ -219,24 +226,40 @@ public void testCreateAndRestorePartialSearchableSnapshot() throws Exception {
|
219 | 226 | long totalExpectedSize = 0;
|
220 | 227 | for (ShardStats shardStats : indicesStatsResponse.getShards()) {
|
221 | 228 | StoreStats store = shardStats.getStats().getStore();
|
222 |
| - assertThat(shardStats.getShardRouting().toString(), store.getReservedSize().getBytes(), equalTo(0L)); |
223 |
| - assertThat(shardStats.getShardRouting().toString(), store.getSize().getBytes(), equalTo(0L)); |
224 |
| - |
225 |
| - // the extra segments_N file created for bootstrap new history and associate translog makes us unable to precisely assert this. |
226 |
| - final long expectedSize = snapshotShards.get(shardStats.getShardRouting().getId()).getStats().getTotalSize(); |
227 |
| - assertThat(shardStats.getShardRouting().toString(), store.getTotalDataSetSize().getBytes(), greaterThanOrEqualTo(expectedSize)); |
228 |
| - // the extra segments_N file only has a new history UUID and translog UUID, both of which have constant size. It's size is |
229 |
| - // therefore identical to the original segments_N file from the snapshot. We expect at least 1 byte of other content, making |
230 |
| - // it safe to assert that the total data set size is less than 2x the size. |
231 |
| - assertThat(shardStats.getShardRouting().toString(), store.getTotalDataSetSize().getBytes(), lessThan(expectedSize * 2)); |
232 |
| - |
233 |
| - totalExpectedSize += expectedSize; |
| 229 | + |
| 230 | + final ShardRouting shardRouting = shardStats.getShardRouting(); |
| 231 | + assertThat(shardRouting.toString(), store.getReservedSize().getBytes(), equalTo(0L)); |
| 232 | + assertThat(shardRouting.toString(), store.getSize().getBytes(), equalTo(0L)); |
| 233 | + |
| 234 | + // the original shard size from the snapshot |
| 235 | + final long originalSize = snapshotShards.get(shardRouting.getId()).getStats().getTotalSize(); |
| 236 | + totalExpectedSize += originalSize; |
| 237 | + |
| 238 | + // an extra segments_N file is created for bootstrapping new history and associating translog. We can extract the size of this |
| 239 | + // extra file but we have to unwrap the in-memory directory first. |
| 240 | + final Directory unwrappedDir = FilterDirectory.unwrap( |
| 241 | + internalCluster().getInstance(IndicesService.class, getDiscoveryNodes().resolveNode(shardRouting.currentNodeId()).getName()) |
| 242 | + .indexServiceSafe(shardRouting.index()) |
| 243 | + .getShard(shardRouting.getId()) |
| 244 | + .store() |
| 245 | + .directory() |
| 246 | + ); |
| 247 | + assertThat(shardRouting.toString(), unwrappedDir, notNullValue()); |
| 248 | + assertThat(shardRouting.toString(), unwrappedDir, instanceOf(ByteBuffersDirectory.class)); |
| 249 | + |
| 250 | + final ByteBuffersDirectory inMemoryDir = (ByteBuffersDirectory) unwrappedDir; |
| 251 | + assertThat(inMemoryDir.listAll(), arrayWithSize(1)); |
| 252 | + |
| 253 | + final String segmentsFileName = SegmentInfos.getLastCommitSegmentsFileName(inMemoryDir); |
| 254 | + assertThat("Fail to find segment file name directory for " + shardRouting.toString(), segmentsFileName, notNullValue()); |
| 255 | + final long extraSegmentFileSize = inMemoryDir.fileLength(segmentsFileName); |
| 256 | + |
| 257 | + assertThat(shardRouting.toString(), store.getTotalDataSetSize().getBytes(), equalTo(originalSize + extraSegmentFileSize)); |
| 258 | + totalExpectedSize += extraSegmentFileSize; |
234 | 259 | }
|
235 | 260 |
|
236 |
| - // the extra segments_N file created for bootstrap new history and associate translog makes us unable to precisely assert this. |
237 | 261 | final StoreStats store = indicesStatsResponse.getTotal().getStore();
|
238 |
| - assertThat(store.getTotalDataSetSize().getBytes(), greaterThanOrEqualTo(totalExpectedSize)); |
239 |
| - assertThat(store.getTotalDataSetSize().getBytes(), lessThan(totalExpectedSize * 2)); |
| 262 | + assertThat(store.getTotalDataSetSize().getBytes(), equalTo(totalExpectedSize)); |
240 | 263 |
|
241 | 264 | statsWatcherRunning.set(false);
|
242 | 265 | statsWatcher.join();
|
|
0 commit comments