IndexShard should not return null stats (#31528)
IndexShard should not return null stats - empty stats or AlreadyCloseException if it's closed is better
This commit is contained in:
parent
1d11fdaad8
commit
2ba50dbf50
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.admin.cluster.stats;
|
package org.elasticsearch.action.admin.cluster.stats;
|
||||||
|
|
||||||
|
import org.apache.lucene.store.AlreadyClosedException;
|
||||||
import org.elasticsearch.action.FailedNodeException;
|
import org.elasticsearch.action.FailedNodeException;
|
||||||
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
|
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
|
||||||
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
|
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
|
||||||
|
@ -36,6 +37,8 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.IndexService;
|
import org.elasticsearch.index.IndexService;
|
||||||
|
import org.elasticsearch.index.engine.CommitStats;
|
||||||
|
import org.elasticsearch.index.seqno.SeqNoStats;
|
||||||
import org.elasticsearch.index.shard.IndexShard;
|
import org.elasticsearch.index.shard.IndexShard;
|
||||||
import org.elasticsearch.indices.IndicesService;
|
import org.elasticsearch.indices.IndicesService;
|
||||||
import org.elasticsearch.node.NodeService;
|
import org.elasticsearch.node.NodeService;
|
||||||
|
@ -96,13 +99,23 @@ public class TransportClusterStatsAction extends TransportNodesAction<ClusterSta
|
||||||
for (IndexShard indexShard : indexService) {
|
for (IndexShard indexShard : indexService) {
|
||||||
if (indexShard.routingEntry() != null && indexShard.routingEntry().active()) {
|
if (indexShard.routingEntry() != null && indexShard.routingEntry().active()) {
|
||||||
// only report on fully started shards
|
// only report on fully started shards
|
||||||
|
CommitStats commitStats;
|
||||||
|
SeqNoStats seqNoStats;
|
||||||
|
try {
|
||||||
|
commitStats = indexShard.commitStats();
|
||||||
|
seqNoStats = indexShard.seqNoStats();
|
||||||
|
} catch (AlreadyClosedException e) {
|
||||||
|
// shard is closed - no stats is fine
|
||||||
|
commitStats = null;
|
||||||
|
seqNoStats = null;
|
||||||
|
}
|
||||||
shardsStats.add(
|
shardsStats.add(
|
||||||
new ShardStats(
|
new ShardStats(
|
||||||
indexShard.routingEntry(),
|
indexShard.routingEntry(),
|
||||||
indexShard.shardPath(),
|
indexShard.shardPath(),
|
||||||
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, SHARD_STATS_FLAGS),
|
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, SHARD_STATS_FLAGS),
|
||||||
indexShard.commitStats(),
|
commitStats,
|
||||||
indexShard.seqNoStats()));
|
seqNoStats));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.admin.indices.stats;
|
package org.elasticsearch.action.admin.indices.stats;
|
||||||
|
|
||||||
|
import org.apache.lucene.store.AlreadyClosedException;
|
||||||
import org.elasticsearch.common.Nullable;
|
import org.elasticsearch.common.Nullable;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
@ -167,57 +168,61 @@ public class CommonStats implements Writeable, ToXContentFragment {
|
||||||
public CommonStats(IndicesQueryCache indicesQueryCache, IndexShard indexShard, CommonStatsFlags flags) {
|
public CommonStats(IndicesQueryCache indicesQueryCache, IndexShard indexShard, CommonStatsFlags flags) {
|
||||||
CommonStatsFlags.Flag[] setFlags = flags.getFlags();
|
CommonStatsFlags.Flag[] setFlags = flags.getFlags();
|
||||||
for (CommonStatsFlags.Flag flag : setFlags) {
|
for (CommonStatsFlags.Flag flag : setFlags) {
|
||||||
switch (flag) {
|
try {
|
||||||
case Docs:
|
switch (flag) {
|
||||||
docs = indexShard.docStats();
|
case Docs:
|
||||||
break;
|
docs = indexShard.docStats();
|
||||||
case Store:
|
break;
|
||||||
store = indexShard.storeStats();
|
case Store:
|
||||||
break;
|
store = indexShard.storeStats();
|
||||||
case Indexing:
|
break;
|
||||||
indexing = indexShard.indexingStats(flags.types());
|
case Indexing:
|
||||||
break;
|
indexing = indexShard.indexingStats(flags.types());
|
||||||
case Get:
|
break;
|
||||||
get = indexShard.getStats();
|
case Get:
|
||||||
break;
|
get = indexShard.getStats();
|
||||||
case Search:
|
break;
|
||||||
search = indexShard.searchStats(flags.groups());
|
case Search:
|
||||||
break;
|
search = indexShard.searchStats(flags.groups());
|
||||||
case Merge:
|
break;
|
||||||
merge = indexShard.mergeStats();
|
case Merge:
|
||||||
break;
|
merge = indexShard.mergeStats();
|
||||||
case Refresh:
|
break;
|
||||||
refresh = indexShard.refreshStats();
|
case Refresh:
|
||||||
break;
|
refresh = indexShard.refreshStats();
|
||||||
case Flush:
|
break;
|
||||||
flush = indexShard.flushStats();
|
case Flush:
|
||||||
break;
|
flush = indexShard.flushStats();
|
||||||
case Warmer:
|
break;
|
||||||
warmer = indexShard.warmerStats();
|
case Warmer:
|
||||||
break;
|
warmer = indexShard.warmerStats();
|
||||||
case QueryCache:
|
break;
|
||||||
queryCache = indicesQueryCache.getStats(indexShard.shardId());
|
case QueryCache:
|
||||||
break;
|
queryCache = indicesQueryCache.getStats(indexShard.shardId());
|
||||||
case FieldData:
|
break;
|
||||||
fieldData = indexShard.fieldDataStats(flags.fieldDataFields());
|
case FieldData:
|
||||||
break;
|
fieldData = indexShard.fieldDataStats(flags.fieldDataFields());
|
||||||
case Completion:
|
break;
|
||||||
completion = indexShard.completionStats(flags.completionDataFields());
|
case Completion:
|
||||||
break;
|
completion = indexShard.completionStats(flags.completionDataFields());
|
||||||
case Segments:
|
break;
|
||||||
segments = indexShard.segmentStats(flags.includeSegmentFileSizes());
|
case Segments:
|
||||||
break;
|
segments = indexShard.segmentStats(flags.includeSegmentFileSizes());
|
||||||
case Translog:
|
break;
|
||||||
translog = indexShard.translogStats();
|
case Translog:
|
||||||
break;
|
translog = indexShard.translogStats();
|
||||||
case RequestCache:
|
break;
|
||||||
requestCache = indexShard.requestCache().stats();
|
case RequestCache:
|
||||||
break;
|
requestCache = indexShard.requestCache().stats();
|
||||||
case Recovery:
|
break;
|
||||||
recoveryStats = indexShard.recoveryStats();
|
case Recovery:
|
||||||
break;
|
recoveryStats = indexShard.recoveryStats();
|
||||||
default:
|
break;
|
||||||
throw new IllegalStateException("Unknown Flag: " + flag);
|
default:
|
||||||
|
throw new IllegalStateException("Unknown Flag: " + flag);
|
||||||
|
}
|
||||||
|
} catch (AlreadyClosedException e) {
|
||||||
|
// shard is closed - no stats is fine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ public class ShardStats implements Streamable, Writeable, ToXContentFragment {
|
||||||
return this.commonStats;
|
return this.commonStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
public CommitStats getCommitStats() {
|
public CommitStats getCommitStats() {
|
||||||
return this.commitStats;
|
return this.commitStats;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.action.admin.indices.stats;
|
package org.elasticsearch.action.admin.indices.stats;
|
||||||
|
|
||||||
|
import org.apache.lucene.store.AlreadyClosedException;
|
||||||
import org.elasticsearch.action.support.ActionFilters;
|
import org.elasticsearch.action.support.ActionFilters;
|
||||||
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
|
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
|
||||||
import org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction;
|
import org.elasticsearch.action.support.broadcast.node.TransportBroadcastByNodeAction;
|
||||||
|
@ -33,6 +34,8 @@ import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.io.stream.StreamInput;
|
import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.settings.Settings;
|
import org.elasticsearch.common.settings.Settings;
|
||||||
import org.elasticsearch.index.IndexService;
|
import org.elasticsearch.index.IndexService;
|
||||||
|
import org.elasticsearch.index.engine.CommitStats;
|
||||||
|
import org.elasticsearch.index.seqno.SeqNoStats;
|
||||||
import org.elasticsearch.index.shard.IndexShard;
|
import org.elasticsearch.index.shard.IndexShard;
|
||||||
import org.elasticsearch.index.shard.ShardNotFoundException;
|
import org.elasticsearch.index.shard.ShardNotFoundException;
|
||||||
import org.elasticsearch.indices.IndicesService;
|
import org.elasticsearch.indices.IndicesService;
|
||||||
|
@ -100,7 +103,17 @@ public class TransportIndicesStatsAction extends TransportBroadcastByNodeAction<
|
||||||
}
|
}
|
||||||
|
|
||||||
CommonStats commonStats = new CommonStats(indicesService.getIndicesQueryCache(), indexShard, request.flags());
|
CommonStats commonStats = new CommonStats(indicesService.getIndicesQueryCache(), indexShard, request.flags());
|
||||||
|
CommitStats commitStats;
|
||||||
|
SeqNoStats seqNoStats;
|
||||||
|
try {
|
||||||
|
commitStats = indexShard.commitStats();
|
||||||
|
seqNoStats = indexShard.seqNoStats();
|
||||||
|
} catch (AlreadyClosedException e) {
|
||||||
|
// shard is closed - no stats is fine
|
||||||
|
commitStats = null;
|
||||||
|
seqNoStats = null;
|
||||||
|
}
|
||||||
return new ShardStats(indexShard.routingEntry(), indexShard.shardPath(), commonStats,
|
return new ShardStats(indexShard.routingEntry(), indexShard.shardPath(), commonStats,
|
||||||
indexShard.commitStats(), indexShard.seqNoStats());
|
commitStats, seqNoStats);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -868,21 +868,19 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link CommitStats} if engine is open, otherwise null
|
* @return {@link CommitStats}
|
||||||
|
* @throws AlreadyClosedException if shard is closed
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public CommitStats commitStats() {
|
public CommitStats commitStats() {
|
||||||
Engine engine = getEngineOrNull();
|
return getEngine().commitStats();
|
||||||
return engine == null ? null : engine.commitStats();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {@link SeqNoStats} if engine is open, otherwise null
|
* @return {@link SeqNoStats}
|
||||||
|
* @throws AlreadyClosedException if shard is closed
|
||||||
*/
|
*/
|
||||||
@Nullable
|
|
||||||
public SeqNoStats seqNoStats() {
|
public SeqNoStats seqNoStats() {
|
||||||
Engine engine = getEngineOrNull();
|
return getEngine().getSeqNoStats(replicationTracker.getGlobalCheckpoint());
|
||||||
return engine == null ? null : engine.getSeqNoStats(replicationTracker.getGlobalCheckpoint());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IndexingStats indexingStats(String... types) {
|
public IndexingStats indexingStats(String... types) {
|
||||||
|
@ -912,8 +910,6 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
|
||||||
return store.stats();
|
return store.stats();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new ElasticsearchException("io exception while building 'store stats'", e);
|
throw new ElasticsearchException("io exception while building 'store stats'", e);
|
||||||
} catch (AlreadyClosedException ex) {
|
|
||||||
return null; // already closed
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,7 @@ import org.elasticsearch.index.IndexService;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.index.analysis.AnalysisRegistry;
|
import org.elasticsearch.index.analysis.AnalysisRegistry;
|
||||||
import org.elasticsearch.index.cache.request.ShardRequestCache;
|
import org.elasticsearch.index.cache.request.ShardRequestCache;
|
||||||
|
import org.elasticsearch.index.engine.CommitStats;
|
||||||
import org.elasticsearch.index.engine.EngineFactory;
|
import org.elasticsearch.index.engine.EngineFactory;
|
||||||
import org.elasticsearch.index.engine.InternalEngineFactory;
|
import org.elasticsearch.index.engine.InternalEngineFactory;
|
||||||
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
import org.elasticsearch.index.fielddata.IndexFieldDataCache;
|
||||||
|
@ -91,6 +92,7 @@ import org.elasticsearch.index.query.QueryRewriteContext;
|
||||||
import org.elasticsearch.index.recovery.RecoveryStats;
|
import org.elasticsearch.index.recovery.RecoveryStats;
|
||||||
import org.elasticsearch.index.refresh.RefreshStats;
|
import org.elasticsearch.index.refresh.RefreshStats;
|
||||||
import org.elasticsearch.index.search.stats.SearchStats;
|
import org.elasticsearch.index.search.stats.SearchStats;
|
||||||
|
import org.elasticsearch.index.seqno.SeqNoStats;
|
||||||
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
|
import org.elasticsearch.index.shard.IllegalIndexShardStateException;
|
||||||
import org.elasticsearch.index.shard.IndexEventListener;
|
import org.elasticsearch.index.shard.IndexEventListener;
|
||||||
import org.elasticsearch.index.shard.IndexShard;
|
import org.elasticsearch.index.shard.IndexShard;
|
||||||
|
@ -333,13 +335,24 @@ public class IndicesService extends AbstractLifecycleComponent
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommitStats commitStats;
|
||||||
|
SeqNoStats seqNoStats;
|
||||||
|
try {
|
||||||
|
commitStats = indexShard.commitStats();
|
||||||
|
seqNoStats = indexShard.seqNoStats();
|
||||||
|
} catch (AlreadyClosedException e) {
|
||||||
|
// shard is closed - no stats is fine
|
||||||
|
commitStats = null;
|
||||||
|
seqNoStats = null;
|
||||||
|
}
|
||||||
|
|
||||||
return new IndexShardStats(indexShard.shardId(),
|
return new IndexShardStats(indexShard.shardId(),
|
||||||
new ShardStats[] {
|
new ShardStats[] {
|
||||||
new ShardStats(indexShard.routingEntry(),
|
new ShardStats(indexShard.routingEntry(),
|
||||||
indexShard.shardPath(),
|
indexShard.shardPath(),
|
||||||
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, flags),
|
new CommonStats(indicesService.getIndicesQueryCache(), indexShard, flags),
|
||||||
indexShard.commitStats(),
|
commitStats,
|
||||||
indexShard.seqNoStats())
|
seqNoStats)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,6 +73,7 @@ import org.elasticsearch.core.internal.io.IOUtils;
|
||||||
import org.elasticsearch.env.NodeEnvironment;
|
import org.elasticsearch.env.NodeEnvironment;
|
||||||
import org.elasticsearch.index.IndexSettings;
|
import org.elasticsearch.index.IndexSettings;
|
||||||
import org.elasticsearch.index.VersionType;
|
import org.elasticsearch.index.VersionType;
|
||||||
|
import org.elasticsearch.index.engine.CommitStats;
|
||||||
import org.elasticsearch.index.engine.Engine;
|
import org.elasticsearch.index.engine.Engine;
|
||||||
import org.elasticsearch.index.engine.EngineException;
|
import org.elasticsearch.index.engine.EngineException;
|
||||||
import org.elasticsearch.index.engine.EngineTestCase;
|
import org.elasticsearch.index.engine.EngineTestCase;
|
||||||
|
@ -88,6 +89,7 @@ import org.elasticsearch.index.mapper.IdFieldMapper;
|
||||||
import org.elasticsearch.index.mapper.MappedFieldType;
|
import org.elasticsearch.index.mapper.MappedFieldType;
|
||||||
import org.elasticsearch.index.mapper.SourceToParse;
|
import org.elasticsearch.index.mapper.SourceToParse;
|
||||||
import org.elasticsearch.index.mapper.Uid;
|
import org.elasticsearch.index.mapper.Uid;
|
||||||
|
import org.elasticsearch.index.seqno.SeqNoStats;
|
||||||
import org.elasticsearch.index.seqno.SequenceNumbers;
|
import org.elasticsearch.index.seqno.SequenceNumbers;
|
||||||
import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus;
|
import org.elasticsearch.index.snapshots.IndexShardSnapshotStatus;
|
||||||
import org.elasticsearch.index.store.Store;
|
import org.elasticsearch.index.store.Store;
|
||||||
|
@ -3082,4 +3084,36 @@ public class IndexShardTests extends IndexShardTestCase {
|
||||||
closeShards(primary);
|
closeShards(primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testOnCloseStats() throws IOException {
|
||||||
|
final IndexShard indexShard = newStartedShard(true);
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
indexDoc(indexShard, "_doc", "" + i, "{\"foo\" : \"" + randomAlphaOfLength(10) + "\"}");
|
||||||
|
indexShard.refresh("test"); // produce segments
|
||||||
|
}
|
||||||
|
|
||||||
|
// check stats on closed and on opened shard
|
||||||
|
if (randomBoolean()) {
|
||||||
|
closeShards(indexShard);
|
||||||
|
|
||||||
|
expectThrows(AlreadyClosedException.class, () -> indexShard.seqNoStats());
|
||||||
|
expectThrows(AlreadyClosedException.class, () -> indexShard.commitStats());
|
||||||
|
expectThrows(AlreadyClosedException.class, () -> indexShard.storeStats());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
final SeqNoStats seqNoStats = indexShard.seqNoStats();
|
||||||
|
assertThat(seqNoStats.getLocalCheckpoint(), equalTo(2L));
|
||||||
|
|
||||||
|
final CommitStats commitStats = indexShard.commitStats();
|
||||||
|
assertThat(commitStats.getGeneration(), equalTo(2L));
|
||||||
|
|
||||||
|
final StoreStats storeStats = indexShard.storeStats();
|
||||||
|
|
||||||
|
assertThat(storeStats.sizeInBytes(), greaterThan(0L));
|
||||||
|
|
||||||
|
closeShards(indexShard);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1111,17 +1111,21 @@ public final class InternalTestCluster extends TestCluster {
|
||||||
IndicesService indexServices = getInstance(IndicesService.class, nodeAndClient.name);
|
IndicesService indexServices = getInstance(IndicesService.class, nodeAndClient.name);
|
||||||
for (IndexService indexService : indexServices) {
|
for (IndexService indexService : indexServices) {
|
||||||
for (IndexShard indexShard : indexService) {
|
for (IndexShard indexShard : indexService) {
|
||||||
CommitStats commitStats = indexShard.commitStats();
|
try {
|
||||||
if (commitStats != null) { // null if the engine is closed or if the shard is recovering
|
CommitStats commitStats = indexShard.commitStats();
|
||||||
String syncId = commitStats.getUserData().get(Engine.SYNC_COMMIT_ID);
|
String syncId = commitStats.getUserData().get(Engine.SYNC_COMMIT_ID);
|
||||||
if (syncId != null) {
|
if (syncId != null) {
|
||||||
long liveDocsOnShard = commitStats.getNumDocs();
|
long liveDocsOnShard = commitStats.getNumDocs();
|
||||||
if (docsOnShards.get(syncId) != null) {
|
if (docsOnShards.get(syncId) != null) {
|
||||||
assertThat("sync id is equal but number of docs does not match on node " + nodeAndClient.name + ". expected " + docsOnShards.get(syncId) + " but got " + liveDocsOnShard, docsOnShards.get(syncId), equalTo(liveDocsOnShard));
|
assertThat("sync id is equal but number of docs does not match on node "
|
||||||
|
+ nodeAndClient.name + ". expected " + docsOnShards.get(syncId) + " but got "
|
||||||
|
+ liveDocsOnShard, docsOnShards.get(syncId), equalTo(liveDocsOnShard));
|
||||||
} else {
|
} else {
|
||||||
docsOnShards.put(syncId, liveDocsOnShard);
|
docsOnShards.put(syncId, liveDocsOnShard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (AlreadyClosedException e) {
|
||||||
|
// the engine is closed or if the shard is recovering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue