Skip to content
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

Add translog files age to Translog Stats (#28613) #28613

Merged
merged 4 commits into from
Feb 16, 2018
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 @@ -33,6 +33,7 @@ setup:
# non empty generation with one op may be smaller or larger than that.
# - gt: { indices.test.primaries.translog.uncommitted_size_in_bytes: $creation_size }
- match: { indices.test.primaries.translog.uncommitted_operations: 1 }
- gte: { indices.test.primaries.translog.earliest_last_modified_age: 0 }

- do:
indices.flush:
Expand All @@ -46,6 +47,7 @@ setup:
## creation translog size has some overhead due to an initial empty generation that will be trimmed later
- lt: { indices.test.primaries.translog.uncommitted_size_in_bytes: $creation_size }
- match: { indices.test.primaries.translog.uncommitted_operations: 0 }
- gte: { indices.test.primaries.translog.earliest_last_modified_age: 0 }

- do:
indices.put_settings:
Expand All @@ -67,3 +69,4 @@ setup:
- match: { indices.test.primaries.translog.operations: 0 }
- lte: { indices.test.primaries.translog.uncommitted_size_in_bytes: $creation_size }
- match: { indices.test.primaries.translog.uncommitted_operations: 0 }
- gte: { indices.test.primaries.translog.earliest_last_modified_age: 0 }
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,26 @@ public long sizeInBytes() {
return sizeInBytesByMinGen(-1);
}

long earliestLastModifiedAge() {
try (ReleasableLock ignored = readLock.acquire()) {
ensureOpen();
return findEarliestLastModifiedAge(System.currentTimeMillis(), readers, current);
} catch (IOException e) {
throw new TranslogException(shardId, "Unable to get the earliest last modified time for the transaction log");
}
}

/**
* Returns the age of the oldest entry in the translog files in seconds
*/
static long findEarliestLastModifiedAge(long currentTime, Iterable<TranslogReader> readers, TranslogWriter writer) throws IOException {
long earliestTime = currentTime;
for (BaseTranslogReader r : readers) {
earliestTime = Math.min(r.getLastModifiedTime(), earliestTime);
}
return Math.max(0, currentTime - Math.min(earliestTime, writer.getLastModifiedTime()));
}

/**
* Returns the number of operations in the transaction files that aren't committed to lucene..
*/
Expand Down Expand Up @@ -738,7 +758,7 @@ private void closeOnTragicEvent(Exception ex) {
public TranslogStats stats() {
// acquire lock to make the two numbers roughly consistent (no file change half way)
try (ReleasableLock lock = readLock.acquire()) {
return new TranslogStats(totalOperations(), sizeInBytes(), uncommittedOperations(), uncommittedSizeInBytes());
return new TranslogStats(totalOperations(), sizeInBytes(), uncommittedOperations(), uncommittedSizeInBytes(), earliestLastModifiedAge());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ public class TranslogStats implements Streamable, ToXContentFragment {
private int numberOfOperations;
private long uncommittedSizeInBytes;
private int uncommittedOperations;
private long earliestLastModifiedAge;

public TranslogStats() {
}

public TranslogStats(int numberOfOperations, long translogSizeInBytes, int uncommittedOperations, long uncommittedSizeInBytes) {
public TranslogStats(int numberOfOperations, long translogSizeInBytes, int uncommittedOperations, long uncommittedSizeInBytes,
long earliestLastModifiedAge) {
if (numberOfOperations < 0) {
throw new IllegalArgumentException("numberOfOperations must be >= 0");
}
Expand All @@ -51,10 +53,14 @@ public TranslogStats(int numberOfOperations, long translogSizeInBytes, int uncom
if (uncommittedSizeInBytes < 0) {
throw new IllegalArgumentException("uncommittedSizeInBytes must be >= 0");
}
if (earliestLastModifiedAge < 0) {
throw new IllegalArgumentException("earliestLastModifiedAge must be >= 0");
}
this.numberOfOperations = numberOfOperations;
this.translogSizeInBytes = translogSizeInBytes;
this.uncommittedSizeInBytes = uncommittedSizeInBytes;
this.uncommittedOperations = uncommittedOperations;
this.earliestLastModifiedAge = earliestLastModifiedAge;
}

public void add(TranslogStats translogStats) {
Expand All @@ -66,6 +72,8 @@ public void add(TranslogStats translogStats) {
this.translogSizeInBytes += translogStats.translogSizeInBytes;
this.uncommittedOperations += translogStats.uncommittedOperations;
this.uncommittedSizeInBytes += translogStats.uncommittedSizeInBytes;
this.earliestLastModifiedAge =
Math.min(this.earliestLastModifiedAge, translogStats.earliestLastModifiedAge);
}

public long getTranslogSizeInBytes() {
Expand All @@ -86,13 +94,16 @@ public int getUncommittedOperations() {
return uncommittedOperations;
}

public long getEarliestLastModifiedAge() { return earliestLastModifiedAge; }

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject("translog");
builder.field("operations", numberOfOperations);
builder.byteSizeField("size_in_bytes", "size", translogSizeInBytes);
builder.field("uncommitted_operations", uncommittedOperations);
builder.byteSizeField("uncommitted_size_in_bytes", "uncommitted_size", uncommittedSizeInBytes);
builder.field("earliest_last_modified_age", earliestLastModifiedAge);
builder.endObject();
return builder;
}
Expand All @@ -113,6 +124,9 @@ public void readFrom(StreamInput in) throws IOException {
uncommittedOperations = numberOfOperations;
uncommittedSizeInBytes = translogSizeInBytes;
}
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
earliestLastModifiedAge = in.readVLong();
}
}

@Override
Expand All @@ -123,5 +137,8 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(uncommittedOperations);
out.writeVLong(uncommittedSizeInBytes);
}
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
out.writeVLong(earliestLastModifiedAge);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.isIn;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.stub;

@LuceneTestCase.SuppressFileSystems("ExtrasFS")
public class TranslogTests extends ESTestCase {
Expand Down Expand Up @@ -366,6 +368,29 @@ protected TranslogStats stats() throws IOException {
return stats;
}

public void testFindEarliestLastModifiedAge() throws IOException {
final int numberOfReaders = scaledRandomIntBetween(1, 10);
long fixedTime = randomLongBetween(0, 10000000000000000L);
long[] periods = new long[numberOfReaders + 1];
long period = randomLongBetween(10000, 1000000);
periods[numberOfReaders] = period;
TranslogWriter w = mock(TranslogWriter.class);
stub(w.getLastModifiedTime()).toReturn(fixedTime - period);
assertThat(Translog.findEarliestLastModifiedAge(fixedTime, new ArrayList<>(), w), equalTo(period));

for (int i = 0; i < numberOfReaders; i++) {
periods[i] = randomLongBetween(10000, 1000000);
}
List<TranslogReader> readers = new ArrayList<>();
for (long l : periods) {
TranslogReader r = mock(TranslogReader.class);
stub(r.getLastModifiedTime()).toReturn(fixedTime - l);
readers.add(r);
}
assertThat(Translog.findEarliestLastModifiedAge(fixedTime, readers, w), equalTo
(LongStream.of(periods).max().orElse(0L)));
}

public void testStats() throws IOException {
// self control cleaning for test
translog.getDeletionPolicy().setRetentionSizeInBytes(1024 * 1024);
Expand All @@ -384,6 +409,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(140L));
assertThat(stats.getUncommittedOperations(), equalTo(1));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(140L));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}

translog.add(new Translog.Delete("test", "2", 1, newUid("2")));
Expand All @@ -393,6 +419,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(189L));
assertThat(stats.getUncommittedOperations(), equalTo(2));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(189L));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}

translog.add(new Translog.Delete("test", "3", 2, newUid("3")));
Expand All @@ -402,6 +429,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(238L));
assertThat(stats.getUncommittedOperations(), equalTo(3));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(238L));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}

