Skip to content

Commit 2900e03

Browse files
authored
Implement lazy rollover for failure stores (#108108)
Allow marking failure stores for lazy rollover.
1 parent df8c8bc commit 2900e03

File tree

12 files changed

+653
-168
lines changed

12 files changed

+653
-168
lines changed

modules/data-streams/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ esplugin {
1414
restResources {
1515
restApi {
1616
include 'bulk', 'count', 'search', '_common', 'indices', 'index', 'cluster', 'rank_eval', 'reindex', 'update_by_query', 'delete_by_query',
17-
'eql', 'data_stream', 'ingest', 'cat'
17+
'eql', 'data_stream', 'ingest', 'cat', 'capabilities'
1818
}
1919
}
2020

modules/data-streams/src/yamlRestTest/resources/rest-api-spec/test/data_stream/200_rollover_failure_store.yml

Lines changed: 219 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ setup:
33
- requires:
44
cluster_features: ["gte_v8.15.0"]
55
reason: "data stream failure stores REST structure changed in 8.15+"
6-
test_runner_features: allowed_warnings
6+
test_runner_features: [allowed_warnings, contains, capabilities]
77

88
- do:
99
allowed_warnings:
@@ -27,13 +27,24 @@ setup:
2727
name: data-stream-for-rollover
2828

2929
---
30+
teardown:
31+
- do:
32+
indices.delete_data_stream:
33+
name: data-stream-for-lazy-rollover
34+
ignore: 404
35+
36+
- do:
37+
ingest.delete_pipeline:
38+
id: failing_pipeline
39+
ignore: 404
40+
---
3041
"Roll over a data stream's failure store without conditions":
31-
# rollover data stream to create new backing index
3242
- do:
3343
indices.rollover:
3444
alias: "data-stream-for-rollover"
3545
target_failure_store: true
3646

47+
- match: { acknowledged: true }
3748
- match: { old_index: "/\\.fs-data-stream-for-rollover-(\\d{4}\\.\\d{2}\\.\\d{2}-)?000001/" }
3849
- match: { new_index: "/\\.fs-data-stream-for-rollover-(\\d{4}\\.\\d{2}\\.\\d{2}-)?000002/" }
3950
- match: { rolled_over: true }
@@ -54,7 +65,6 @@ setup:
5465

5566
---
5667
"Roll over a data stream's failure store with conditions":
57-
# index first document and wait for refresh
5868
- do:
5969
index:
6070
index: data-stream-for-rollover
@@ -63,7 +73,6 @@ setup:
6373
'@timestamp': '2020-12-12'
6474
count: 'invalid value'
6575

66-
# rollover data stream to create new backing index
6776
- do:
6877
indices.rollover:
6978
alias: "data-stream-for-rollover"
@@ -72,6 +81,7 @@ setup:
7281
conditions:
7382
max_docs: 1
7483

84+
- match: { acknowledged: true }
7585
- match: { old_index: "/\\.fs-data-stream-for-rollover-(\\d{4}\\.\\d{2}\\.\\d{2}-)?000001/" }
7686
- match: { new_index: "/\\.fs-data-stream-for-rollover-(\\d{4}\\.\\d{2}\\.\\d{2}-)?000002/" }
7787
- match: { rolled_over: true }
@@ -92,7 +102,6 @@ setup:
92102

93103
---
94104
"Don't roll over a data stream's failure store when conditions aren't met":
95-
# rollover data stream to create new backing index
96105
- do:
97106
indices.rollover:
98107
alias: "data-stream-for-rollover"
@@ -101,14 +110,219 @@ setup:
101110
conditions:
102111
max_docs: 1
103112

113+
- match: { acknowledged: false }
114+
- match: { rolled_over: false }
115+
- match: { dry_run: false }
116+
117+
- do:
118+
indices.get_data_stream:
119+
name: "*"
120+
- match: { data_streams.0.name: data-stream-for-rollover }
121+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
122+
- match: { data_streams.0.generation: 1 }
123+
- length: { data_streams.0.indices: 1 }
124+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
125+
- length: { data_streams.0.failure_store.indices: 1 }
126+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
127+
128+
---
129+
"Lazily roll over a data stream's failure store after a shard failure":
130+
- requires:
131+
reason: "data stream failure store lazy rollover only supported in 8.15+"
132+
test_runner_features: [allowed_warnings, capabilities]
133+
capabilities:
134+
- method: POST
135+
path: /{index}/_rollover
136+
capabilities: [lazy-rollover-failure-store]
137+
138+
# Mark the failure store for lazy rollover
139+
- do:
140+
indices.rollover:
141+
alias: "data-stream-for-rollover"
142+
target_failure_store: true
143+
lazy: true
144+
145+
- match: { acknowledged: true }
146+
- match: { rolled_over: false }
147+
- match: { dry_run: false }
148+
149+
- do:
150+
indices.get_data_stream:
151+
name: "*"
152+
- match: { data_streams.0.name: data-stream-for-rollover }
153+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
154+
- match: { data_streams.0.generation: 1 }
155+
- length: { data_streams.0.indices: 1 }
156+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
157+
- length: { data_streams.0.failure_store.indices: 1 }
158+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
159+
160+
- do:
161+
index:
162+
index: data-stream-for-rollover
163+
refresh: true
164+
body:
165+
'@timestamp': '2020-12-12'
166+
count: 'invalid value'
167+
168+
- do:
169+
indices.get_data_stream:
170+
name: "*"
171+
- match: { data_streams.0.name: data-stream-for-rollover }
172+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
173+
# Both backing and failure indices use the same generation field.
174+
- match: { data_streams.0.generation: 2 }
175+
- length: { data_streams.0.indices: 1 }
176+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
177+
- length: { data_streams.0.failure_store.indices: 2 }
178+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
179+
- match: { data_streams.0.failure_store.indices.1.index_name: '/\.fs-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000002/' }
180+
181+
- do:
182+
search:
183+
index: .fs-data-stream-for-rollover-*
184+
- length: { hits.hits: 1 }
185+
- match: { hits.hits.0._index: "/\\.fs-data-stream-for-rollover-(\\d{4}\\.\\d{2}\\.\\d{2}-)?000002/" }
186+
- exists: hits.hits.0._source.@timestamp
187+
- not_exists: hits.hits.0._source.count
188+
- match: { hits.hits.0._source.document.index: 'data-stream-for-rollover' }
189+
- match: { hits.hits.0._source.document.source.@timestamp: '2020-12-12' }
190+
- match: { hits.hits.0._source.document.source.count: 'invalid value' }
191+
- match: { hits.hits.0._source.error.type: 'document_parsing_exception' }
192+
193+
---
194+
"Lazily roll over a data stream's failure store after an ingest failure":
195+
- requires:
196+
reason: "data stream failure store lazy rollover only supported in 8.15+"
197+
test_runner_features: [allowed_warnings, capabilities]
198+
capabilities:
199+
- method: POST
200+
path: /{index}/_rollover
201+
capabilities: [lazy-rollover-failure-store]
202+
203+
- do:
204+
ingest.put_pipeline:
205+
id: "failing_pipeline"
206+
body: >
207+
{
208+
"description": "_description",
209+
"processors": [
210+
{
211+
"fail" : {
212+
"message" : "error_message"
213+
}
214+
}
215+
]
216+
}
217+
- match: { acknowledged: true }
218+
219+
- do:
220+
allowed_warnings:
221+
- "index template [generic_logs_template] has index patterns [logs-*] matching patterns from existing older templates [global] with patterns (global => [*]); this template [generic_logs_template] will take precedence during new index creation"
222+
indices.put_index_template:
223+
name: my-template
224+
body:
225+
index_patterns: [data-*]
226+
data_stream:
227+
failure_store: true
228+
template:
229+
settings:
230+
index:
231+
default_pipeline: "failing_pipeline"
232+
233+
- do:
234+
indices.create_data_stream:
235+
name: data-stream-for-lazy-rollover
236+
237+
# Mark the failure store for lazy rollover
238+
- do:
239+
indices.rollover:
240+
alias: data-stream-for-lazy-rollover
241+
target_failure_store: true
242+
lazy: true
243+
244+
- match: { acknowledged: true }
104245
- match: { rolled_over: false }
105246
- match: { dry_run: false }
106247

248+
- do:
249+
indices.get_data_stream:
250+
name: "*"
251+
- match: { data_streams.0.name: data-stream-for-lazy-rollover }
252+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
253+
- match: { data_streams.0.generation: 1 }
254+
- length: { data_streams.0.indices: 1 }
255+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-lazy-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
256+
- length: { data_streams.0.failure_store.indices: 1 }
257+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-lazy-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
258+
259+
- do:
260+
index:
261+
index: data-stream-for-lazy-rollover
262+
refresh: true
263+
body:
264+
'@timestamp': '2020-12-12'
265+
count: 1
266+
267+
- do:
268+
indices.get_data_stream:
269+
name: "*"
270+
- match: { data_streams.0.name: data-stream-for-lazy-rollover }
271+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
272+
# Both backing and failure indices use the same generation field.
273+
- match: { data_streams.0.generation: 2 }
274+
- length: { data_streams.0.indices: 1 }
275+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-lazy-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
276+
- length: { data_streams.0.failure_store.indices: 2 }
277+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-lazy-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
278+
- match: { data_streams.0.failure_store.indices.1.index_name: '/\.fs-data-stream-for-lazy-rollover-(\d{4}\.\d{2}\.\d{2}-)?000002/' }
279+
280+
---
281+
"A failure store marked for lazy rollover should only be rolled over when there is a failure":
282+
- requires:
283+
reason: "data stream failure store lazy rollover only supported in 8.15+"
284+
test_runner_features: [allowed_warnings, capabilities]
285+
capabilities:
286+
- method: POST
287+
path: /{index}/_rollover
288+
capabilities: [lazy-rollover-failure-store]
289+
290+
# Mark the failure store for lazy rollover
291+
- do:
292+
indices.rollover:
293+
alias: "data-stream-for-rollover"
294+
target_failure_store: true
295+
lazy: true
296+
297+
- match: { acknowledged: true }
298+
- match: { rolled_over: false }
299+
- match: { dry_run: false }
300+
301+
- do:
302+
indices.get_data_stream:
303+
name: "*"
304+
- match: { data_streams.0.name: data-stream-for-rollover }
305+
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
306+
- match: { data_streams.0.generation: 1 }
307+
- length: { data_streams.0.indices: 1 }
308+
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
309+
- length: { data_streams.0.failure_store.indices: 1 }
310+
- match: { data_streams.0.failure_store.indices.0.index_name: '/\.fs-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }
311+
312+
- do:
313+
index:
314+
index: data-stream-for-rollover
315+
refresh: true
316+
body:
317+
'@timestamp': '2020-12-12'
318+
count: 3
319+
107320
- do:
108321
indices.get_data_stream:
109322
name: "*"
110323
- match: { data_streams.0.name: data-stream-for-rollover }
111324
- match: { data_streams.0.timestamp_field.name: '@timestamp' }
325+
# Both backing and failure indices use the same generation field.
112326
- match: { data_streams.0.generation: 1 }
113327
- length: { data_streams.0.indices: 1 }
114328
- match: { data_streams.0.indices.0.index_name: '/\.ds-data-stream-for-rollover-(\d{4}\.\d{2}\.\d{2}-)?000001/' }

server/src/main/java/org/elasticsearch/action/admin/indices/rollover/LazyRolloverAction.java

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ protected void masterOperation(
9999
rolloverRequest.getRolloverTarget(),
100100
rolloverRequest.getNewIndexName(),
101101
rolloverRequest.getCreateIndexRequest(),
102-
false
102+
rolloverRequest.indicesOptions().failureStoreOptions().includeFailureIndices()
103103
);
104104
final String trialSourceIndexName = trialRolloverNames.sourceName();
105105
final String trialRolloverIndexName = trialRolloverNames.rolloverName();
@@ -121,13 +121,9 @@ protected void masterOperation(
121121
String source = "lazy_rollover source [" + trialRolloverIndexName + "] to target [" + trialRolloverIndexName + "]";
122122
// We create a new rollover request to ensure that it doesn't contain any other parameters apart from the data stream name
123123
// This will provide a more resilient user experience
124-
RolloverTask rolloverTask = new RolloverTask(
125-
new RolloverRequest(rolloverRequest.getRolloverTarget(), null),
126-
null,
127-
trialRolloverResponse,
128-
null,
129-
listener
130-
);
124+
var newRolloverRequest = new RolloverRequest(rolloverRequest.getRolloverTarget(), null);
125+
newRolloverRequest.setIndicesOptions(rolloverRequest.indicesOptions());
126+
RolloverTask rolloverTask = new RolloverTask(newRolloverRequest, null, trialRolloverResponse, null, listener);
131127
submitRolloverTask(rolloverRequest, source, rolloverTask);
132128
}
133129
}

server/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ public ActionRequestValidationException validate() {
153153
);
154154
}
155155

156-
if (failureStoreOptions.includeFailureIndices() && lazy) {
157-
validationException = addValidationError("lazily rolling over a failure store is currently not supported", validationException);
158-
}
159-
160156
return validationException;
161157
}
162158

0 commit comments

Comments
 (0)