Skip to content

Commit eb7480e

Browse files
authored
More precise total data set size verification in FrozenSearchableSnapshotsIntegTests (#73243)
In #70625 we added the total data set size of shards to the Indices Stats API and we enhanced the test testCreateAndRestorePartialSearchableSnapshot to also verify the correctness of this data set size. Because restoring a searchable snapshot shard creates a new in-memory segment size, the verification of the data set size was implemented in an approximative fashion: between the expected size and twice the expected size. This approximation sometimes fails for shards that have no documents indexed (see #73194). This commit changes the test so that it now verifies the exact data set size returned by the Indices Stats API, which should be the sum of the original expected size of the snapshotted size + the length of the extra segment file in memory. Closes #73194
1 parent 67680db commit eb7480e

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/FrozenSearchableSnapshotsIntegTests.java

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@
77

88
package org.elasticsearch.xpack.searchablesnapshots;
99

10+
import org.apache.lucene.index.SegmentInfos;
1011
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;
1115
import org.elasticsearch.ResourceNotFoundException;
1216
import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotResponse;
1317
import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotIndexShardStatus;
@@ -17,6 +21,7 @@
1721
import org.elasticsearch.action.admin.indices.stats.ShardStats;
1822
import org.elasticsearch.cluster.metadata.IndexMetadata;
1923
import org.elasticsearch.cluster.node.DiscoveryNode;
24+
import org.elasticsearch.cluster.routing.ShardRouting;
2025
import org.elasticsearch.cluster.routing.allocation.decider.Decision;
2126
import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider;
2227
import org.elasticsearch.common.Priority;
@@ -32,6 +37,7 @@
3237
import org.elasticsearch.index.store.Store;
3338
import org.elasticsearch.index.store.StoreStats;
3439
import org.elasticsearch.indices.IndexClosedException;
40+
import org.elasticsearch.indices.IndicesService;
3541
import org.elasticsearch.snapshots.SnapshotInfo;
3642
import org.elasticsearch.xpack.cluster.routing.allocation.DataTierAllocationDecider;
3743
import org.elasticsearch.xpack.core.DataTier;
@@ -54,10 +60,11 @@
5460
import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshots.getDataTiersPreference;
5561
import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsConstants.SNAPSHOT_DIRECTORY_FACTORY_KEY;
5662
import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshotsConstants.SNAPSHOT_RECOVERY_STATE_FACTORY_KEY;
63+
import static org.hamcrest.Matchers.arrayWithSize;
5764
import static org.hamcrest.Matchers.equalTo;
5865
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;
6168
import static org.hamcrest.Matchers.oneOf;
6269
import static org.hamcrest.Matchers.sameInstance;
6370

@@ -219,24 +226,40 @@ public void testCreateAndRestorePartialSearchableSnapshot() throws Exception {
219226
long totalExpectedSize = 0;
220227
for (ShardStats shardStats : indicesStatsResponse.getShards()) {
221228
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;
234259
}
235260

236-
// the extra segments_N file created for bootstrap new history and associate translog makes us unable to precisely assert this.
237261
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));
240263

241264
statsWatcherRunning.set(false);
242265
statsWatcher.join();

0 commit comments

Comments
 (0)