|
42 | 42 | import static org.elasticsearch.index.translog.TranslogDeletionPolicies.createTranslogDeletionPolicy;
|
43 | 43 | import static org.hamcrest.Matchers.contains;
|
44 | 44 | import static org.hamcrest.Matchers.equalTo;
|
| 45 | +import static org.hamcrest.Matchers.greaterThan; |
45 | 46 | import static org.mockito.Mockito.mock;
|
46 | 47 | import static org.mockito.Mockito.never;
|
47 | 48 | import static org.mockito.Mockito.times;
|
@@ -149,6 +150,54 @@ public void testLegacyIndex() throws Exception {
|
149 | 150 | assertThat(translogPolicy.getTranslogGenerationOfLastCommit(), equalTo(safeTranslogGen));
|
150 | 151 | }
|
151 | 152 |
|
| 153 | + public void testKeepSingleNoOpsCommits() throws Exception { |
| 154 | + final AtomicLong globalCheckpoint = new AtomicLong(randomLong()); |
| 155 | + final UUID translogUUID = UUID.randomUUID(); |
| 156 | + TranslogDeletionPolicy translogPolicy = createTranslogDeletionPolicy(); |
| 157 | + CombinedDeletionPolicy indexPolicy = new CombinedDeletionPolicy(OPEN_INDEX_AND_TRANSLOG, translogPolicy, globalCheckpoint::get); |
| 158 | + |
| 159 | + final List<IndexCommit> commitList = new ArrayList<>(); |
| 160 | + final int numOfNoOpsCommits = between(1, 10); |
| 161 | + long lastNoopTranslogGen = 0; |
| 162 | + for (int i = 0; i < numOfNoOpsCommits; i++) { |
| 163 | + lastNoopTranslogGen += between(1, 20); |
| 164 | + commitList.add(mockIndexCommit(SequenceNumbers.NO_OPS_PERFORMED, translogUUID, lastNoopTranslogGen)); |
| 165 | + } |
| 166 | + // Keep only one no_ops commit. |
| 167 | + indexPolicy.onCommit(commitList); |
| 168 | + assertThat(translogPolicy.getMinTranslogGenerationForRecovery(), equalTo(lastNoopTranslogGen)); |
| 169 | + assertThat(translogPolicy.getTranslogGenerationOfLastCommit(), equalTo(lastNoopTranslogGen)); |
| 170 | + for (int i = 0; i < numOfNoOpsCommits - 1; i++) { |
| 171 | + verify(commitList.get(i), times(1)).delete(); |
| 172 | + } |
| 173 | + verify(commitList.get(commitList.size() - 1), never()).delete(); |
| 174 | + // Add a some good commits. |
| 175 | + final int numOfGoodCommits = between(1, 5); |
| 176 | + long maxSeqNo = 0; |
| 177 | + long lastTranslogGen = lastNoopTranslogGen; |
| 178 | + for (int i = 0; i < numOfGoodCommits; i++) { |
| 179 | + maxSeqNo += between(1, 1000); |
| 180 | + lastTranslogGen += between(1, 20); |
| 181 | + commitList.add(mockIndexCommit(maxSeqNo, translogUUID, lastTranslogGen)); |
| 182 | + } |
| 183 | + // If the global checkpoint is still unassigned, we should still keep one NO_OPS_PERFORMED commit. |
| 184 | + globalCheckpoint.set(SequenceNumbers.UNASSIGNED_SEQ_NO); |
| 185 | + indexPolicy.onCommit(commitList); |
| 186 | + assertThat(translogPolicy.getMinTranslogGenerationForRecovery(), equalTo(lastNoopTranslogGen)); |
| 187 | + assertThat(translogPolicy.getTranslogGenerationOfLastCommit(), equalTo(lastTranslogGen)); |
| 188 | + for (int i = 0; i < numOfNoOpsCommits - 1; i++) { |
| 189 | + verify(commitList.get(i), times(2)).delete(); |
| 190 | + } |
| 191 | + verify(commitList.get(numOfNoOpsCommits - 1), never()).delete(); |
| 192 | + // Delete no-ops commit if global checkpoint advanced enough. |
| 193 | + final long lower = Long.parseLong(commitList.get(numOfNoOpsCommits).getUserData().get(SequenceNumbers.MAX_SEQ_NO)); |
| 194 | + globalCheckpoint.set(randomLongBetween(lower, Long.MAX_VALUE)); |
| 195 | + indexPolicy.onCommit(commitList); |
| 196 | + assertThat(translogPolicy.getMinTranslogGenerationForRecovery(), greaterThan(lastNoopTranslogGen)); |
| 197 | + assertThat(translogPolicy.getTranslogGenerationOfLastCommit(), equalTo(lastTranslogGen)); |
| 198 | + verify(commitList.get(numOfNoOpsCommits - 1), times(1)).delete(); |
| 199 | + } |
| 200 | + |
152 | 201 | public void testDeleteInvalidCommits() throws Exception {
|
153 | 202 | final AtomicLong globalCheckpoint = new AtomicLong(randomNonNegativeLong());
|
154 | 203 | TranslogDeletionPolicy translogPolicy = createTranslogDeletionPolicy();
|
|
0 commit comments