translog.add(new Translog.NoOp(3, 1, randomAlphaOfLength(16)));
Expand All @@ -411,6 +439,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(280L));
assertThat(stats.getUncommittedOperations(), equalTo(4));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(280L));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}

final long expectedSizeInBytes = 323L;
Expand All @@ -421,6 +450,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(expectedSizeInBytes));
assertThat(stats.getUncommittedOperations(), equalTo(4));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(expectedSizeInBytes));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}

{
Expand All @@ -438,7 +468,8 @@ public void testStats() throws IOException {
copy.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
assertThat(builder.string(), equalTo("{\"translog\":{\"operations\":4,\"size_in_bytes\":" + expectedSizeInBytes
+ ",\"uncommitted_operations\":4,\"uncommitted_size_in_bytes\":" + expectedSizeInBytes + "}}"));
+ ",\"uncommitted_operations\":4,\"uncommitted_size_in_bytes\":" + expectedSizeInBytes
+ ",\"earliest_last_modified_age\":" + stats.getEarliestLastModifiedAge() + "}}"));
}
}

Expand All @@ -449,6 +480,7 @@ public void testStats() throws IOException {
assertThat(stats.getTranslogSizeInBytes(), equalTo(expectedSizeInBytes));
assertThat(stats.getUncommittedOperations(), equalTo(0));
assertThat(stats.getUncommittedSizeInBytes(), equalTo(firstOperationPosition));
assertThat(stats.getEarliestLastModifiedAge(), greaterThan(1L));
}
}

