|
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