Skip to content

Commit e845b0a

Browse files
authored
Do not schedule Refresh/Translog/GlobalCheckpoint tasks for closed indices (#38329)
Replicated closed indices do not need to be refreshed, neither they need their translogs or global checkpoint to be fsync. This pull request changes how `BaseAsyncTask` tasks are rescheduled in `IndexService` instances so that the tasks are rescheduled only when the index is opened. Relates to #33888
1 parent cf9a015 commit e845b0a

File tree

2 files changed

+84
-7
lines changed

2 files changed

+84
-7
lines changed

server/src/main/java/org/elasticsearch/index/IndexService.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ public synchronized void updateMetaData(final IndexMetaData currentIndexMetaData
672672
// once we change the refresh interval we schedule yet another refresh
673673
// to ensure we are in a clean and predictable state.
674674
// it doesn't matter if we move from or to <code>-1</code> in both cases we want
675-
// docs to become visible immediately. This also flushes all pending indexing / search reqeusts
675+
// docs to become visible immediately. This also flushes all pending indexing / search requests
676676
// that are waiting for a refresh.
677677
threadPool.executor(ThreadPool.Names.REFRESH).execute(new AbstractRunnable() {
678678
@Override
@@ -829,17 +829,20 @@ private void sync(final Consumer<IndexShard> sync, final String source) {
829829
}
830830

831831
abstract static class BaseAsyncTask extends AbstractAsyncTask {
832+
832833
protected final IndexService indexService;
833834

834-
BaseAsyncTask(IndexService indexService, TimeValue interval) {
835+
BaseAsyncTask(final IndexService indexService, final TimeValue interval) {
835836
super(indexService.logger, indexService.threadPool, interval, true);
836837
this.indexService = indexService;
837838
rescheduleIfNecessary();
838839
}
839840

841+
@Override
840842
protected boolean mustReschedule() {
841-
// don't re-schedule if its closed or if we don't have a single shard here..., we are done
842-
return indexService.closed.get() == false;
843+
// don't re-schedule if the IndexService instance is closed or if the index is closed
844+
return indexService.closed.get() == false
845+
&& indexService.indexSettings.getIndexMetaData().getState() == IndexMetaData.State.OPEN;
843846
}
844847
}
845848

server/src/test/java/org/elasticsearch/index/IndexServiceTests.java

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.elasticsearch.index.shard.IndexShard;
3535
import org.elasticsearch.index.shard.IndexShardTestCase;
3636
import org.elasticsearch.index.translog.Translog;
37+
import org.elasticsearch.indices.IndicesService;
3738
import org.elasticsearch.plugins.Plugin;
3839
import org.elasticsearch.test.ESSingleNodeTestCase;
3940
import org.elasticsearch.test.InternalSettingsPlugin;
@@ -47,6 +48,7 @@
4748
import java.util.concurrent.atomic.AtomicReference;
4849

4950
import static org.elasticsearch.test.InternalSettingsPlugin.TRANSLOG_RETENTION_CHECK_INTERVAL_SETTING;
51+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
5052
import static org.hamcrest.core.IsEqual.equalTo;
5153

5254
/** Unit test(s) for IndexService */
@@ -109,22 +111,49 @@ protected String getThreadPool() {
109111
latch2.get().countDown();
110112
assertEquals(2, count.get());
111113

112-
113114
task = new IndexService.BaseAsyncTask(indexService, TimeValue.timeValueMillis(1000000)) {
114115
@Override
115116
protected void runInternal() {
116117

117118
}
118119
};
119120
assertTrue(task.mustReschedule());
121+
122+
// now close the index
123+
final Index index = indexService.index();
124+
assertAcked(client().admin().indices().prepareClose(index.getName()));
125+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
126+
127+
final IndexService closedIndexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
128+
assertNotSame(indexService, closedIndexService);
129+
assertFalse(task.mustReschedule());
130+
assertFalse(task.isClosed());
131+
assertEquals(1000000, task.getInterval().millis());
132+
133+
// now reopen the index
134+
assertAcked(client().admin().indices().prepareOpen(index.getName()));
135+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
136+
indexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
137+
assertNotSame(closedIndexService, indexService);
138+
139+
task = new IndexService.BaseAsyncTask(indexService, TimeValue.timeValueMillis(100000)) {
140+
@Override
141+
protected void runInternal() {
142+
143+
}
144+
};
145+
assertTrue(task.mustReschedule());
146+
assertFalse(task.isClosed());
147+
assertTrue(task.isScheduled());
148+
120149
indexService.close("simon says", false);
121150
assertFalse("no shards left", task.mustReschedule());
122151
assertTrue(task.isScheduled());
123152
task.close();
124153
assertFalse(task.isScheduled());
125154
}
126155

127-
public void testRefreshTaskIsUpdated() throws IOException {
156+
public void testRefreshTaskIsUpdated() throws Exception {
128157
IndexService indexService = createIndex("test", Settings.EMPTY);
129158
IndexService.AsyncRefreshTask refreshTask = indexService.getRefreshTask();
130159
assertEquals(1000, refreshTask.getInterval().millis());
@@ -167,12 +196,35 @@ public void testRefreshTaskIsUpdated() throws IOException {
167196
assertTrue(refreshTask.isScheduled());
168197
assertFalse(refreshTask.isClosed());
169198
assertEquals(200, refreshTask.getInterval().millis());
199+
200+
// now close the index
201+
final Index index = indexService.index();
202+
assertAcked(client().admin().indices().prepareClose(index.getName()));
203+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
204+
205+
final IndexService closedIndexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
206+
assertNotSame(indexService, closedIndexService);
207+
assertNotSame(refreshTask, closedIndexService.getRefreshTask());
208+
assertFalse(closedIndexService.getRefreshTask().mustReschedule());
209+
assertFalse(closedIndexService.getRefreshTask().isClosed());
210+
assertEquals(200, closedIndexService.getRefreshTask().getInterval().millis());
211+
212+
// now reopen the index
213+
assertAcked(client().admin().indices().prepareOpen(index.getName()));
214+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
215+
indexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
216+
assertNotSame(closedIndexService, indexService);
217+
refreshTask = indexService.getRefreshTask();
218+
assertTrue(indexService.getRefreshTask().mustReschedule());
219+
assertTrue(refreshTask.isScheduled());
220+
assertFalse(refreshTask.isClosed());
221+
170222
indexService.close("simon says", false);
171223
assertFalse(refreshTask.isScheduled());
172224
assertTrue(refreshTask.isClosed());
173225
}
174226

175-
public void testFsyncTaskIsRunning() throws IOException {
227+
public void testFsyncTaskIsRunning() throws Exception {
176228
Settings settings = Settings.builder()
177229
.put(IndexSettings.INDEX_TRANSLOG_DURABILITY_SETTING.getKey(), Translog.Durability.ASYNC).build();
178230
IndexService indexService = createIndex("test", settings);
@@ -182,6 +234,28 @@ public void testFsyncTaskIsRunning() throws IOException {
182234
assertTrue(fsyncTask.mustReschedule());
183235
assertTrue(fsyncTask.isScheduled());
184236

237+
// now close the index
238+
final Index index = indexService.index();
239+
assertAcked(client().admin().indices().prepareClose(index.getName()));
240+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
241+
242+
final IndexService closedIndexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
243+
assertNotSame(indexService, closedIndexService);
244+
assertNotSame(fsyncTask, closedIndexService.getFsyncTask());
245+
assertFalse(closedIndexService.getFsyncTask().mustReschedule());
246+
assertFalse(closedIndexService.getFsyncTask().isClosed());
247+
assertEquals(5000, closedIndexService.getFsyncTask().getInterval().millis());
248+
249+
// now reopen the index
250+
assertAcked(client().admin().indices().prepareOpen(index.getName()));
251+
awaitBusy(() -> getInstanceFromNode(IndicesService.class).hasIndex(index));
252+
indexService = getInstanceFromNode(IndicesService.class).indexServiceSafe(index);
253+
assertNotSame(closedIndexService, indexService);
254+
fsyncTask = indexService.getFsyncTask();
255+
assertTrue(indexService.getRefreshTask().mustReschedule());
256+
assertTrue(fsyncTask.isScheduled());
257+
assertFalse(fsyncTask.isClosed());
258+
185259
indexService.close("simon says", false);
186260
assertFalse(fsyncTask.isScheduled());
187261
assertTrue(fsyncTask.isClosed());

0 commit comments

Comments
 (0)