Expand Down Expand Up @@ -478,12 +510,12 @@ public void testUncommittedOperations() throws Exception {
}

public void testTotalTests() {
final TranslogStats total = new TranslogStats();
final TranslogStats total = new TranslogStats(0, 0, 0, 0, 1);
final int n = randomIntBetween(0, 16);
final List<TranslogStats> statsList = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
final TranslogStats stats = new TranslogStats(randomIntBetween(1, 4096), randomIntBetween(1, 1 << 20),
randomIntBetween(1, 1 << 20), randomIntBetween(1, 4096));
randomIntBetween(1, 1 << 20), randomIntBetween(1, 4096), randomIntBetween(1, 1 << 20));
statsList.add(stats);
total.add(stats);
}
Expand All @@ -500,22 +532,30 @@ public void testTotalTests() {
assertThat(
total.getUncommittedSizeInBytes(),
equalTo(statsList.stream().mapToLong(TranslogStats::getUncommittedSizeInBytes).sum()));
assertThat(
total.getEarliestLastModifiedAge(),
equalTo(1L));
}

public void testNegativeNumberOfOperations() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(-1, 1, 1, 1));
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(-1, 1, 1, 1, 1));
assertThat(e, hasToString(containsString("numberOfOperations must be >= 0")));
e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, 1, -1, 1));
e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, 1, -1, 1, 1));
assertThat(e, hasToString(containsString("uncommittedOperations must be >= 0")));
}

public void testNegativeSizeInBytes() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, -1, 1, 1));
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, -1, 1, 1, 1));
assertThat(e, hasToString(containsString("translogSizeInBytes must be >= 0")));
e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, 1, 1, -1));
e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, 1, 1, -1, 1));
assertThat(e, hasToString(containsString("uncommittedSizeInBytes must be >= 0")));
}

public void testOldestEntryInSeconds() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new TranslogStats(1, 1, 1, 1, -1));
assertThat(e, hasToString(containsString("earliestLastModifiedAge must be >= 0")));
}

public void testSnapshot() throws IOException {
ArrayList<Translog.Operation> ops = new ArrayList<>();
try (Translog.Snapshot snapshot = translog.newSnapshot()) {
Expand Down