Fix possible BWC break after upgrading from pre 1.0.0
This is happening because of #4074 when we required that the top-level "query" is present to delete-by-query requests, but prior to that we required that it is not present. So the translog has a DBQ without "query" and when we try to parse it we hit this exception. This commit adds special handling for pre 1.0.0 indices if we hit parse exception, we try to reparse without a top-level query object to be BWC compatible for these indices. Closes #10262 Conflicts: src/main/java/org/elasticsearch/index/shard/IndexShard.java src/test/java/org/elasticsearch/index/shard/IndexShardTests.java
This commit is contained in:
parent
aa248990bb
commit
7264fd4eb8
|
@ -21,11 +21,14 @@ package org.elasticsearch.index.shard;
|
|||
import org.apache.lucene.search.Query;
|
||||
import org.apache.lucene.search.join.BitDocIdSetFilter;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.index.aliases.IndexAliasesService;
|
||||
import org.elasticsearch.index.cache.IndexCache;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
|
@ -37,6 +40,8 @@ import org.elasticsearch.index.mapper.MapperUtils;
|
|||
import org.elasticsearch.index.mapper.Mapping;
|
||||
import org.elasticsearch.index.mapper.Uid;
|
||||
import org.elasticsearch.index.query.IndexQueryParserService;
|
||||
import org.elasticsearch.index.query.ParsedQuery;
|
||||
import org.elasticsearch.index.query.QueryParsingException;
|
||||
import org.elasticsearch.index.translog.Translog;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -160,7 +165,24 @@ public class TranslogRecoveryPerformer {
|
|||
if (types == null) {
|
||||
types = Strings.EMPTY_ARRAY;
|
||||
}
|
||||
Query query = queryParserService.parseQuery(source).query();
|
||||
Query query;
|
||||
try {
|
||||
query = queryParserService.parseQuery(source).query();
|
||||
} catch (QueryParsingException ex) {
|
||||
// for BWC we try to parse directly the query since pre 1.0.0.Beta2 we didn't require a top level query field
|
||||
if ( queryParserService.getIndexCreatedVersion().onOrBefore(Version.V_1_0_0_Beta2)) {
|
||||
try {
|
||||
XContentParser parser = XContentHelper.createParser(source);
|
||||
ParsedQuery parse = queryParserService.parse(parser);
|
||||
query = parse.query();
|
||||
} catch (Throwable t) {
|
||||
ex.addSuppressed(t);
|
||||
throw ex;
|
||||
}
|
||||
} else {
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
Query searchFilter = mapperService.searchFilter(types);
|
||||
if (searchFilter != null) {
|
||||
query = Queries.filtered(query, searchFilter);
|
||||
|
|
|
@ -19,22 +19,26 @@
|
|||
package org.elasticsearch.index.shard;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.action.admin.indices.stats.IndexStats;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.routing.MutableShardRouting;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.ShardRoutingState;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.NodeEnvironment;
|
||||
import org.elasticsearch.env.ShardLock;
|
||||
import org.elasticsearch.index.IndexService;
|
||||
import org.elasticsearch.index.engine.Engine;
|
||||
import org.elasticsearch.index.query.QueryParsingException;
|
||||
import org.elasticsearch.index.translog.Translog;
|
||||
import org.elasticsearch.index.translog.TranslogConfig;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.test.DummyShardLock;
|
||||
import org.elasticsearch.test.ElasticsearchSingleNodeTest;
|
||||
import org.elasticsearch.test.VersionUtils;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -329,4 +333,33 @@ public class IndexShardTests extends ElasticsearchSingleNodeTest {
|
|||
client().admin().indices().prepareUpdateSettings(shard.shardId.getIndex()).setSettings(settingsBuilder().put(TranslogConfig.INDEX_TRANSLOG_DURABILITY, durabilty.name()).build()).get();
|
||||
assertEquals(durabilty, shard.getTranslogDurability());
|
||||
}
|
||||
|
||||
public void testDeleteByQueryBWC() {
|
||||
Version version = VersionUtils.randomVersion(random());
|
||||
assertAcked(client().admin().indices().prepareCreate("test")
|
||||
.setSettings(SETTING_NUMBER_OF_SHARDS, 1, SETTING_NUMBER_OF_REPLICAS, 0, IndexMetaData.SETTING_VERSION_CREATED, version.id));
|
||||
ensureGreen("test");
|
||||
client().prepareIndex("test", "person").setSource("{ \"user\" : \"kimchy\" }").get();
|
||||
|
||||
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
|
||||
IndexService test = indicesService.indexService("test");
|
||||
IndexShard shard = test.shard(0);
|
||||
int numDocs = 1;
|
||||
shard.state = IndexShardState.RECOVERING;
|
||||
try {
|
||||
shard.recoveryState().getTranslog().totalOperations(1);
|
||||
shard.engine().config().getTranslogRecoveryPerformer().performRecoveryOperation(shard.engine(), new Translog.DeleteByQuery(new Engine.DeleteByQuery(null, new BytesArray("{\"term\" : { \"user\" : \"kimchy\" }}"), null, null, null, Engine.Operation.Origin.RECOVERY, 0, "person")));
|
||||
assertTrue(version.onOrBefore(Version.V_1_0_0_Beta2));
|
||||
numDocs = 0;
|
||||
} catch (QueryParsingException ex) {
|
||||
assertTrue(version.after(Version.V_1_0_0_Beta2));
|
||||
} finally {
|
||||
shard.state = IndexShardState.STARTED;
|
||||
}
|
||||
shard.engine().refresh("foo");
|
||||
|
||||
try (Engine.Searcher searcher = shard.engine().acquireSearcher("foo")) {
|
||||
assertEquals(numDocs, searcher.reader().numDocs());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue