This is an automated email from the ASF dual-hosted git repository. tledkov pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push: new b7682cc IGNITE-13119 fix data race when getting index rebuild status (#7901) b7682cc is described below commit b7682cc9d49fbaa8a7392f4e41ce2916a23481b3 Author: ktkalenko <ktkale...@gridgain.com> AuthorDate: Mon Jun 8 12:15:48 2020 +0300 IGNITE-13119 fix data race when getting index rebuild status (#7901) --- .../processors/query/h2/IgniteH2Indexing.java | 9 ++- .../query/h2/GridIndexRebuildSelfTest.java | 66 +++++++++++++++++++++- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java index 48990fd..df6089c 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/IgniteH2Indexing.java @@ -1996,6 +1996,9 @@ public class IgniteH2Indexing implements GridQueryIndexing { GridFutureAdapter<Void> rebuildCacheIdxFut = new GridFutureAdapter<>(); + //to avoid possible data race + GridFutureAdapter<Void> outRebuildCacheIdxFut = new GridFutureAdapter<>(); + rebuildCacheIdxFut.listen(fut -> { Throwable err = fut.error(); @@ -2005,18 +2008,18 @@ public class IgniteH2Indexing implements GridQueryIndexing { } catch (Throwable t) { err = t; - - rebuildCacheIdxFut.onDone(t); } } if (nonNull(err)) U.error(log, "Failed to rebuild indexes for cache: " + cacheName, err); + + outRebuildCacheIdxFut.onDone(err); }); rebuildIndexesFromHash0(cctx, clo, rebuildCacheIdxFut); - return rebuildCacheIdxFut; + return outRebuildCacheIdxFut; } /** diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java index 3a6301b..8aa902b 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/GridIndexRebuildSelfTest.java @@ -37,6 +37,7 @@ import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow; import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager; import org.apache.ignite.internal.processors.query.GridQueryIndexing; import org.apache.ignite.internal.processors.query.GridQueryProcessor; +import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; import org.apache.ignite.internal.processors.query.schema.SchemaIndexCacheVisitorClosure; import org.apache.ignite.internal.util.future.GridFutureAdapter; import org.apache.ignite.internal.util.lang.GridCursor; @@ -45,6 +46,9 @@ import org.junit.Test; import static java.util.Objects.nonNull; import static java.util.Objects.requireNonNull; +import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.INDEX_FILE_NAME; +import static org.apache.ignite.internal.processors.query.QueryUtils.DFLT_SCHEMA; +import static org.apache.ignite.internal.util.IgniteUtils.delete; /** * Index rebuild after node restart test. @@ -100,6 +104,8 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { cleanPersistenceDir(); INSTANCE = this; + + BlockingIndexing.slowRebuildIdxFut = false; } /** {@inheritDoc} */ @@ -154,7 +160,7 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { stopAllGrids(); - assertTrue(U.delete(idxPath)); + assertTrue(delete(idxPath)); srv = startServer(); @@ -185,6 +191,46 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { } /** + * Test checks that there will be no data race between notifications about index rebuilding + * and an indication that index has been rebuilt. + * + * Steps: + * 1)Create a node with data filling; + * 2)Stopping a node with deletion index.bin; + * 3)Set a delay between notification and a note about index rebuilding; + * 4)Restarting node with waiting index rebuild; + * 5)Checking that index is not being rebuilt. + * + * @throws Exception if failed. + */ + @Test + public void testDataRaceWhenMarkIdxRebuild() throws Exception { + IgniteEx srv = startServer(); + + IgniteInternalCache internalCache = createAndFillTableWithIndex(srv); + + File idxFile = indexFile(internalCache); + + stopAllGrids(); + + assertTrue(delete(idxFile)); + + BlockingIndexing.slowRebuildIdxFut = true; + + srv = startServer(); + + srv.cache(CACHE_NAME).indexReadyFuture().get(); + + IgniteH2Indexing idx = (IgniteH2Indexing)srv.context().query().getIndexing(); + + GridH2Table tbl = idx.schemaManager().dataTable(DFLT_SCHEMA, CACHE_NAME); + + assertNotNull(tbl); + + assertFalse(tbl.rebuildFromHashInProgress()); + } + + /** * Check that index rebuild uses the number of threads * that specified in configuration. * @@ -207,7 +253,7 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { stopAllGrids(); - assertTrue(U.delete(idxPath)); + assertTrue(delete(idxPath)); buildIdxThreadPoolSize = buildIdxThreadCnt; @@ -260,7 +306,7 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { File cacheWorkDir = ((FilePageStoreManager)internalCache.context().shared().pageStore()) .cacheWorkDir(internalCache.configuration()); - return cacheWorkDir.toPath().resolve("index.bin").toFile(); + return cacheWorkDir.toPath().resolve(INDEX_FILE_NAME).toFile(); } /** @@ -342,6 +388,9 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { /** Flag to ignore first rebuild performed on initial node start. */ private boolean firstRbld = true; + /** Flag for slowing down {@code rebuildIdxFut} to reproduce data race. */ + static boolean slowRebuildIdxFut; + /** {@inheritDoc} */ @Override protected void rebuildIndexesFromHash0( GridCacheContext cctx, @@ -359,6 +408,17 @@ public class GridIndexRebuildSelfTest extends DynamicIndexAbstractSelfTest { else firstRbld = false; + if (slowRebuildIdxFut) { + rebuildIdxFut.listen(fut -> { + try { + U.sleep(1_000); + } + catch (IgniteInterruptedCheckedException e) { + log.error("Error while slow down " + fut, e); + } + }); + } + super.rebuildIndexesFromHash0(cctx, clo, rebuildIdxFut); } }