Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ setup:
---
keyword:
- requires:
cluster_features: ["gte_v8.4.0"]
reason: introduced in 8.4.0
cluster_features: [ "mapper.synthetic_recovery_source" ]
reason: requires synthetic recovery source

- do:
indices.create:
Expand Down Expand Up @@ -60,13 +60,14 @@ keyword:
index: test
run_expensive_tasks: true
- is_false: test.fields._source
- is_true: test.fields._recovery_source
# When synthetic source is used there is no _recovery_source field
- match: { test.fields._recovery_source: null }

---
stored text:
- requires:
cluster_features: ["gte_v8.5.0"]
reason: introduced in 8.5.0
cluster_features: [ "mapper.synthetic_recovery_source" ]
reason: requires synthetic recovery source

- do:
indices.create:
Expand Down Expand Up @@ -121,4 +122,5 @@ stored text:
index: test
run_expensive_tasks: true
- is_false: test.fields._source
- is_true: test.fields._recovery_source
# When synthetic source is used there is no _recovery_source field
- match: { test.fields._recovery_source: null }
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,15 @@ public static Setting<Boolean> boolSetting(String key, boolean defaultValue, Val
return new Setting<>(key, Boolean.toString(defaultValue), b -> parseBoolean(b, key, isFiltered(properties)), validator, properties);
}

public static Setting<Boolean> boolSetting(
String key,
Function<Settings, String> defaultValueFn,
Validator<Boolean> validator,
Property... properties
) {
return new Setting<>(key, defaultValueFn, b -> parseBoolean(b, key, isFiltered(properties)), validator, properties);
}

public static Setting<Boolean> boolSetting(String key, Function<Settings, String> defaultValueFn, Property... properties) {
return new Setting<>(key, defaultValueFn, b -> parseBoolean(b, key, isFiltered(properties)), properties);
}
Expand Down
17 changes: 15 additions & 2 deletions server/src/main/java/org/elasticsearch/index/IndexSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.elasticsearch.common.time.DateUtils;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.util.FeatureFlag;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.features.NodeFeature;
import org.elasticsearch.index.mapper.IgnoredSourceFieldMapper;
Expand All @@ -40,6 +41,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Function;
Expand Down Expand Up @@ -725,9 +727,19 @@ public Iterator<Setting<?>> settings() {
Setting.Property.IndexScope
);

