Skip to content

[7.x] Add max_single_primary_size as a condition for the rollover index API #68489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 4, 2021
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 @@ -10,6 +10,7 @@
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSinglePrimarySizeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition;
import org.elasticsearch.client.TimedRequest;
import org.elasticsearch.client.indices.CreateIndexRequest;
Expand Down Expand Up @@ -94,6 +95,7 @@ public RolloverRequest addMaxIndexDocsCondition(long numDocs) {
this.conditions.put(maxDocsCondition.name(), maxDocsCondition);
return this;
}

/**
* Adds a size-based condition to check if the index size is at least <code>size</code>.
*/
Expand All @@ -105,6 +107,19 @@ public RolloverRequest addMaxIndexSizeCondition(ByteSizeValue size) {
this.conditions.put(maxSizeCondition.name(), maxSizeCondition);
return this;
}

/**
* Adds a size-based condition to check if the size of the largest primary shard is at least <code>size</code>.
*/
public RolloverRequest addMaxSinglePrimarySizeCondition(ByteSizeValue size) {
MaxSinglePrimarySizeCondition maxSinglePrimarySizeCondition = new MaxSinglePrimarySizeCondition(size);
if (this.conditions.containsKey(maxSinglePrimarySizeCondition.name())) {
throw new IllegalArgumentException(maxSinglePrimarySizeCondition + " condition is already set");
}
this.conditions.put(maxSinglePrimarySizeCondition.name(), maxSinglePrimarySizeCondition);
return this;
}

