Pass TranslogRecoveryRunner to engine from outside (#33449)

This commit allows us to use different TranslogRecoveryRunner when
recovering an engine from its local translog. This change is a
prerequisite for the commit-based rollback PR.

Relates #32867
This commit is contained in:
Nhat Nguyen 2018-09-06 11:59:16 -04:00 committed by GitHub
parent 443f9caddd
commit 8afe09a749
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 67 additions and 78 deletions

View File

@ -1642,9 +1642,10 @@ public abstract class Engine implements Closeable {
* Performs recovery from the transaction log up to {@code recoverUpToSeqNo} (inclusive). * Performs recovery from the transaction log up to {@code recoverUpToSeqNo} (inclusive).
* This operation will close the engine if the recovery fails. * This operation will close the engine if the recovery fails.
* *
* @param recoverUpToSeqNo the upper bound, inclusive, of sequence number to be recovered * @param translogRecoveryRunner the translog recovery runner
* @param recoverUpToSeqNo the upper bound, inclusive, of sequence number to be recovered
*/ */
public abstract Engine recoverFromTranslog(long recoverUpToSeqNo) throws IOException; public abstract Engine recoverFromTranslog(TranslogRecoveryRunner translogRecoveryRunner, long recoverUpToSeqNo) throws IOException;
/** /**
* Do not replay translog operations, but make the engine be ready. * Do not replay translog operations, but make the engine be ready.
@ -1662,4 +1663,9 @@ public abstract class Engine implements Closeable {
* Tries to prune buffered deletes from the version map. * Tries to prune buffered deletes from the version map.
*/ */
public abstract void maybePruneDeletes(); public abstract void maybePruneDeletes();
@FunctionalInterface
public interface TranslogRecoveryRunner {
int run(Engine engine, Translog.Snapshot snapshot) throws IOException;
}
} }

View File