public static final FeatureFlag RECOVERY_USE_SYNTHETIC_SOURCE = new FeatureFlag("index_recovery_use_synthetic_source");
public static final Setting<Boolean> RECOVERY_USE_SYNTHETIC_SOURCE_SETTING = Setting.boolSetting(
"index.recovery.use_synthetic_source",
false,
settings -> {
boolean isSyntheticSourceRecoveryFeatureFlagEnabled = RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled();
boolean isNewIndexVersion = SETTING_INDEX_VERSION_CREATED.get(settings)
.onOrAfter(IndexVersions.USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT_BACKPORT);
boolean useSyntheticRecoverySource = isSyntheticSourceRecoveryFeatureFlagEnabled && isNewIndexVersion;
return String.valueOf(
useSyntheticRecoverySource
&& Objects.equals(INDEX_MAPPER_SOURCE_MODE_SETTING.get(settings), SourceFieldMapper.Mode.SYNTHETIC)
);
},
new Setting.Validator<>() {
@Override
public void validate(Boolean value) {}
Expand Down Expand Up @@ -1088,7 +1100,8 @@ public IndexSettings(final IndexMetadata indexMetadata, final Settings nodeSetti
skipIgnoredSourceRead = scopedSettings.get(IgnoredSourceFieldMapper.SKIP_IGNORED_SOURCE_READ_SETTING);
indexMappingSourceMode = scopedSettings.get(INDEX_MAPPER_SOURCE_MODE_SETTING);
recoverySourceEnabled = RecoverySettings.INDICES_RECOVERY_SOURCE_ENABLED_SETTING.get(nodeSettings);
recoverySourceSyntheticEnabled = scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
recoverySourceSyntheticEnabled = DiscoveryNode.isStateless(nodeSettings) == false
&& scopedSettings.get(RECOVERY_USE_SYNTHETIC_SOURCE_SETTING);
if (recoverySourceSyntheticEnabled) {
if (DiscoveryNode.isStateless(settings)) {
throw new IllegalArgumentException("synthetic recovery source is only allowed in stateful");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ private static IndexVersion def(int id, Version luceneVersion) {
public static final IndexVersion UPGRADE_TO_LUCENE_9_12_1 = def(8_523_0_00, Version.LUCENE_9_12_1);
public static final IndexVersion INFERENCE_METADATA_FIELDS_BACKPORT = def(8_524_0_00, Version.LUCENE_9_12_1);
public static final IndexVersion LOGSB_OPTIONAL_SORTING_ON_HOST_NAME_BACKPORT = def(8_525_0_00, Version.LUCENE_9_12_1);
public static final IndexVersion USE_SYNTHETIC_SOURCE_FOR_RECOVERY_BY_DEFAULT_BACKPORT = def(8_526_0_00, Version.LUCENE_9_12_1);
/*
* STOP! READ THIS FIRST! No, really,
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2455,8 +2455,14 @@ protected void validateRoundTripReader(String syntheticSource, DirectoryReader r
// and since the copy is exact, contents of ignored source are different.
assertReaderEquals(
"round trip " + syntheticSource,
new FieldMaskingReader(Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME), reader),
new FieldMaskingReader(Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME), roundTripReader)
new FieldMaskingReader(
Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME),
reader
),
new FieldMaskingReader(
Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, IgnoredSourceFieldMapper.NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME),
roundTripReader
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,8 +475,13 @@ public void testRecoverySourceWithSyntheticSource() throws IOException {
MapperService mapperService = createMapperService(settings, topMapping(b -> {}));
DocumentMapper docMapper = mapperService.documentMapper();
ParsedDocument doc = docMapper.parse(source(b -> b.field("field1", "value1")));
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(doc.rootDoc().getField("_recovery_source").binaryValue(), equalTo(new BytesRef("{\"field1\":\"value1\"}")));
if (IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled() == false) {
// TODO: remove this if branch when removing the 'index_recovery_use_synthetic_source' feature flag
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(doc.rootDoc().getField("_recovery_source").binaryValue(), equalTo(new BytesRef("{\"field1\":\"value1\"}")));
} else {
assertNull(doc.rootDoc().getField("_recovery_source"));
}
}
{
Settings settings = Settings.builder()
Expand Down Expand Up @@ -507,8 +512,16 @@ public void testRecoverySourceWithLogs() throws IOException {
MapperService mapperService = createMapperService(settings, mapping(b -> {}));
DocumentMapper docMapper = mapperService.documentMapper();
ParsedDocument doc = docMapper.parse(source(b -> { b.field("@timestamp", "2012-02-13"); }));
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(doc.rootDoc().getField("_recovery_source").binaryValue(), equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\"}")));
if (IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled() == false) {
// TODO: remove this if branch when removing the 'index_recovery_use_synthetic_source' feature flag
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\"}"))
);
} else {
assertNull(doc.rootDoc().getField("_recovery_source"));
}
}
{
Settings settings = Settings.builder()
Expand Down Expand Up @@ -701,8 +714,16 @@ public void testRecoverySourceWithLogsCustom() throws IOException {
MapperService mapperService = createMapperService(settings, mappings);
DocumentMapper docMapper = mapperService.documentMapper();
ParsedDocument doc = docMapper.parse(source(b -> { b.field("@timestamp", "2012-02-13"); }));
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(doc.rootDoc().getField("_recovery_source").binaryValue(), equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\"}")));
if (IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled() == false) {
// TODO: remove this if branch when removing the 'index_recovery_use_synthetic_source' feature flag
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\"}"))
);
} else {
assertNull(doc.rootDoc().getField("_recovery_source"));
}
}
{
Settings settings = Settings.builder()
Expand All @@ -728,11 +749,16 @@ public void testRecoverySourceWithTimeSeries() throws IOException {
}));
DocumentMapper docMapper = mapperService.documentMapper();
ParsedDocument doc = docMapper.parse(source("123", b -> b.field("@timestamp", "2012-02-13").field("field", "value1"), null));
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\",\"field\":\"value1\"}"))
);
if (IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled() == false) {
// TODO: remove this if branch when removing the 'index_recovery_use_synthetic_source' feature flag
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\",\"field\":\"value1\"}"))
);
} else {
assertNull(doc.rootDoc().getField("_recovery_source"));
}
}
{
Settings settings = Settings.builder()
Expand Down Expand Up @@ -776,11 +802,16 @@ public void testRecoverySourceWithTimeSeriesCustom() throws IOException {
MapperService mapperService = createMapperService(settings, mappings);
DocumentMapper docMapper = mapperService.documentMapper();
ParsedDocument doc = docMapper.parse(source("123", b -> b.field("@timestamp", "2012-02-13").field("field", "value1"), null));
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\",\"field\":\"value1\"}"))
);
if (IndexSettings.RECOVERY_USE_SYNTHETIC_SOURCE.isEnabled() == false) {
// TODO: remove this if branch when removing the 'index_recovery_use_synthetic_source' feature flag
assertNotNull(doc.rootDoc().getField("_recovery_source"));
assertThat(
doc.rootDoc().getField("_recovery_source").binaryValue(),
equalTo(new BytesRef("{\"@timestamp\":\"2012-02-13\",\"field\":\"value1\"}"))
);
} else {
assertNull(doc.rootDoc().getField("_recovery_source"));
}
}
{
Settings settings = Settings.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -884,8 +884,11 @@ protected void validateRoundTripReader(String syntheticSource, DirectoryReader r
throws IOException {
assertReaderEquals(
"round trip " + syntheticSource,
new FieldMaskingReader(SourceFieldMapper.RECOVERY_SOURCE_NAME, reader),
new FieldMaskingReader(SourceFieldMapper.RECOVERY_SOURCE_NAME, roundTripReader)
new FieldMaskingReader(Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME), reader),
new FieldMaskingReader(
Set.of(SourceFieldMapper.RECOVERY_SOURCE_NAME, SourceFieldMapper.RECOVERY_SOURCE_SIZE_NAME),
roundTripReader
)
);
}

Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugin/logsdb/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ tasks.named("javaRestTest").configure {
tasks.named('yamlRestTest') {
usesDefaultDistribution()
}


Loading