Require soft-deletes when access changes snapshot (#36446)
Today we do not enforce soft-deletes when accessing the Lucene changes snapshot. This might lead to internal errors because we assume soft-deletes are enabled in that code path.
This commit is contained in:
parent
8b821706cc
commit
084e06e481
|
@ -722,7 +722,8 @@ public abstract class Engine implements Closeable {
|
||||||
public abstract Closeable acquireRetentionLockForPeerRecovery();
|
public abstract Closeable acquireRetentionLockForPeerRecovery();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new history snapshot from Lucene for reading operations whose seqno in the requesting seqno range (both inclusive)
|
* Creates a new history snapshot from Lucene for reading operations whose seqno in the requesting seqno range (both inclusive).
|
||||||
|
* This feature requires soft-deletes enabled. If soft-deletes are disabled, this method will throw an {@link IllegalStateException}.
|
||||||
*/
|
*/
|
||||||
public abstract Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService,
|
public abstract Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService,
|
||||||
long fromSeqNo, long toSeqNo, boolean requiredFullRange) throws IOException;
|
long fromSeqNo, long toSeqNo, boolean requiredFullRange) throws IOException;
|
||||||
|
|
|
@ -2481,7 +2481,9 @@ public class InternalEngine extends Engine {
|
||||||
@Override
|
@Override
|
||||||
public Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService,
|
public Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService,
|
||||||
long fromSeqNo, long toSeqNo, boolean requiredFullRange) throws IOException {
|
long fromSeqNo, long toSeqNo, boolean requiredFullRange) throws IOException {
|
||||||
// TODO: Should we defer the refresh until we really need it?
|
if (softDeleteEnabled == false) {
|
||||||
|
throw new IllegalStateException("accessing changes snapshot requires soft-deletes enabled");
|
||||||
|
}
|
||||||
ensureOpen();
|
ensureOpen();
|
||||||
refreshIfNeeded(source, toSeqNo);
|
refreshIfNeeded(source, toSeqNo);
|
||||||
Searcher searcher = acquireSearcher(source, SearcherScope.INTERNAL);
|
Searcher searcher = acquireSearcher(source, SearcherScope.INTERNAL);
|
||||||
|
|
|
@ -243,6 +243,9 @@ public class ReadOnlyEngine extends Engine {
|
||||||
@Override
|
@Override
|
||||||
public Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService, long fromSeqNo, long toSeqNo,
|
public Translog.Snapshot newChangesSnapshot(String source, MapperService mapperService, long fromSeqNo, long toSeqNo,
|
||||||
boolean requiredFullRange) throws IOException {
|
boolean requiredFullRange) throws IOException {
|
||||||
|
if (engineConfig.getIndexSettings().isSoftDeleteEnabled() == false) {
|
||||||
|
throw new IllegalStateException("accessing changes snapshot requires soft-deletes enabled");
|
||||||
|
}
|
||||||
return readHistoryOperations(source, mapperService, fromSeqNo);
|
return readHistoryOperations(source, mapperService, fromSeqNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3411,8 +3411,10 @@ public class InternalEngineTests extends EngineTestCase {
|
||||||
TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), 10);
|
TopDocs topDocs = searcher.searcher().search(new MatchAllDocsQuery(), 10);
|
||||||
assertEquals(1, topDocs.totalHits.value);
|
assertEquals(1, topDocs.totalHits.value);
|
||||||
}
|
}
|
||||||
List<Translog.Operation> ops = readAllOperationsInLucene(engine, createMapperService("test"));
|
if (engine.engineConfig.getIndexSettings().isSoftDeleteEnabled()) {
|
||||||
assertThat(ops.stream().map(o -> o.seqNo()).collect(Collectors.toList()), hasItem(20L));
|
List<Translog.Operation> ops = readAllOperationsInLucene(engine, createMapperService("test"));
|
||||||
|
assertThat(ops.stream().map(o -> o.seqNo()).collect(Collectors.toList()), hasItem(20L));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRetryWithAutogeneratedIdWorksAndNoDuplicateDocs() throws IOException {
|
public void testRetryWithAutogeneratedIdWorksAndNoDuplicateDocs() throws IOException {
|
||||||
|
@ -5292,8 +5294,11 @@ public class InternalEngineTests extends EngineTestCase {
|
||||||
final MapperService mapperService = createMapperService("test");
|
final MapperService mapperService = createMapperService("test");
|
||||||
final long maxSeqNo = randomLongBetween(10, 50);
|
final long maxSeqNo = randomLongBetween(10, 50);
|
||||||
final AtomicLong refreshCounter = new AtomicLong();
|
final AtomicLong refreshCounter = new AtomicLong();
|
||||||
|
final IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(
|
||||||
|
IndexMetaData.builder(defaultSettings.getIndexMetaData()).settings(Settings.builder().
|
||||||
|
put(defaultSettings.getSettings()).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), true)).build());
|
||||||
try (Store store = createStore();
|
try (Store store = createStore();
|
||||||
InternalEngine engine = createEngine(config(defaultSettings, store, createTempDir(), newMergePolicy(),
|
InternalEngine engine = createEngine(config(indexSettings, store, createTempDir(), newMergePolicy(),
|
||||||
null,
|
null,
|
||||||
new ReferenceManager.RefreshListener() {
|
new ReferenceManager.RefreshListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -5481,6 +5486,19 @@ public class InternalEngineTests extends EngineTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRequireSoftDeletesWhenAccessingChangesSnapshot() throws Exception {
|
||||||
|
try (Store store = createStore()) {
|
||||||
|
final IndexSettings indexSettings = IndexSettingsModule.newIndexSettings(
|
||||||
|
IndexMetaData.builder(defaultSettings.getIndexMetaData()).settings(Settings.builder().
|
||||||
|
put(defaultSettings.getSettings()).put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), false)).build());
|
||||||
|
try (InternalEngine engine = createEngine(config(indexSettings, store, createTempDir(), newMergePolicy(), null))) {
|
||||||
|
IllegalStateException error = expectThrows(IllegalStateException.class,
|
||||||
|
() -> engine.newChangesSnapshot("test", createMapperService("test"), 0, randomNonNegativeLong(), randomBoolean()));
|
||||||
|
assertThat(error.getMessage(), equalTo("accessing changes snapshot requires soft-deletes enabled"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void trimUnsafeCommits(EngineConfig config) throws IOException {
|
static void trimUnsafeCommits(EngineConfig config) throws IOException {
|
||||||
final Store store = config.getStore();
|
final Store store = config.getStore();
|
||||||
final TranslogConfig translogConfig = config.getTranslogConfig();
|
final TranslogConfig translogConfig = config.getTranslogConfig();
|
||||||
|
|
Loading…
Reference in New Issue