@ -37,13 +37,11 @@ import org.elasticsearch.index.codec.CodecService;
import org.elasticsearch.index.mapper.ParsedDocument; import org.elasticsearch.index.mapper.ParsedDocument;
import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.index.store.Store; import org.elasticsearch.index.store.Store;
import org.elasticsearch.index.translog.Translog;
import org.elasticsearch.index.translog.TranslogConfig; import org.elasticsearch.index.translog.TranslogConfig;
import org.elasticsearch.indices.IndexingMemoryController; import org.elasticsearch.indices.IndexingMemoryController;
import org.elasticsearch.indices.breaker.CircuitBreakerService; import org.elasticsearch.indices.breaker.CircuitBreakerService;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.function.LongSupplier; import java.util.function.LongSupplier;
@ -76,7 +74,6 @@ public final class EngineConfig {
private final List<ReferenceManager.RefreshListener> internalRefreshListener; private final List<ReferenceManager.RefreshListener> internalRefreshListener;
@Nullable @Nullable
private final Sort indexSort; private final Sort indexSort;
private final TranslogRecoveryRunner translogRecoveryRunner;
@Nullable @Nullable
private final CircuitBreakerService circuitBreakerService; private final CircuitBreakerService circuitBreakerService;
private final LongSupplier globalCheckpointSupplier; private final LongSupplier globalCheckpointSupplier;
@ -127,9 +124,8 @@ public final class EngineConfig {
TranslogConfig translogConfig, TimeValue flushMergesAfter, TranslogConfig translogConfig, TimeValue flushMergesAfter,
List<ReferenceManager.RefreshListener> externalRefreshListener, List<ReferenceManager.RefreshListener> externalRefreshListener,
List<ReferenceManager.RefreshListener> internalRefreshListener, Sort indexSort, List<ReferenceManager.RefreshListener> internalRefreshListener, Sort indexSort,
TranslogRecoveryRunner translogRecoveryRunner, CircuitBreakerService circuitBreakerService, CircuitBreakerService circuitBreakerService, LongSupplier globalCheckpointSupplier,
LongSupplier globalCheckpointSupplier, LongSupplier primaryTermSupplier, LongSupplier primaryTermSupplier, TombstoneDocSupplier tombstoneDocSupplier) {
TombstoneDocSupplier tombstoneDocSupplier) {
this.shardId = shardId; this.shardId = shardId;
this.allocationId = allocationId; this.allocationId = allocationId;
this.indexSettings = indexSettings; this.indexSettings = indexSettings;
@ -163,7 +159,6 @@ public final class EngineConfig {
this.externalRefreshListener = externalRefreshListener; this.externalRefreshListener = externalRefreshListener;
this.internalRefreshListener = internalRefreshListener; this.internalRefreshListener = internalRefreshListener;
this.indexSort = indexSort; this.indexSort = indexSort;
this.translogRecoveryRunner = translogRecoveryRunner;
this.circuitBreakerService = circuitBreakerService; this.circuitBreakerService = circuitBreakerService;
this.globalCheckpointSupplier = globalCheckpointSupplier; this.globalCheckpointSupplier = globalCheckpointSupplier;
this.primaryTermSupplier = primaryTermSupplier; this.primaryTermSupplier = primaryTermSupplier;
@ -324,18 +319,6 @@ public final class EngineConfig {
*/ */
public TimeValue getFlushMergesAfter() { return flushMergesAfter; } public TimeValue getFlushMergesAfter() { return flushMergesAfter; }
@FunctionalInterface
public interface TranslogRecoveryRunner {
int run(Engine engine, Translog.Snapshot snapshot) throws IOException;
}
/**
* Returns a runner that implements the translog recovery from the given snapshot
*/
public TranslogRecoveryRunner getTranslogRecoveryRunner() {
return translogRecoveryRunner;
}
/** /**
* The refresh listeners to add to Lucene for externally visible refreshes * The refresh listeners to add to Lucene for externally visible refreshes
*/ */

View File

@ -393,7 +393,7 @@ public class InternalEngine extends Engine {
} }
@Override @Override
public InternalEngine recoverFromTranslog(long recoverUpToSeqNo) throws IOException { public InternalEngine recoverFromTranslog(TranslogRecoveryRunner translogRecoveryRunner, long recoverUpToSeqNo) throws IOException {
flushLock.lock(); flushLock.lock();
try (ReleasableLock lock = readLock.acquire()) { try (ReleasableLock lock = readLock.acquire()) {
ensureOpen(); ensureOpen();
@ -401,7 +401,7 @@ public class InternalEngine extends Engine {
throw new IllegalStateException("Engine has already been recovered"); throw new IllegalStateException("Engine has already been recovered");
} }
try { try {
recoverFromTranslogInternal(recoverUpToSeqNo); recoverFromTranslogInternal(translogRecoveryRunner, recoverUpToSeqNo);
} catch (Exception e) { } catch (Exception e) {
try { try {
pendingTranslogRecovery.set(true); // just play safe and never allow commits on this see #ensureCanFlush pendingTranslogRecovery.set(true); // just play safe and never allow commits on this see #ensureCanFlush
@ -423,13 +423,13 @@ public class InternalEngine extends Engine {
pendingTranslogRecovery.set(false); // we are good - now we can commit pendingTranslogRecovery.set(false); // we are good - now we can commit
} }
private void recoverFromTranslogInternal(long recoverUpToSeqNo) throws IOException { private void recoverFromTranslogInternal(TranslogRecoveryRunner translogRecoveryRunner, long recoverUpToSeqNo) throws IOException {
Translog.TranslogGeneration translogGeneration = translog.getGeneration(); Translog.TranslogGeneration translogGeneration = translog.getGeneration();
final int opsRecovered; final int opsRecovered;
final long translogFileGen = Long.parseLong(lastCommittedSegmentInfos.getUserData().get(Translog.TRANSLOG_GENERATION_KEY)); final long translogFileGen = Long.parseLong(lastCommittedSegmentInfos.getUserData().get(Translog.TRANSLOG_GENERATION_KEY));
try (Translog.Snapshot snapshot = translog.newSnapshotFromGen( try (Translog.Snapshot snapshot = translog.newSnapshotFromGen(
new Translog.TranslogGeneration(translog.getTranslogUUID(), translogFileGen), recoverUpToSeqNo)) { new Translog.TranslogGeneration(translog.getTranslogUUID(), translogFileGen), recoverUpToSeqNo)) {
opsRecovered = config().getTranslogRecoveryRunner().run(this, snapshot); opsRecovered = translogRecoveryRunner.run(this, snapshot);
} catch (Exception e) { } catch (Exception e) {
throw new EngineException(shardId, "failed to recover from translog", e); throw new EngineException(shardId, "failed to recover from translog", e);
} }

View File

@ -1314,7 +1314,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
**/ **/
public void openEngineAndRecoverFromTranslog() throws IOException { public void openEngineAndRecoverFromTranslog() throws IOException {
innerOpenEngineAndTranslog(); innerOpenEngineAndTranslog();
getEngine().recoverFromTranslog(Long.MAX_VALUE); getEngine().recoverFromTranslog(this::runTranslogRecovery, Long.MAX_VALUE);
} }
/** /**
@ -2233,7 +2233,7 @@ public class IndexShard extends AbstractIndexShardComponent implements IndicesCl
IndexingMemoryController.SHARD_INACTIVE_TIME_SETTING.get(indexSettings.getSettings()), IndexingMemoryController.SHARD_INACTIVE_TIME_SETTING.get(indexSettings.getSettings()),
Collections.singletonList(refreshListeners), Collections.singletonList(refreshListeners),
Collections.singletonList(new RefreshMetricUpdater(refreshMetric)), Collections.singletonList(new RefreshMetricUpdater(refreshMetric)),
indexSort, this::runTranslogRecovery, circuitBreakerService, replicationTracker, () -> operationPrimaryTerm, tombstoneDocSupplier()); indexSort, circuitBreakerService, replicationTracker, () -> operationPrimaryTerm, tombstoneDocSupplier());
} }
/** /**

View File

@ -661,7 +661,7 @@ public class InternalEngineTests extends EngineTestCase {
trimUnsafeCommits(engine.config()); trimUnsafeCommits(engine.config());
engine = new InternalEngine(engine.config()); engine = new InternalEngine(engine.config());
assertTrue(engine.isRecovering()); assertTrue(engine.isRecovering());
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
Engine.Searcher searcher = wrapper.wrap(engine.acquireSearcher("test")); Engine.Searcher searcher = wrapper.wrap(engine.acquireSearcher("test"));
assertThat(counter.get(), equalTo(2)); assertThat(counter.get(), equalTo(2));
searcher.close(); searcher.close();
@ -678,7 +678,7 @@ public class InternalEngineTests extends EngineTestCase {
engine = new InternalEngine(engine.config()); engine = new InternalEngine(engine.config());
expectThrows(IllegalStateException.class, () -> engine.flush(true, true)); expectThrows(IllegalStateException.class, () -> engine.flush(true, true));
assertTrue(engine.isRecovering()); assertTrue(engine.isRecovering());
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertFalse(engine.isRecovering()); assertFalse(engine.isRecovering());
doc = testParsedDocument("2", null, testDocumentWithTextField(), SOURCE, null); doc = testParsedDocument("2", null, testDocumentWithTextField(), SOURCE, null);
engine.index(indexForDoc(doc)); engine.index(indexForDoc(doc));
@ -708,7 +708,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
trimUnsafeCommits(engine.config()); trimUnsafeCommits(engine.config());
try (Engine recoveringEngine = new InternalEngine(engine.config())){ try (Engine recoveringEngine = new InternalEngine(engine.config())){
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
try (Engine.Searcher searcher = recoveringEngine.acquireSearcher("test")) { try (Engine.Searcher searcher = recoveringEngine.acquireSearcher("test")) {
final TotalHitCountCollector collector = new TotalHitCountCollector(); final TotalHitCountCollector collector = new TotalHitCountCollector();
searcher.searcher().search(new MatchAllDocsQuery(), collector); searcher.searcher().search(new MatchAllDocsQuery(), collector);
@ -744,7 +744,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
}; };
assertThat(getTranslog(recoveringEngine).stats().getUncommittedOperations(), equalTo(docs)); assertThat(getTranslog(recoveringEngine).stats().getUncommittedOperations(), equalTo(docs));
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertTrue(committed.get()); assertTrue(committed.get());
} finally { } finally {
IOUtils.close(recoveringEngine); IOUtils.close(recoveringEngine);
@ -778,7 +778,7 @@ public class InternalEngineTests extends EngineTestCase {
initialEngine.close(); initialEngine.close();
trimUnsafeCommits(initialEngine.config()); trimUnsafeCommits(initialEngine.config());
recoveringEngine = new InternalEngine(initialEngine.config()); recoveringEngine = new InternalEngine(initialEngine.config());
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
try (Engine.Searcher searcher = recoveringEngine.acquireSearcher("test")) { try (Engine.Searcher searcher = recoveringEngine.acquireSearcher("test")) {
TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), docs); TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), docs);
assertEquals(docs, topDocs.totalHits.value); assertEquals(docs, topDocs.totalHits.value);
@ -811,14 +811,14 @@ public class InternalEngineTests extends EngineTestCase {
} }
trimUnsafeCommits(config); trimUnsafeCommits(config);
try (InternalEngine engine = new InternalEngine(config)) { try (InternalEngine engine = new InternalEngine(config)) {
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertThat(engine.getLocalCheckpoint(), equalTo(maxSeqNo)); assertThat(engine.getLocalCheckpoint(), equalTo(maxSeqNo));
assertThat(engine.getLocalCheckpointTracker().getMaxSeqNo(), equalTo(maxSeqNo)); assertThat(engine.getLocalCheckpointTracker().getMaxSeqNo(), equalTo(maxSeqNo));
} }
trimUnsafeCommits(config); trimUnsafeCommits(config);
try (InternalEngine engine = new InternalEngine(config)) { try (InternalEngine engine = new InternalEngine(config)) {
long upToSeqNo = randomLongBetween(globalCheckpoint.get(), maxSeqNo); long upToSeqNo = randomLongBetween(globalCheckpoint.get(), maxSeqNo);
engine.recoverFromTranslog(upToSeqNo); engine.recoverFromTranslog(translogHandler, upToSeqNo);
assertThat(engine.getLocalCheckpoint(), equalTo(upToSeqNo)); assertThat(engine.getLocalCheckpoint(), equalTo(upToSeqNo));
assertThat(engine.getLocalCheckpointTracker().getMaxSeqNo(), equalTo(upToSeqNo)); assertThat(engine.getLocalCheckpointTracker().getMaxSeqNo(), equalTo(upToSeqNo));
} }
@ -1202,7 +1202,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
trimUnsafeCommits(config); trimUnsafeCommits(config);
engine = new InternalEngine(config); engine = new InternalEngine(config);
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(engine.getLastCommittedSegmentInfos().getUserData().get(Engine.SYNC_COMMIT_ID), syncId); assertEquals(engine.getLastCommittedSegmentInfos().getUserData().get(Engine.SYNC_COMMIT_ID), syncId);
} }
@ -1221,7 +1221,7 @@ public class InternalEngineTests extends EngineTestCase {
engine.close(); engine.close();
trimUnsafeCommits(config); trimUnsafeCommits(config);
engine = new InternalEngine(config); engine = new InternalEngine(config);
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertNull("Sync ID must be gone since we have a document to replay", engine.getLastCommittedSegmentInfos().getUserData().get(Engine.SYNC_COMMIT_ID)); assertNull("Sync ID must be gone since we have a document to replay", engine.getLastCommittedSegmentInfos().getUserData().get(Engine.SYNC_COMMIT_ID));
} }
@ -2187,7 +2187,7 @@ public class InternalEngineTests extends EngineTestCase {
trimUnsafeCommits(initialEngine.engineConfig); trimUnsafeCommits(initialEngine.engineConfig);
try (InternalEngine recoveringEngine = new InternalEngine(initialEngine.config())){ try (InternalEngine recoveringEngine = new InternalEngine(initialEngine.config())){
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(primarySeqNo, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo()); assertEquals(primarySeqNo, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo());
assertThat( assertThat(
@ -2508,7 +2508,7 @@ public class InternalEngineTests extends EngineTestCase {
try (InternalEngine engine = createEngine(config)) { try (InternalEngine engine = createEngine(config)) {
engine.index(firstIndexRequest); engine.index(firstIndexRequest);
globalCheckpoint.set(engine.getLocalCheckpoint()); globalCheckpoint.set(engine.getLocalCheckpoint());
expectThrows(IllegalStateException.class, () -> engine.recoverFromTranslog(Long.MAX_VALUE)); expectThrows(IllegalStateException.class, () -> engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE));
Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData(); Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData();
assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY));
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
@ -2530,7 +2530,7 @@ public class InternalEngineTests extends EngineTestCase {
assertEquals("3", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("3", userData.get(Translog.TRANSLOG_GENERATION_KEY));
} }
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
userData = engine.getLastCommittedSegmentInfos().getUserData(); userData = engine.getLastCommittedSegmentInfos().getUserData();
assertEquals("3", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("3", userData.get(Translog.TRANSLOG_GENERATION_KEY));
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
@ -2547,7 +2547,7 @@ public class InternalEngineTests extends EngineTestCase {
Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData(); Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData();
assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY));
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(2, engine.getTranslog().currentFileGeneration()); assertEquals(2, engine.getTranslog().currentFileGeneration());
assertEquals(0L, engine.getTranslog().stats().getUncommittedOperations()); assertEquals(0L, engine.getTranslog().stats().getUncommittedOperations());
} }
@ -2561,7 +2561,7 @@ public class InternalEngineTests extends EngineTestCase {
Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData(); Map<String, String> userData = engine.getLastCommittedSegmentInfos().getUserData();
assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("1", userData.get(Translog.TRANSLOG_GENERATION_KEY));
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
userData = engine.getLastCommittedSegmentInfos().getUserData(); userData = engine.getLastCommittedSegmentInfos().getUserData();
assertEquals("no changes - nothing to commit", "1", userData.get(Translog.TRANSLOG_GENERATION_KEY)); assertEquals("no changes - nothing to commit", "1", userData.get(Translog.TRANSLOG_GENERATION_KEY));
assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY)); assertEquals(engine.getTranslog().getTranslogUUID(), userData.get(Translog.TRANSLOG_UUID_KEY));
@ -2667,7 +2667,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
} }
}) { }) {
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
final ParsedDocument doc1 = testParsedDocument("1", null, testDocumentWithTextField(), SOURCE, null); final ParsedDocument doc1 = testParsedDocument("1", null, testDocumentWithTextField(), SOURCE, null);
engine.index(indexForDoc(doc1)); engine.index(indexForDoc(doc1));
globalCheckpoint.set(engine.getLocalCheckpoint()); globalCheckpoint.set(engine.getLocalCheckpoint());
@ -2678,7 +2678,7 @@ public class InternalEngineTests extends EngineTestCase {
try (InternalEngine engine = try (InternalEngine engine =
new InternalEngine(config(indexSettings, store, translogPath, newMergePolicy(), null, null, new InternalEngine(config(indexSettings, store, translogPath, newMergePolicy(), null, null,
globalCheckpointSupplier))) { globalCheckpointSupplier))) {
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertVisibleCount(engine, 1); assertVisibleCount(engine, 1);
final long committedGen = Long.valueOf( final long committedGen = Long.valueOf(
engine.getLastCommittedSegmentInfos().getUserData().get(Translog.TRANSLOG_GENERATION_KEY)); engine.getLastCommittedSegmentInfos().getUserData().get(Translog.TRANSLOG_GENERATION_KEY));
@ -2739,30 +2739,28 @@ public class InternalEngineTests extends EngineTestCase {
assertThat(indexResult.getVersion(), equalTo(1L)); assertThat(indexResult.getVersion(), equalTo(1L));
} }
assertVisibleCount(engine, numDocs); assertVisibleCount(engine, numDocs);
translogHandler = createTranslogHandler(engine.engineConfig.getIndexSettings());
TranslogHandler parser = (TranslogHandler) engine.config().getTranslogRecoveryRunner(); translogHandler.mappingUpdate = dynamicUpdate();
parser.mappingUpdate = dynamicUpdate();
engine.close(); engine.close();
trimUnsafeCommits(copy(engine.config(), inSyncGlobalCheckpointSupplier)); trimUnsafeCommits(copy(engine.config(), inSyncGlobalCheckpointSupplier));
engine = new InternalEngine(copy(engine.config(), inSyncGlobalCheckpointSupplier)); // we need to reuse the engine config unless the parser.mappingModified won't work engine = new InternalEngine(copy(engine.config(), inSyncGlobalCheckpointSupplier)); // we need to reuse the engine config unless the parser.mappingModified won't work
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertVisibleCount(engine, numDocs, false); assertVisibleCount(engine, numDocs, false);
parser = (TranslogHandler) engine.config().getTranslogRecoveryRunner(); assertEquals(numDocs, translogHandler.appliedOperations());
assertEquals(numDocs, parser.appliedOperations()); if (translogHandler.mappingUpdate != null) {
if (parser.mappingUpdate != null) { assertEquals(1, translogHandler.getRecoveredTypes().size());
assertEquals(1, parser.getRecoveredTypes().size()); assertTrue(translogHandler.getRecoveredTypes().containsKey("test"));
assertTrue(parser.getRecoveredTypes().containsKey("test"));
} else { } else {
assertEquals(0, parser.getRecoveredTypes().size()); assertEquals(0, translogHandler.getRecoveredTypes().size());
} }
engine.close(); engine.close();
translogHandler = createTranslogHandler(engine.engineConfig.getIndexSettings());
engine = createEngine(store, primaryTranslogDir, inSyncGlobalCheckpointSupplier); engine = createEngine(store, primaryTranslogDir, inSyncGlobalCheckpointSupplier);
assertVisibleCount(engine, numDocs, false); assertVisibleCount(engine, numDocs, false);
parser = (TranslogHandler) engine.config().getTranslogRecoveryRunner(); assertEquals(0, translogHandler.appliedOperations());
assertEquals(0, parser.appliedOperations());
final boolean flush = randomBoolean(); final boolean flush = randomBoolean();
int randomId = randomIntBetween(numDocs + 1, numDocs + 10); int randomId = randomIntBetween(numDocs + 1, numDocs + 10);
@ -2786,13 +2784,13 @@ public class InternalEngineTests extends EngineTestCase {
} }
engine.close(); engine.close();
translogHandler = createTranslogHandler(engine.engineConfig.getIndexSettings());
engine = createEngine(store, primaryTranslogDir, inSyncGlobalCheckpointSupplier); engine = createEngine(store, primaryTranslogDir, inSyncGlobalCheckpointSupplier);
try (Engine.Searcher searcher = engine.acquireSearcher("test")) { try (Engine.Searcher searcher = engine.acquireSearcher("test")) {
TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), numDocs + 1); TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), numDocs + 1);
assertThat(topDocs.totalHits.value, equalTo(numDocs + 1L)); assertThat(topDocs.totalHits.value, equalTo(numDocs + 1L));
} }
parser = (TranslogHandler) engine.config().getTranslogRecoveryRunner(); assertEquals(flush ? 1 : 2, translogHandler.appliedOperations());
assertEquals(flush ? 1 : 2, parser.appliedOperations());
engine.delete(new Engine.Delete("test", Integer.toString(randomId), newUid(doc), primaryTerm.get())); engine.delete(new Engine.Delete("test", Integer.toString(randomId), newUid(doc), primaryTerm.get()));
if (randomBoolean()) { if (randomBoolean()) {
engine.refresh("test"); engine.refresh("test");
@ -2836,7 +2834,7 @@ public class InternalEngineTests extends EngineTestCase {
threadPool, config.getIndexSettings(), null, store, newMergePolicy(), config.getAnalyzer(), config.getSimilarity(), threadPool, config.getIndexSettings(), null, store, newMergePolicy(), config.getAnalyzer(), config.getSimilarity(),
new CodecService(null, logger), config.getEventListener(), IndexSearcher.getDefaultQueryCache(), new CodecService(null, logger), config.getEventListener(), IndexSearcher.getDefaultQueryCache(),
IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig, TimeValue.timeValueMinutes(5), IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig, TimeValue.timeValueMinutes(5),
config.getExternalRefreshListener(), config.getInternalRefreshListener(), null, config.getTranslogRecoveryRunner(), config.getExternalRefreshListener(), config.getInternalRefreshListener(), null,
new NoneCircuitBreakerService(), () -> SequenceNumbers.UNASSIGNED_SEQ_NO, primaryTerm::get, tombstoneDocSupplier()); new NoneCircuitBreakerService(), () -> SequenceNumbers.UNASSIGNED_SEQ_NO, primaryTerm::get, tombstoneDocSupplier());
try { try {
InternalEngine internalEngine = new InternalEngine(brokenConfig); InternalEngine internalEngine = new InternalEngine(brokenConfig);
@ -3455,7 +3453,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
try (Store store = createStore(newFSDirectory(storeDir)); Engine engine = new InternalEngine(configSupplier.apply(store))) { try (Store store = createStore(newFSDirectory(storeDir)); Engine engine = new InternalEngine(configSupplier.apply(store))) {
assertEquals(IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, engine.segmentsStats(false).getMaxUnsafeAutoIdTimestamp()); assertEquals(IndexRequest.UNSET_AUTO_GENERATED_TIMESTAMP, engine.segmentsStats(false).getMaxUnsafeAutoIdTimestamp());
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(timestamp1, engine.segmentsStats(false).getMaxUnsafeAutoIdTimestamp()); assertEquals(timestamp1, engine.segmentsStats(false).getMaxUnsafeAutoIdTimestamp());
final ParsedDocument doc = testParsedDocument("1", null, testDocumentWithTextField(), final ParsedDocument doc = testParsedDocument("1", null, testDocumentWithTextField(),
new BytesArray("{}".getBytes(Charset.defaultCharset())), null); new BytesArray("{}".getBytes(Charset.defaultCharset())), null);
@ -3738,7 +3736,7 @@ public class InternalEngineTests extends EngineTestCase {
} }
trimUnsafeCommits(initialEngine.config()); trimUnsafeCommits(initialEngine.config());
try (Engine recoveringEngine = new InternalEngine(initialEngine.config())) { try (Engine recoveringEngine = new InternalEngine(initialEngine.config())) {
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
recoveringEngine.fillSeqNoGaps(2); recoveringEngine.fillSeqNoGaps(2);
assertThat(recoveringEngine.getLocalCheckpoint(), greaterThanOrEqualTo((long) (docs - 1))); assertThat(recoveringEngine.getLocalCheckpoint(), greaterThanOrEqualTo((long) (docs - 1)));
} }
@ -3849,7 +3847,7 @@ public class InternalEngineTests extends EngineTestCase {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
}; };
noOpEngine.recoverFromTranslog(Long.MAX_VALUE); noOpEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
final int gapsFilled = noOpEngine.fillSeqNoGaps(primaryTerm.get()); final int gapsFilled = noOpEngine.fillSeqNoGaps(primaryTerm.get());
final String reason = "filling gaps"; final String reason = "filling gaps";
noOpEngine.noOp(new Engine.NoOp(maxSeqNo + 1, primaryTerm.get(), LOCAL_TRANSLOG_RECOVERY, System.nanoTime(), reason)); noOpEngine.noOp(new Engine.NoOp(maxSeqNo + 1, primaryTerm.get(), LOCAL_TRANSLOG_RECOVERY, System.nanoTime(), reason));
@ -4127,7 +4125,7 @@ public class InternalEngineTests extends EngineTestCase {
trimUnsafeCommits(copy(replicaEngine.config(), globalCheckpoint::get)); trimUnsafeCommits(copy(replicaEngine.config(), globalCheckpoint::get));
recoveringEngine = new InternalEngine(copy(replicaEngine.config(), globalCheckpoint::get)); recoveringEngine = new InternalEngine(copy(replicaEngine.config(), globalCheckpoint::get));
assertEquals(numDocsOnReplica, getTranslog(recoveringEngine).stats().getUncommittedOperations()); assertEquals(numDocsOnReplica, getTranslog(recoveringEngine).stats().getUncommittedOperations());
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(maxSeqIDOnReplica, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo()); assertEquals(maxSeqIDOnReplica, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo());
assertEquals(checkpointOnReplica, recoveringEngine.getLocalCheckpoint()); assertEquals(checkpointOnReplica, recoveringEngine.getLocalCheckpoint());
assertEquals((maxSeqIDOnReplica + 1) - numDocsOnReplica, recoveringEngine.fillSeqNoGaps(2)); assertEquals((maxSeqIDOnReplica + 1) - numDocsOnReplica, recoveringEngine.fillSeqNoGaps(2));
@ -4163,7 +4161,7 @@ public class InternalEngineTests extends EngineTestCase {
if (flushed) { if (flushed) {
assertThat(recoveringEngine.getTranslogStats().getUncommittedOperations(), equalTo(0)); assertThat(recoveringEngine.getTranslogStats().getUncommittedOperations(), equalTo(0));
} }
recoveringEngine.recoverFromTranslog(Long.MAX_VALUE); recoveringEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
assertEquals(maxSeqIDOnReplica, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo()); assertEquals(maxSeqIDOnReplica, recoveringEngine.getSeqNoStats(-1).getMaxSeqNo());
assertEquals(maxSeqIDOnReplica, recoveringEngine.getLocalCheckpoint()); assertEquals(maxSeqIDOnReplica, recoveringEngine.getLocalCheckpoint());
assertEquals(0, recoveringEngine.fillSeqNoGaps(3)); assertEquals(0, recoveringEngine.fillSeqNoGaps(3));
@ -4356,7 +4354,7 @@ public class InternalEngineTests extends EngineTestCase {
super.commitIndexWriter(writer, translog, syncId); super.commitIndexWriter(writer, translog, syncId);
} }
}) { }) {
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
int numDocs = scaledRandomIntBetween(10, 100); int numDocs = scaledRandomIntBetween(10, 100);
for (int docId = 0; docId < numDocs; docId++) { for (int docId = 0; docId < numDocs; docId++) {
ParseContext.Document document = testDocumentWithTextField(); ParseContext.Document document = testDocumentWithTextField();

View File

@ -131,10 +131,10 @@ public class RefreshListenersTests extends ESTestCase {
indexSettings, null, store, newMergePolicy(), iwc.getAnalyzer(), iwc.getSimilarity(), new CodecService(null, logger), indexSettings, null, store, newMergePolicy(), iwc.getAnalyzer(), iwc.getSimilarity(), new CodecService(null, logger),
eventListener, IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig, eventListener, IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig,
TimeValue.timeValueMinutes(5), Collections.singletonList(listeners), Collections.emptyList(), null, TimeValue.timeValueMinutes(5), Collections.singletonList(listeners), Collections.emptyList(), null,
(e, s) -> 0, new NoneCircuitBreakerService(), () -> SequenceNumbers.NO_OPS_PERFORMED, () -> primaryTerm, new NoneCircuitBreakerService(), () -> SequenceNumbers.NO_OPS_PERFORMED, () -> primaryTerm,
EngineTestCase.tombstoneDocSupplier()); EngineTestCase.tombstoneDocSupplier());
engine = new InternalEngine(config); engine = new InternalEngine(config);
engine.recoverFromTranslog(Long.MAX_VALUE); engine.recoverFromTranslog((e, s) -> 0, Long.MAX_VALUE);
listeners.setCurrentRefreshLocationSupplier(engine::getTranslogLastWriteLocation); listeners.setCurrentRefreshLocationSupplier(engine::getTranslogLastWriteLocation);
} }

View File

@ -125,6 +125,7 @@ public abstract class EngineTestCase extends ESTestCase {
protected static final IndexSettings INDEX_SETTINGS = IndexSettingsModule.newIndexSettings("index", Settings.EMPTY); protected static final IndexSettings INDEX_SETTINGS = IndexSettingsModule.newIndexSettings("index", Settings.EMPTY);
protected ThreadPool threadPool; protected ThreadPool threadPool;
protected TranslogHandler translogHandler;
protected Store store; protected Store store;
protected Store storeReplica; protected Store storeReplica;
@ -189,6 +190,7 @@ public abstract class EngineTestCase extends ESTestCase {
Lucene.cleanLuceneIndex(store.directory()); Lucene.cleanLuceneIndex(store.directory());
Lucene.cleanLuceneIndex(storeReplica.directory()); Lucene.cleanLuceneIndex(storeReplica.directory());
primaryTranslogDir = createTempDir("translog-primary"); primaryTranslogDir = createTempDir("translog-primary");
translogHandler = createTranslogHandler(defaultSettings);
engine = createEngine(store, primaryTranslogDir); engine = createEngine(store, primaryTranslogDir);
LiveIndexWriterConfig currentIndexWriterConfig = engine.getCurrentIndexWriterConfig(); LiveIndexWriterConfig currentIndexWriterConfig = engine.getCurrentIndexWriterConfig();
@ -213,7 +215,7 @@ public abstract class EngineTestCase extends ESTestCase {
config.getWarmer(), config.getStore(), config.getMergePolicy(), config.getAnalyzer(), config.getSimilarity(), config.getWarmer(), config.getStore(), config.getMergePolicy(), config.getAnalyzer(), config.getSimilarity(),
new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(), new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(),
config.getTranslogConfig(), config.getFlushMergesAfter(), config.getTranslogConfig(), config.getFlushMergesAfter(),
config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(), config.getTranslogRecoveryRunner(), config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(),
config.getCircuitBreakerService(), globalCheckpointSupplier, config.getPrimaryTermSupplier(), tombstoneDocSupplier()); config.getCircuitBreakerService(), globalCheckpointSupplier, config.getPrimaryTermSupplier(), tombstoneDocSupplier());
} }
@ -222,7 +224,7 @@ public abstract class EngineTestCase extends ESTestCase {
config.getWarmer(), config.getStore(), config.getMergePolicy(), analyzer, config.getSimilarity(), config.getWarmer(), config.getStore(), config.getMergePolicy(), analyzer, config.getSimilarity(),
new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(), new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(),
config.getTranslogConfig(), config.getFlushMergesAfter(), config.getTranslogConfig(), config.getFlushMergesAfter(),
config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(), config.getTranslogRecoveryRunner(), config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(),
config.getCircuitBreakerService(), config.getGlobalCheckpointSupplier(), config.getPrimaryTermSupplier(), config.getCircuitBreakerService(), config.getGlobalCheckpointSupplier(), config.getPrimaryTermSupplier(),
config.getTombstoneDocSupplier()); config.getTombstoneDocSupplier());
} }
@ -232,7 +234,7 @@ public abstract class EngineTestCase extends ESTestCase {
config.getWarmer(), config.getStore(), mergePolicy, config.getAnalyzer(), config.getSimilarity(), config.getWarmer(), config.getStore(), mergePolicy, config.getAnalyzer(), config.getSimilarity(),
new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(), new CodecService(null, logger), config.getEventListener(), config.getQueryCache(), config.getQueryCachingPolicy(),
config.getTranslogConfig(), config.getFlushMergesAfter(), config.getTranslogConfig(), config.getFlushMergesAfter(),
config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(), config.getTranslogRecoveryRunner(), config.getExternalRefreshListener(), Collections.emptyList(), config.getIndexSort(),
config.getCircuitBreakerService(), config.getGlobalCheckpointSupplier(), config.getPrimaryTermSupplier(), config.getCircuitBreakerService(), config.getGlobalCheckpointSupplier(), config.getPrimaryTermSupplier(),
config.getTombstoneDocSupplier()); config.getTombstoneDocSupplier());
} }
@ -377,6 +379,10 @@ public abstract class EngineTestCase extends ESTestCase {
() -> SequenceNumbers.NO_OPS_PERFORMED, primaryTermSupplier); () -> SequenceNumbers.NO_OPS_PERFORMED, primaryTermSupplier);
} }
protected TranslogHandler createTranslogHandler(IndexSettings indexSettings) {
return new TranslogHandler(xContentRegistry(), indexSettings);
}
protected InternalEngine createEngine(Store store, Path translogPath) throws IOException { protected InternalEngine createEngine(Store store, Path translogPath) throws IOException {
return createEngine(defaultSettings, store, translogPath, newMergePolicy(), null); return createEngine(defaultSettings, store, translogPath, newMergePolicy(), null);
} }
@ -478,7 +484,7 @@ public abstract class EngineTestCase extends ESTestCase {
} }
InternalEngine internalEngine = createInternalEngine(indexWriterFactory, localCheckpointTrackerSupplier, seqNoForOperation, config); InternalEngine internalEngine = createInternalEngine(indexWriterFactory, localCheckpointTrackerSupplier, seqNoForOperation, config);
internalEngine.recoverFromTranslog(Long.MAX_VALUE); internalEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
return internalEngine; return internalEngine;
} }
@ -553,14 +559,12 @@ public abstract class EngineTestCase extends ESTestCase {
// we don't need to notify anybody in this test // we don't need to notify anybody in this test
} }
}; };
final TranslogHandler handler = new TranslogHandler(xContentRegistry(), IndexSettingsModule.newIndexSettings(shardId.getIndexName(),
indexSettings.getSettings()));
final List<ReferenceManager.RefreshListener> refreshListenerList = final List<ReferenceManager.RefreshListener> refreshListenerList =
refreshListener == null ? emptyList() : Collections.singletonList(refreshListener); refreshListener == null ? emptyList() : Collections.singletonList(refreshListener);
EngineConfig config = new EngineConfig(shardId, allocationId.getId(), threadPool, indexSettings, null, store, EngineConfig config = new EngineConfig(shardId, allocationId.getId(), threadPool, indexSettings, null, store,
mergePolicy, iwc.getAnalyzer(), iwc.getSimilarity(), new CodecService(null, logger), listener, mergePolicy, iwc.getAnalyzer(), iwc.getSimilarity(), new CodecService(null, logger), listener,
IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig, IndexSearcher.getDefaultQueryCache(), IndexSearcher.getDefaultQueryCachingPolicy(), translogConfig,
TimeValue.timeValueMinutes(5), refreshListenerList, Collections.emptyList(), indexSort, handler, TimeValue.timeValueMinutes(5), refreshListenerList, Collections.emptyList(), indexSort,
new NoneCircuitBreakerService(), new NoneCircuitBreakerService(),
globalCheckpointSupplier == null ? globalCheckpointSupplier == null ?
new ReplicationTracker(shardId, allocationId.getId(), indexSettings, SequenceNumbers.NO_OPS_PERFORMED, update -> {}) : new ReplicationTracker(shardId, allocationId.getId(), indexSettings, SequenceNumbers.NO_OPS_PERFORMED, update -> {}) :

View File

@ -46,7 +46,7 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap; import static java.util.Collections.emptyMap;
import static org.elasticsearch.index.mapper.SourceToParse.source; import static org.elasticsearch.index.mapper.SourceToParse.source;
public class TranslogHandler implements EngineConfig.TranslogRecoveryRunner { public class TranslogHandler implements Engine.TranslogRecoveryRunner {
private final MapperService mapperService; private final MapperService mapperService;
public Mapping mappingUpdate = null; public Mapping mappingUpdate = null;

View File

@ -44,7 +44,6 @@ import org.elasticsearch.index.translog.TranslogConfig;
import org.elasticsearch.indices.breaker.NoneCircuitBreakerService; import org.elasticsearch.indices.breaker.NoneCircuitBreakerService;
import org.elasticsearch.test.DummyShardLock; import org.elasticsearch.test.DummyShardLock;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.IndexSettingsModule;
import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
@ -254,8 +253,6 @@ public class FollowingEngineTests extends ESTestCase {
Collections.emptyList(), Collections.emptyList(),
Collections.emptyList(), Collections.emptyList(),
null, null,
new TranslogHandler(
xContentRegistry, IndexSettingsModule.newIndexSettings(shardId.getIndexName(), indexSettings.getSettings())),
new NoneCircuitBreakerService(), new NoneCircuitBreakerService(),
() -> SequenceNumbers.NO_OPS_PERFORMED, () -> SequenceNumbers.NO_OPS_PERFORMED,
() -> primaryTerm.get(), () -> primaryTerm.get(),
@ -280,7 +277,8 @@ public class FollowingEngineTests extends ESTestCase {
SequenceNumbers.NO_OPS_PERFORMED, shardId, 1L); SequenceNumbers.NO_OPS_PERFORMED, shardId, 1L);
store.associateIndexWithNewTranslog(translogUuid); store.associateIndexWithNewTranslog(translogUuid);
FollowingEngine followingEngine = new FollowingEngine(config); FollowingEngine followingEngine = new FollowingEngine(config);
followingEngine.recoverFromTranslog(Long.MAX_VALUE); TranslogHandler translogHandler = new TranslogHandler(xContentRegistry(), config.getIndexSettings());
followingEngine.recoverFromTranslog(translogHandler, Long.MAX_VALUE);
return followingEngine; return followingEngine;
} }