/**
* Returns all set conditions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1213,15 +1213,17 @@ public void testRollover() throws IOException {
rolloverRequest.getCreateIndexRequest().mapping(mappings, XContentType.JSON);
rolloverRequest.dryRun(false);
rolloverRequest.addMaxIndexSizeCondition(new ByteSizeValue(1, ByteSizeUnit.MB));
rolloverRequest.addMaxSinglePrimarySizeCondition(new ByteSizeValue(1, ByteSizeUnit.MB));
RolloverResponse rolloverResponse = execute(rolloverRequest, highLevelClient().indices()::rollover,
highLevelClient().indices()::rolloverAsync);
assertTrue(rolloverResponse.isRolledOver());
assertFalse(rolloverResponse.isDryRun());
Map<String, Boolean> conditionStatus = rolloverResponse.getConditionStatus();
assertEquals(3, conditionStatus.size());
assertEquals(4, conditionStatus.size());
assertTrue(conditionStatus.get("[max_docs: 1]"));
assertTrue(conditionStatus.get("[max_age: 1ms]"));
assertFalse(conditionStatus.get("[max_size: 1mb]"));
assertFalse(conditionStatus.get("[max_single_primary_size: 1mb]"));
assertEquals("test", rolloverResponse.getOldIndex());
assertEquals("test_new", rolloverResponse.getNewIndex());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,7 @@ public void testRolloverIndex() throws Exception {
request.addMaxIndexAgeCondition(new TimeValue(7, TimeUnit.DAYS)); // <2>
request.addMaxIndexDocsCondition(1000); // <3>
request.addMaxIndexSizeCondition(new ByteSizeValue(5, ByteSizeUnit.GB)); // <4>
request.addMaxSinglePrimarySizeCondition(new ByteSizeValue(2, ByteSizeUnit.GB)); // <5>
// end::rollover-index-request

// tag::rollover-index-request-timeout
Expand Down Expand Up @@ -1945,7 +1946,7 @@ public void testRolloverIndex() throws Exception {
assertEquals("index-2", newIndex);
assertFalse(isRolledOver);
assertTrue(isDryRun);
assertEquals(3, conditionStatus.size());
assertEquals(4, conditionStatus.size());

// tag::rollover-index-execute-listener
ActionListener<RolloverResponse> listener = new ActionListener<RolloverResponse>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSinglePrimarySizeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
Expand All @@ -36,12 +37,16 @@ public void testConstructorAndFieldAssignments() {

// test assignment of conditions
MaxAgeCondition maxAgeCondition = new MaxAgeCondition(new TimeValue(10));
MaxSizeCondition maxSizeCondition = new MaxSizeCondition(new ByteSizeValue(2000));
MaxDocsCondition maxDocsCondition = new MaxDocsCondition(10000L);
Condition<?>[] expectedConditions = new Condition<?>[] {maxAgeCondition, maxSizeCondition, maxDocsCondition};
MaxSizeCondition maxSizeCondition = new MaxSizeCondition(new ByteSizeValue(2000));
MaxSinglePrimarySizeCondition maxSinglePrimarySizeCondition = new MaxSinglePrimarySizeCondition(new ByteSizeValue(3000));
Condition<?>[] expectedConditions = new Condition<?>[]{
maxAgeCondition, maxDocsCondition, maxSizeCondition, maxSinglePrimarySizeCondition
};
rolloverRequest.addMaxIndexAgeCondition(maxAgeCondition.value());
rolloverRequest.addMaxIndexSizeCondition(maxSizeCondition.value());
rolloverRequest.addMaxIndexDocsCondition(maxDocsCondition.value());
rolloverRequest.addMaxIndexSizeCondition(maxSizeCondition.value());
rolloverRequest.addMaxSinglePrimarySizeCondition(maxSinglePrimarySizeCondition.value());
List<Condition<?>> requestConditions = new ArrayList<>(rolloverRequest.getConditions().values());
assertThat(requestConditions, containsInAnyOrder(expectedConditions));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSinglePrimarySizeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
Expand All @@ -36,8 +37,9 @@ public class RolloverResponseTests extends ESTestCase {
private static final List<Supplier<Condition<?>>> conditionSuppliers = new ArrayList<>();
static {
conditionSuppliers.add(() -> new MaxAgeCondition(new TimeValue(randomNonNegativeLong())));
conditionSuppliers.add(() -> new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong())));
conditionSuppliers.add(() -> new MaxDocsCondition(randomNonNegativeLong()));
conditionSuppliers.add(() -> new MaxSizeCondition(new ByteSizeValue(randomNonNegativeLong())));
conditionSuppliers.add(() -> new MaxSinglePrimarySizeCondition(new ByteSizeValue(randomNonNegativeLong())));
}

public void testFromXContent() throws IOException {
Expand Down
1 change: 1 addition & 0 deletions docs/java-rest/high-level/indices/rollover.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ The new index argument is optional, and can be set to null
<2> Condition on the age of the index
<3> Condition on the number of documents in the index
<4> Condition on the size of the index
<5> Condition on the size of the largest primary shard of the index

==== Optional arguments
The following arguments can optionally be provided:
Expand Down
30 changes: 24 additions & 6 deletions docs/reference/indices/rollover-index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ POST /alias1/_rollover/my-index-000002
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
}
}
----
Expand Down Expand Up @@ -165,6 +166,16 @@ Replicas are not counted toward the maximum index size.

TIP: To see the current index size, use the <<cat-indices, _cat indices>> API.
The `pri.store.size` value shows the combined size of all primary shards.

`max_single_primary_size`::
(Optional, <<byte-units, byte units>>)
Maximum primary shard size.
This is the maximum size of the primary shards in the index. As with `max_size`,
replicas are ignored.

TIP: To see the current shard size, use the <<cat-shards, _cat shards>> API.
The `store` value shows the size each shard, and `prirep` indicates whether a
shard is a primary (`p`) or a replica (`r`).
--

include::{es-repo-dir}/rest-api/common-parms.asciidoc[tag=mappings]
Expand Down Expand Up @@ -194,7 +205,8 @@ POST /logs_write/_rollover <2>
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
}
}
--------------------------------------------------
Expand All @@ -220,6 +232,7 @@ The API returns the following response:
"[max_age: 7d]": false,
"[max_docs: 1000]": true,
"[max_size: 5gb]": false,
"[max_single_primary_size: 2gb]": false
}
}
--------------------------------------------------
Expand Down Expand Up @@ -252,7 +265,8 @@ POST /my-data-stream/_rollover <2>
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
}
}
--------------------------------------------------
Expand Down Expand Up @@ -286,6 +300,7 @@ The API returns the following response:
"[max_age: 7d]": false,
"[max_docs: 1000]": true,
"[max_size: 5gb]": false,
"[max_single_primary_size: 2gb]": false
}
}
--------------------------------------------------
Expand Down Expand Up @@ -332,7 +347,8 @@ POST /logs_write/_rollover
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
},
"settings": {
"index.number_of_shards": 2
Expand All @@ -359,7 +375,8 @@ POST /my_alias/_rollover/my_new_index_name
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
}
}
--------------------------------------------------
Expand Down Expand Up @@ -457,7 +474,8 @@ POST /logs_write/_rollover?dry_run
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
"max_size": "5gb",
"max_single_primary_size": "2gb"
}
}
--------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
"Rollover with max_single_primary_size condition":
- skip:
version: " - 7.11.99"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check my brain on this one bit here -- is this the right version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is the right version

reason: max_single_primary_size condition was introduced in 7.12.0

# create index with alias and replica
- do:
indices.create:
index: logs-1
wait_for_active_shards: 1
body:
aliases:
logs_search: {}

# index a document
- do:
index:
index: logs-1
id: "1"
body: { "foo": "hello world" }
refresh: true

# perform alias rollover with a large max_single_primary_size, no action.
- do:
indices.rollover:
alias: "logs_search"
wait_for_active_shards: 1
body:
conditions:
max_single_primary_size: 100mb

- match: { conditions: { "[max_single_primary_size: 100mb]": false } }
- match: { rolled_over: false }

# perform alias rollover with a small max_single_primary_size, got action.
- do:
indices.rollover:
alias: "logs_search"
wait_for_active_shards: 1
body:
conditions:
max_single_primary_size: 10b

- match: { conditions: { "[max_single_primary_size: 10b]": true } }
- match: { rolled_over: true }

# perform alias rollover on an empty index, no action.
- do:
indices.rollover:
alias: "logs_search"
wait_for_active_shards: 1
body:
conditions:
max_single_primary_size: 1b

- match: { conditions: { "[max_single_primary_size: 1b]": false } }
- match: { rolled_over: false }
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,62 @@ public void testRolloverMaxSize() throws Exception {
}
}

public void testRolloverMaxSinglePrimarySize() throws Exception {
assertAcked(prepareCreate("test-1").addAlias(new Alias("test_alias")).get());
int numDocs = randomIntBetween(10, 20);
for (int i = 0; i < numDocs; i++) {
index("test-1", "doc", Integer.toString(i), "field", "foo-" + i);
}
flush("test-1");
refresh("test_alias");

// A large max_single_primary_size
{
final RolloverResponse response = client().admin().indices()
.prepareRolloverIndex("test_alias")
.addMaxSinglePrimarySizeCondition(new ByteSizeValue(randomIntBetween(100, 50 * 1024), ByteSizeUnit.MB))
.get();
assertThat(response.getOldIndex(), equalTo("test-1"));
assertThat(response.getNewIndex(), equalTo("test-000002"));
assertThat("No rollover with a large max_single_primary_size condition", response.isRolledOver(), equalTo(false));
final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-1");
assertThat(oldIndex.getRolloverInfos().size(), equalTo(0));
}

// A small max_single_primary_size
{
ByteSizeValue maxSinglePrimarySizeCondition = new ByteSizeValue(randomIntBetween(1, 20), ByteSizeUnit.BYTES);
long beforeTime = client().threadPool().absoluteTimeInMillis() - 1000L;
final RolloverResponse response = client().admin().indices()
.prepareRolloverIndex("test_alias")
.addMaxSinglePrimarySizeCondition(maxSinglePrimarySizeCondition)
.get();
assertThat(response.getOldIndex(), equalTo("test-1"));
assertThat(response.getNewIndex(), equalTo("test-000002"));
assertThat("Should rollover with a small max_single_primary_size condition", response.isRolledOver(), equalTo(true));
final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-1");
List<Condition<?>> metConditions = oldIndex.getRolloverInfos().get("test_alias").getMetConditions();
assertThat(metConditions.size(), equalTo(1));
assertThat(metConditions.get(0).toString(),
equalTo(new MaxSinglePrimarySizeCondition(maxSinglePrimarySizeCondition).toString()));
assertThat(oldIndex.getRolloverInfos().get("test_alias").getTime(),
is(both(greaterThanOrEqualTo(beforeTime)).and(lessThanOrEqualTo(client().threadPool().absoluteTimeInMillis() + 1000L))));
}

// An empty index
{
final RolloverResponse response = client().admin().indices()
.prepareRolloverIndex("test_alias")
.addMaxSinglePrimarySizeCondition(new ByteSizeValue(randomNonNegativeLong(), ByteSizeUnit.BYTES))
.get();
assertThat(response.getOldIndex(), equalTo("test-000002"));
assertThat(response.getNewIndex(), equalTo("test-000003"));
assertThat("No rollover with an empty index", response.isRolledOver(), equalTo(false));
final IndexMetadata oldIndex = client().admin().cluster().prepareState().get().getState().metadata().index("test-000002");
assertThat(oldIndex.getRolloverInfos().size(), equalTo(0));
}
}

public void testRejectIfAliasFoundInTemplate() throws Exception {
client().admin().indices().preparePutTemplate("logs")
.setPatterns(Collections.singletonList("logs-*")).addAlias(new Alias("logs-write")).get();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ public static class Stats {
public final long numDocs;
public final long indexCreated;
public final ByteSizeValue indexSize;
public final ByteSizeValue maxSinglePrimarySize;

public Stats(long numDocs, long indexCreated, ByteSizeValue indexSize) {
public Stats(long numDocs, long indexCreated, ByteSizeValue indexSize, ByteSizeValue maxSinglePrimarySize) {
this.numDocs = numDocs;
this.indexCreated = indexCreated;
this.indexSize = indexSize;
this.maxSinglePrimarySize = maxSinglePrimarySize;
}
}

Expand Down
Loading