This is an automated email from the ASF dual-hosted git repository. agoncharuk 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 965be31 IGNITE-12489 Fix persistence corruption caused by invalid tag check (flags were not rotated for some pages) - Fixes #8358. 965be31 is described below commit 965be312a340fb6fb9f958bc4fcabda0a5e4bc16 Author: Nikita Tolstunov <ntolstu...@gmail.com> AuthorDate: Tue Nov 17 13:30:41 2020 +0300 IGNITE-12489 Fix persistence corruption caused by invalid tag check (flags were not rotated for some pages) - Fixes #8358. Signed-off-by: Alexey Goncharuk <alexey.goncha...@gmail.com> --- .../benchmarks/jmh/tree/BPlusTreeBenchmark.java | 6 + .../ignite/internal/pagemem/PageIdAllocator.java | 18 ++- .../ignite/internal/pagemem/PageIdUtils.java | 2 +- .../pagemem/store/IgnitePageStoreManager.java | 2 +- .../ignite/internal/pagemem/store/PageStore.java | 6 + .../cache/IgniteCacheOffheapManagerImpl.java | 6 +- .../processors/cache/mvcc/txlog/TxLog.java | 3 +- .../processors/cache/mvcc/txlog/TxLogTree.java | 2 + .../cache/persistence/DataStructure.java | 32 ++++- .../cache/persistence/GridCacheOffheapManager.java | 63 ++++---- .../IgniteCacheDatabaseSharedManager.java | 4 +- .../cache/persistence/IndexStorageImpl.java | 2 + .../persistence/file/FilePageStoreFactory.java | 5 +- .../persistence/file/FilePageStoreManager.java | 5 +- .../persistence/freelist/AbstractFreeList.java | 34 +++-- .../cache/persistence/freelist/CacheFreeList.java | 7 +- .../cache/persistence/freelist/PagesList.java | 124 +++++++++++++--- .../cache/persistence/metastorage/MetaStorage.java | 21 +-- .../persistence/metastorage/MetastorageTree.java | 5 +- .../UpgradePendingTreeToPerPartitionTask.java | 4 +- .../cache/persistence/pagemem/PageMemoryImpl.java | 13 +- .../persistence/partstate/GroupPartitionId.java | 12 +- .../partstorage/PartitionMetaStorageImpl.java | 6 +- .../snapshot/IgniteSnapshotManager.java | 4 +- .../cache/persistence/tree/BPlusTree.java | 9 +- .../cache/persistence/tree/io/TrackingPageIO.java | 7 +- .../cache/persistence/tree/reuse/ReuseList.java | 18 +++ .../persistence/tree/reuse/ReuseListImpl.java | 13 +- .../processors/cache/tree/CacheDataTree.java | 5 +- .../processors/cache/tree/PendingEntriesTree.java | 5 +- .../processors/cache/verify/IdleVerifyUtility.java | 14 +- ...IoStatisticsMetricsLocalMXBeanImplSelfTest.java | 2 +- .../internal/pagemem/impl/PageIdUtilsSelfTest.java | 41 ++++-- .../persistence/PendingTreeCorruptionTest.java | 159 +++++++++++++++++++++ .../db/CheckpointBufferDeadlockTest.java | 12 ++ .../database/BPlusTreeFakeReuseSelfTest.java | 6 + .../database/BPlusTreeReuseSelfTest.java | 3 +- .../processors/database/BPlusTreeSelfTest.java | 1 + .../processors/database/CacheFreeListSelfTest.java | 3 +- .../ignite/testsuites/IgnitePdsTestSuite4.java | 3 + .../processors/query/h2/IgniteH2Indexing.java | 2 + .../processors/query/h2/database/H2Tree.java | 2 + 42 files changed, 559 insertions(+), 132 deletions(-) diff --git a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java index 7a35430..af843cb 100644 --- a/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java +++ b/modules/benchmarks/src/main/java/org/apache/ignite/internal/benchmarks/jmh/tree/BPlusTreeBenchmark.java @@ -104,6 +104,11 @@ public class BPlusTreeBenchmark extends JmhAbstractBenchmark { } /** {@inheritDoc} */ + @Override public long initRecycledPage(long pageId, byte flag, PageIO initIO) throws IgniteCheckedException { + return pageId; + } + + /** {@inheritDoc} */ @Override public long recycledPagesCount() throws IgniteCheckedException { return deque.size(); } @@ -186,6 +191,7 @@ public class BPlusTreeBenchmark extends JmhAbstractBenchmark { reuseList, new IOVersions<>(new LongInnerIO()), new IOVersions<>(new LongLeafIO()), + PageIdAllocator.FLAG_IDX, null, null ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdAllocator.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdAllocator.java index 7395695..f97ada7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdAllocator.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdAllocator.java @@ -25,12 +25,26 @@ import static org.apache.ignite.internal.pagemem.PageIdUtils.pageId; * Allocates page ID's. */ public interface PageIdAllocator { - /** */ + /** + * Flag for Data page. + * Also used by partition meta and tracking pages. + * This type doesn't use Page ID rotation mechanizm. + */ public static final byte FLAG_DATA = 1; - /** */ + /** + * Flag for index page. + * Also used by internal structure in inmemory caches. + * This type uses Page ID rotation mechanizm. + */ public static final byte FLAG_IDX = 2; + /** + * Flag for internal structure page. + * This type uses Page ID rotation mechanizm. + */ + public static final byte FLAG_AUX = 4; + /** Max partition ID that can be used by affinity. */ public static final int MAX_PARTITION_ID = 65500; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java index c48f4a8..395586c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/PageIdUtils.java @@ -108,7 +108,7 @@ public final class PageIdUtils { * @return Page ID. */ public static long pageId(long link) { - return flag(link) == PageIdAllocator.FLAG_IDX ? link : link & PAGE_ID_MASK; + return flag(link) == PageIdAllocator.FLAG_DATA ? link & PAGE_ID_MASK : link; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java index 50af2a4..da606a68 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/IgnitePageStoreManager.java @@ -162,7 +162,7 @@ public interface IgnitePageStoreManager extends GridCacheSharedManager, IgniteCh * Allocates a page for the given page space. * * @param grpId Cache group ID. - * @param partId Partition ID. Used only if {@code flags} is equal to {@link PageMemory#FLAG_DATA}. + * @param partId Partition ID. Used only if {@code flags} is not equal to {@link PageMemory#FLAG_IDX}. * @param flags Page allocation flags. * @return Allocated page ID. * @throws IgniteCheckedException If IO exception occurred while allocating a page ID. diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java index 1d9e501..528c682 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/store/PageStore.java @@ -26,6 +26,12 @@ import org.apache.ignite.internal.processors.cache.persistence.StorageException; * Persistent store of pages. */ public interface PageStore extends Closeable { + /** Type for regular affinity partitions. */ + public static byte TYPE_DATA = 1; + + /** Type for index partition. */ + public static byte TYPE_IDX = 2; + /** * @param lsnr Page write listener to set. */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java index 4743d89..024287f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java @@ -237,7 +237,8 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager rootPage, grp.reuseList(), true, - lsnr + lsnr, + FLAG_IDX ); } } @@ -1291,7 +1292,8 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager rowStore, rootPage, true, - lsnr + lsnr, + FLAG_IDX ); return new CacheDataStoreImpl(p, rowStore, dataTree, () -> pendingEntries, grp, busyLock, log); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLog.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLog.java index 0e98b8d..8cf61a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLog.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLog.java @@ -184,7 +184,8 @@ public class TxLog implements CheckpointListener { isNew, txLogReuseListLockLsnr, ctx, - null + null, + FLAG_IDX ); tree = new TxLogTree( diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java index c850928..a4df8bd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/mvcc/txlog/TxLogTree.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.mvcc.txlog; import java.util.concurrent.atomic.AtomicLong; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; import org.apache.ignite.internal.processors.cache.persistence.tree.BPlusTree; @@ -61,6 +62,7 @@ public class TxLogTree extends BPlusTree<TxKey, TxRow> { reuseList, TxLogInnerIO.VERSIONS, TxLogLeafIO.VERSIONS, + PageIdAllocator.FLAG_IDX, failureProcessor, lockLsnr ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java index 68fd48e..8814d18 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStructure.java @@ -70,6 +70,9 @@ public abstract class DataStructure { /** */ protected final PageIoResolver pageIoRslvr; + /** */ + protected final byte pageFlag; + /** * @param cacheGrpId Cache group ID. * @param grpName Cache group name. @@ -77,6 +80,7 @@ public abstract class DataStructure { * @param wal Write ahead log manager. * @param lockLsnr Page lock listener. * @param pageIoRslvr Page IO resolver. + * @param pageFlag Default flag value for allocated pages. */ public DataStructure( int cacheGrpId, @@ -84,7 +88,8 @@ public abstract class DataStructure { PageMemory pageMem, IgniteWriteAheadLogManager wal, PageLockListener lockLsnr, - PageIoResolver pageIoRslvr + PageIoResolver pageIoRslvr, + byte pageFlag ) { assert pageMem != null; @@ -94,6 +99,7 @@ public abstract class DataStructure { this.wal = wal; this.lockLsnr = lockLsnr == null ? NOOP_LSNR : lockLsnr; this.pageIoRslvr = pageIoRslvr; + this.pageFlag = pageFlag; } /** @@ -131,16 +137,30 @@ public abstract class DataStructure { * @throws IgniteCheckedException If failed. */ protected final long allocatePage(ReuseBag bag, boolean useRecycled) throws IgniteCheckedException { - long pageId = bag != null ? bag.pollFreePage() : 0; + long pageId = 0; + + if (useRecycled && reuseList != null) { + pageId = bag != null ? bag.pollFreePage() : 0; + + if (pageId == 0) + pageId = reuseList.takeRecycledPage(); - if (pageId == 0 && useRecycled && reuseList != null) - pageId = reuseList.takeRecycledPage(); + // Recycled. "pollFreePage" result should be reinitialized to move rotatedId to itemId. + if (pageId != 0) + pageId = reuseList.initRecycledPage(pageId, pageFlag, null); + } if (pageId == 0) pageId = allocatePageNoReuse(); assert pageId != 0; + assert PageIdUtils.flag(pageId) == FLAG_IDX && PageIdUtils.partId(pageId) == INDEX_PARTITION || + PageIdUtils.flag(pageId) != FLAG_IDX && PageIdUtils.partId(pageId) <= MAX_PARTITION_ID : + PageIdUtils.toDetailString(pageId); + + assert PageIdUtils.flag(pageId) != FLAG_DATA || PageIdUtils.itemId(pageId) == 0 : PageIdUtils.toDetailString(pageId); + return pageId; } @@ -160,7 +180,7 @@ public abstract class DataStructure { */ protected final long acquirePage(long pageId, IoStatisticsHolder statHolder) throws IgniteCheckedException { assert PageIdUtils.flag(pageId) == FLAG_IDX && PageIdUtils.partId(pageId) == INDEX_PARTITION || - PageIdUtils.flag(pageId) == FLAG_DATA && PageIdUtils.partId(pageId) <= MAX_PARTITION_ID : + PageIdUtils.flag(pageId) != FLAG_IDX && PageIdUtils.partId(pageId) <= MAX_PARTITION_ID : U.hexLong(pageId) + " flag=" + PageIdUtils.flag(pageId) + " part=" + PageIdUtils.partId(pageId); return pageMem.acquirePage(grpId, pageId, statHolder); @@ -403,7 +423,7 @@ public abstract class DataStructure { int rotatedIdPart = PageIO.getRotatedIdPart(pageAddr); if (rotatedIdPart != 0) { - recycled = PageIdUtils.link(pageId, rotatedIdPart > MAX_ITEMID_NUM ? 1 : rotatedIdPart); + recycled = PageIdUtils.link(pageId, rotatedIdPart); PageIO.setRotatedIdPart(pageAddr, 0); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java index cb7b6dc..ad062a8 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java @@ -206,7 +206,8 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple reuseListRoot.isAllocated(), diagnosticMgr.pageLockTracker().createPageLockTracker(reuseListName), ctx.kernalContext(), - pageListCacheLimit + pageListCacheLimit, + PageIdAllocator.FLAG_IDX ); RootPage metastoreRoot = metas.treeRoot; @@ -828,7 +829,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple boolean init = cntrsPageId == 0; if (init && !sizes.isEmpty()) - cntrsPageId = pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + cntrsPageId = pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); long nextId = cntrsPageId; int written = 0; @@ -859,7 +860,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple if (written != items && (init = nextId == 0)) { //allocate new counters page - nextId = pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + nextId = pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); partCntrIo.setNextCountersPageId(curAddr, nextId); } } @@ -1959,13 +1960,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple reuseRoot.isAllocated(), ctx.diagnostic().pageLockTracker().createPageLockTracker(freeListName), ctx.kernalContext(), - pageListCacheLimit + pageListCacheLimit, + PageIdAllocator.FLAG_AUX ) { /** {@inheritDoc} */ @Override protected long allocatePageNoReuse() throws IgniteCheckedException { assert ctx.database().checkpointLockIsHeldByThread(); - return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); } }; @@ -1984,13 +1986,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple partMetastoreReuseListRoot.isAllocated(), ctx.diagnostic().pageLockTracker().createPageLockTracker(partitionMetaStoreName), ctx.kernalContext(), - pageListCacheLimit + pageListCacheLimit, + PageIdAllocator.FLAG_AUX ) { /** {@inheritDoc} */ @Override protected long allocatePageNoReuse() throws IgniteCheckedException { assert ctx.database().checkpointLockIsHeldByThread(); - return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); } }; @@ -2007,13 +2010,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple rowStore, treeRoot.pageId().pageId(), treeRoot.isAllocated(), - ctx.diagnostic().pageLockTracker().createPageLockTracker(dataTreeName) + ctx.diagnostic().pageLockTracker().createPageLockTracker(dataTreeName), + PageIdAllocator.FLAG_AUX ) { /** {@inheritDoc} */ @Override protected long allocatePageNoReuse() throws IgniteCheckedException { assert ctx.database().checkpointLockIsHeldByThread(); - return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); } }; @@ -2028,13 +2032,14 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple pendingTreeRoot.pageId().pageId(), freeList, pendingTreeRoot.isAllocated(), - ctx.diagnostic().pageLockTracker().createPageLockTracker(pendingEntriesTreeName) + ctx.diagnostic().pageLockTracker().createPageLockTracker(pendingEntriesTreeName), + PageIdAllocator.FLAG_AUX ) { /** {@inheritDoc} */ @Override protected long allocatePageNoReuse() throws IgniteCheckedException { assert ctx.database().checkpointLockIsHeldByThread(); - return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_DATA); + return pageMem.allocatePage(grpId, partId, PageIdAllocator.FLAG_AUX); } }; @@ -2185,15 +2190,15 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple io.initNewPage(pageAddr, partMetaId, pageMem.realPageSize(grpId)); - treeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); - reuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); - pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); - partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); + treeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); + reuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); + pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); + partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); - assert PageIdUtils.flag(treeRoot) == PageMemory.FLAG_DATA; - assert PageIdUtils.flag(reuseListRoot) == PageMemory.FLAG_DATA; - assert PageIdUtils.flag(pendingTreeRoot) == PageMemory.FLAG_DATA; - assert PageIdUtils.flag(partMetaStoreReuseListRoot) == PageMemory.FLAG_DATA; + assert PageIdUtils.flag(treeRoot) == PageMemory.FLAG_AUX; + assert PageIdUtils.flag(reuseListRoot) == PageMemory.FLAG_AUX; + assert PageIdUtils.flag(pendingTreeRoot) == PageMemory.FLAG_AUX; + assert PageIdUtils.flag(partMetaStoreReuseListRoot) == PageMemory.FLAG_AUX; io.setTreeRoot(pageAddr, treeRoot); io.setReuseListRoot(pageAddr, reuseListRoot); @@ -2228,8 +2233,8 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple ((PagePartitionMetaIOV3)io).upgradePage(pageAddr); - pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); - partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); + pendingTreeRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); + partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); io.setPendingTreeRoot(pageAddr, pendingTreeRoot); io.setPartitionMetaStoreReuseListRoot(pageAddr, partMetaStoreReuseListRoot); @@ -2247,7 +2252,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple partMetaStoreReuseListRoot = io.getPartitionMetaStoreReuseListRoot(pageAddr); if (partMetaStoreReuseListRoot == 0) { - partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_DATA); + partMetaStoreReuseListRoot = pageMem.allocatePage(grpId, partId, PageMemory.FLAG_AUX); if (PageHandler.isWalDeltaRecordNeeded(pageMem, grpId, partMetaId, partMetaPage, wal, null)) { @@ -2259,19 +2264,23 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple } } - if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_AUX + && PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong tree root page id flag: treeRoot=" + U.hexLong(treeRoot) + ", part=" + partId + ", grpId=" + grpId); - if (PageIdUtils.flag(reuseListRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(reuseListRoot) != PageMemory.FLAG_AUX + && PageIdUtils.flag(reuseListRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong reuse list root page id flag: reuseListRoot=" + U.hexLong(reuseListRoot) + ", part=" + partId + ", grpId=" + grpId); - if (PageIdUtils.flag(pendingTreeRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(pendingTreeRoot) != PageMemory.FLAG_AUX + && PageIdUtils.flag(pendingTreeRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong pending tree root page id flag: reuseListRoot=" - + U.hexLong(reuseListRoot) + ", part=" + partId + ", grpId=" + grpId); + + U.hexLong(pendingTreeRoot) + ", part=" + partId + ", grpId=" + grpId); - if (PageIdUtils.flag(partMetaStoreReuseListRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(partMetaStoreReuseListRoot) != PageMemory.FLAG_AUX + && PageIdUtils.flag(partMetaStoreReuseListRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong partition meta store list root page id flag: partMetaStoreReuseListRoot=" + U.hexLong(partMetaStoreReuseListRoot) + ", part=" + partId + ", grpId=" + grpId); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java index 9eb02fb..bfadeb2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IgniteCacheDatabaseSharedManager.java @@ -55,6 +55,7 @@ import org.apache.ignite.internal.mem.DirectMemoryRegion; import org.apache.ignite.internal.mem.IgniteOutOfMemoryException; import org.apache.ignite.internal.mem.file.MappedFileMemoryProvider; import org.apache.ignite.internal.mem.unsafe.UnsafeMemoryProvider; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.impl.PageMemoryNoStoreImpl; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -315,7 +316,8 @@ public class IgniteCacheDatabaseSharedManager extends GridCacheSharedManagerAdap true, lsnr, cctx.kernalContext(), - null + null, + PageIdAllocator.FLAG_IDX ); freeListMap.put(memPlcCfg.getName(), freeList); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java index 1be0b97..94f7feb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/IndexStorageImpl.java @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicLong; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.internal.pagemem.FullPageId; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.PageUtils; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; @@ -267,6 +268,7 @@ public class IndexStorageImpl implements IndexStorage { reuseList, innerIos, leafIos, + PageIdAllocator.FLAG_IDX, failureProcessor, lockLsnr ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java index ae92359..53e9fe9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreFactory.java @@ -21,7 +21,6 @@ import java.io.File; import java.nio.file.Path; import java.util.function.LongConsumer; import org.apache.ignite.IgniteCheckedException; -import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.store.PageStore; import org.apache.ignite.lang.IgniteOutClosure; @@ -32,7 +31,7 @@ public interface FilePageStoreFactory { /** * Creates instance of PageStore based on given file. * - * @param type Data type, can be {@link PageIdAllocator#FLAG_IDX} or {@link PageIdAllocator#FLAG_DATA}. + * @param type Data type, can be {@link PageStore#TYPE_IDX} or {@link PageStore#TYPE_DATA}. * @param file File Page store file. * @param allocatedTracker metrics updater. * @return page store @@ -46,7 +45,7 @@ public interface FilePageStoreFactory { /** * Creates instance of PageStore based on file path provider. * - * @param type Data type, can be {@link PageIdAllocator#FLAG_IDX} or {@link PageIdAllocator#FLAG_DATA} + * @param type Data type, can be {@link PageStore#TYPE_IDX} or {@link PageStore#TYPE_DATA} * @param pathProvider File Page store path provider. * @param allocatedTracker metrics updater * @return page store diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java index 7152b1e..3f5f8a9 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/file/FilePageStoreManager.java @@ -64,7 +64,6 @@ import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.client.util.GridConcurrentHashSet; import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; -import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager; import org.apache.ignite.internal.pagemem.store.PageStore; import org.apache.ignite.internal.pagemem.store.PageStoreCollection; @@ -741,7 +740,7 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen PageStore idxStore = pageStoreFactory.createPageStore( - PageMemory.FLAG_IDX, + PageStore.TYPE_IDX, idxFile, allocatedTracker); @@ -752,7 +751,7 @@ public class FilePageStoreManager extends GridCacheSharedManagerAdapter implemen PageStore partStore = pageStoreFactory.createPageStore( - PageMemory.FLAG_DATA, + PageStore.TYPE_DATA, () -> getPartitionFilePath(cacheWorkDir, p), allocatedTracker); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java index b46417b..7ccaf37 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/AbstractFreeList.java @@ -50,6 +50,8 @@ import org.apache.ignite.internal.util.GridCursorIteratorWrapper; import org.apache.ignite.internal.util.lang.GridCursor; import org.apache.ignite.internal.util.typedef.internal.U; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA; + /** */ public abstract class AbstractFreeList<T extends Storable> extends PagesList implements FreeList<T>, ReuseList { @@ -425,6 +427,7 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp * @param wal Write ahead log manager. * @param metaPageId Metadata page ID. * @param initNew {@code True} if new metadata should be initialized. + * @param pageFlag Default flag value for allocated pages. * @throws IgniteCheckedException If failed. */ public AbstractFreeList( @@ -438,9 +441,10 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp boolean initNew, PageLockListener lockLsnr, GridKernalContext ctx, - AtomicLong pageListCacheLimit + AtomicLong pageListCacheLimit, + byte pageFlag ) throws IgniteCheckedException { - super(cacheId, name, memPlc.pageMemory(), BUCKETS, wal, metaPageId, lockLsnr, ctx); + super(cacheId, name, memPlc.pageMemory(), BUCKETS, wal, metaPageId, lockLsnr, ctx, pageFlag); rmvRow = new RemoveRowHandler(cacheId == 0); @@ -565,9 +569,8 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp */ private long allocateDataPage(int part) throws IgniteCheckedException { assert part <= PageIdAllocator.MAX_PARTITION_ID; - assert part != PageIdAllocator.INDEX_PARTITION; - return pageMem.allocatePage(grpId, part, PageIdAllocator.FLAG_DATA); + return pageMem.allocatePage(grpId, part, FLAG_DATA); } /** {@inheritDoc} */ @@ -719,17 +722,23 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp } if (pageId == 0L) { // Handle reuse bucket. - pageId = reuseList == this ? - takeEmptyPage(REUSE_BUCKET, row.ioVersions(), statHolder) : reuseList.takeRecycledPage(); + if (reuseList == this) + pageId = takeEmptyPage(REUSE_BUCKET, row.ioVersions(), statHolder); + else { + pageId = reuseList.takeRecycledPage(); + + if (pageId != 0) + pageId = reuseList.initRecycledPage(pageId, FLAG_DATA, row.ioVersions().latest()); + } } if (pageId == 0L) return 0; - if (PageIdUtils.tag(pageId) != PageIdAllocator.FLAG_DATA) // Page is taken from reuse bucket. - return initReusedPage(row, pageId, statHolder); - else // Page is taken from free space bucket. For in-memory mode partition must be changed. - return PageIdUtils.changePartitionId(pageId, row.partition()); + assert PageIdUtils.flag(pageId) == FLAG_DATA + : "rowVersions=" + row.ioVersions() + ", pageId=" + PageIdUtils.toDetailString(pageId); + + return PageIdUtils.changePartitionId(pageId, row.partition()); } /** @@ -912,6 +921,11 @@ public abstract class AbstractFreeList<T extends Storable> extends PagesList imp } /** {@inheritDoc} */ + @Override public long initRecycledPage(long pageId, byte flag, PageIO initIO) throws IgniteCheckedException { + return initRecycledPage0(pageId, flag, initIO); + } + + /** {@inheritDoc} */ @Override public long recycledPagesCount() throws IgniteCheckedException { assert reuseList == this : "not allowed to be a reuse list"; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeList.java index a4a4363..fdf50c9 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeList.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/CacheFreeList.java @@ -41,6 +41,7 @@ public class CacheFreeList extends AbstractFreeList<CacheDataRow> { * @param wal Wal. * @param metaPageId Meta page id. * @param initNew Initialize new. + * @param pageFlag Default flag value for allocated pages. */ public CacheFreeList( int cacheId, @@ -52,7 +53,8 @@ public class CacheFreeList extends AbstractFreeList<CacheDataRow> { boolean initNew, PageLockListener lockLsnr, GridKernalContext ctx, - AtomicLong pageListCacheLimit + AtomicLong pageListCacheLimit, + byte pageFlag ) throws IgniteCheckedException { super( cacheId, @@ -65,7 +67,8 @@ public class CacheFreeList extends AbstractFreeList<CacheDataRow> { initNew, lockLsnr, ctx, - pageListCacheLimit + pageListCacheLimit, + pageFlag ); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java index 530690e..bf66500 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java @@ -32,6 +32,7 @@ import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.managers.communication.GridIoPolicy; import org.apache.ignite.internal.metric.IoStatisticsHolder; import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; @@ -43,6 +44,7 @@ import org.apache.ignite.internal.pagemem.wal.record.delta.PagesListInitNewPageR import org.apache.ignite.internal.pagemem.wal.record.delta.PagesListRemovePageRecord; import org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord; import org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetPreviousRecord; +import org.apache.ignite.internal.pagemem.wal.record.delta.RecycleRecord; import org.apache.ignite.internal.pagemem.wal.record.delta.RotatedIdPartRecord; import org.apache.ignite.internal.processors.cache.persistence.DataStructure; import org.apache.ignite.internal.processors.cache.persistence.freelist.io.PagesListMetaIO; @@ -65,7 +67,12 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA; import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_IDX; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.INDEX_PARTITION; import static org.apache.ignite.internal.pagemem.PageIdUtils.MAX_ITEMID_NUM; +import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO.T_DATA; +import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO.T_DATA_METASTORAGE; +import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO.T_DATA_PART; +import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO.T_META; import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO.getPageId; import static org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIoResolver.DEFAULT_PAGE_IO_RESOLVER; @@ -201,6 +208,7 @@ public abstract class PagesList extends DataStructure { * @param buckets Number of buckets. * @param wal Write ahead log manager. * @param metaPageId Metadata page ID. + * @param pageFlag Default flag value for allocated pages. */ protected PagesList( int cacheId, @@ -210,9 +218,10 @@ public abstract class PagesList extends DataStructure { IgniteWriteAheadLogManager wal, long metaPageId, PageLockListener lockLsnr, - GridKernalContext ctx + GridKernalContext ctx, + byte pageFlag ) { - super(cacheId, null, pageMem, wal, lockLsnr, DEFAULT_PAGE_IO_RESOLVER); + super(cacheId, null, pageMem, wal, lockLsnr, DEFAULT_PAGE_IO_RESOLVER, pageFlag); this.name = name; this.buckets = buckets; @@ -1305,6 +1314,8 @@ public abstract class PagesList extends DataStructure { ", pageId=" + pageId + ']'); } + assert !isReuseBucket(bucket) : "reuse bucket detected"; + return pageId; } @@ -1372,7 +1383,15 @@ public abstract class PagesList extends DataStructure { PageIdUtils.itemId(pageId) > 0 && PageIdUtils.itemId(pageId) <= MAX_ITEMID_NUM : "Incorrectly recycled pageId in reuse bucket: " + U.hexLong(pageId); - dataPageId = pageId; + if (isReuseBucket(bucket)) { + byte flag = getFlag(initIoVers); + + PageIO initIO = initIoVers == null ? null : initIoVers.latest(); + + dataPageId = initRecycledPage0(pageId, flag, initIO); + } + else + dataPageId = pageId; if (io.isEmpty(tailAddr)) { long prevId = io.getPreviousId(tailAddr); @@ -1410,12 +1429,11 @@ public abstract class PagesList extends DataStructure { decrementBucketSize(bucket); - if (initIoVers != null) { - int partId = PageIdUtils.partId(tailId); + byte flag = getFlag(initIoVers); - dataPageId = initReusedPage(tailId, tailPage, tailAddr, partId, FLAG_DATA, initIoVers.latest()); - } else - dataPageId = recyclePage(tailId, tailPage, tailAddr, null); + PageIO pageIO = initIoVers != null ? initIoVers.latest() : null; + + dataPageId = initReusedPage(tailId, tailPage, tailAddr, PageIdUtils.partId(tailId), flag, pageIO); dirty = true; } @@ -1450,7 +1468,56 @@ public abstract class PagesList extends DataStructure { } /** - * Reused page must obtain correctly assembled page id, then initialized by proper {@link PageIO} instance and + * @param initIoVers Optional IO versions list that will be used later to init the page. + * @return {@link PageIdAllocator#FLAG_DATA} for cache group metas and data pages, + * {@link #pageFlag} otherwise. + */ + private byte getFlag(IOVersions<?> initIoVers) { + if (initIoVers != null) { + PageIO pageIO = initIoVers.latest(); + + switch (pageIO.getType()) { + case T_META: + case T_DATA: + case T_DATA_PART: + case T_DATA_METASTORAGE: + return FLAG_DATA; + } + } + + return pageFlag; + } + + /** + * Create new page id and update page content accordingly if it's necessary. + * + * @param pageId Id of the recycled page from reuse bucket. + * @param flag New flag for the page. + * @return New page id. + * @throws IgniteCheckedException If failed. + * + * @see PagesList#initReusedPage(long, long, long, int, byte, PageIO) + */ + protected long initRecycledPage0(long pageId, byte flag, PageIO initIO) throws IgniteCheckedException { + long page = pageMem.acquirePage(grpId, pageId); + + try { + long pageAddr = pageMem.writeLock(grpId, pageId, page); + + try { + return initReusedPage(pageId, page, pageAddr, PageIdUtils.partId(pageId), flag, initIO); + } + finally { + pageMem.writeUnlock(grpId, pageId, page, null, true); + } + } + finally { + pageMem.releasePage(grpId, pageId, page); + } + } + + /** + * Reused page must obtain correctly assaembled page id, then initialized by proper {@link PageIO} instance and * non-zero {@code itemId} of reused page id must be saved into special place. * * @param reusedPageId Reused page id. @@ -1464,30 +1531,47 @@ public abstract class PagesList extends DataStructure { */ protected final long initReusedPage(long reusedPageId, long reusedPage, long reusedPageAddr, int partId, byte flag, PageIO initIo) throws IgniteCheckedException { + if (flag == FLAG_IDX) + partId = INDEX_PARTITION; long newPageId = PageIdUtils.pageId(partId, flag, PageIdUtils.pageIndex(reusedPageId)); - initIo.initNewPage(reusedPageAddr, newPageId, pageSize()); - boolean needWalDeltaRecord = needWalDeltaRecord(reusedPageId, reusedPage, null); - if (needWalDeltaRecord) { - assert PageIdUtils.partId(reusedPageId) == PageIdUtils.partId(newPageId) : - "Partition consistency failure: " + - "newPageId=" + Long.toHexString(newPageId) + " (newPartId: " + PageIdUtils.partId(newPageId) + ") " + - "reusedPageId=" + Long.toHexString(reusedPageId) + " (partId: " + PageIdUtils.partId(reusedPageId) + ")"; + if (initIo != null) { + initIo.initNewPage(reusedPageAddr, newPageId, pageSize()); + + if (needWalDeltaRecord) { + assert PageIdUtils.partId(reusedPageId) == PageIdUtils.partId(newPageId) : + "Partition consistency failure: " + + "newPageId=" + Long.toHexString(newPageId) + " (newPartId: " + PageIdUtils.partId(newPageId) + ") " + + "reusedPageId=" + Long.toHexString(reusedPageId) + " (partId: " + PageIdUtils.partId(reusedPageId) + ")"; - wal.log(new InitNewPageRecord(grpId, reusedPageId, initIo.getType(), - initIo.getVersion(), newPageId)); + wal.log(new InitNewPageRecord(grpId, reusedPageId, initIo.getType(), + initIo.getVersion(), newPageId)); + } } int itemId = PageIdUtils.itemId(reusedPageId); if (itemId != 0) { - PageIO.setRotatedIdPart(reusedPageAddr, itemId); + if (flag == FLAG_DATA) { + PageIO.setRotatedIdPart(reusedPageAddr, itemId); + + if (needWalDeltaRecord) + wal.log(new RotatedIdPartRecord(grpId, newPageId, itemId)); + } + else + newPageId = PageIdUtils.link(newPageId, itemId); + } + + long storedPageId = getPageId(reusedPageAddr); + + if (storedPageId != newPageId) { + PageIO.setPageId(reusedPageAddr, newPageId); if (needWalDeltaRecord) - wal.log(new RotatedIdPartRecord(grpId, newPageId, itemId)); + wal.log(new RecycleRecord(grpId, storedPageId, newPageId)); } return newPageId; diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java index b88cad8..2c20a02 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetaStorage.java @@ -72,7 +72,7 @@ import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.marshaller.jdk.JdkMarshaller; import org.jetbrains.annotations.NotNull; -import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_AUX; import static org.apache.ignite.internal.pagemem.PageIdAllocator.OLD_METASTORE_PARTITION; /** @@ -266,10 +266,11 @@ public class MetaStorage implements CheckpointListener, ReadWriteMetastorage { reuseListRoot.isAllocated(), diagnosticMgr.pageLockTracker().createPageLockTracker(freeListName), cctx.kernalContext(), - null + null, + FLAG_AUX ) { @Override protected long allocatePageNoReuse() throws IgniteCheckedException { - return pageMem.allocatePage(grpId, partId, FLAG_DATA); + return pageMem.allocatePage(grpId, partId, FLAG_AUX); } }; @@ -487,11 +488,13 @@ public class MetaStorage implements CheckpointListener, ReadWriteMetastorage { /** */ private void checkRootsPageIdFlag(long treeRoot, long reuseListRoot) throws StorageException { - if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_AUX && + PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong tree root page id flag: treeRoot=" + U.hexLong(treeRoot) + ", METASTORAGE_CACHE_ID=" + METASTORAGE_CACHE_ID); - if (PageIdUtils.flag(reuseListRoot) != PageMemory.FLAG_DATA) + if (PageIdUtils.flag(treeRoot) != PageMemory.FLAG_AUX && + PageIdUtils.flag(treeRoot) != PageMemory.FLAG_DATA) throw new StorageException("Wrong reuse list root page id flag: reuseListRoot=" + U.hexLong(reuseListRoot) + ", METASTORAGE_CACHE_ID=" + METASTORAGE_CACHE_ID); } @@ -550,11 +553,11 @@ public class MetaStorage implements CheckpointListener, ReadWriteMetastorage { //MetaStorage never encrypted so realPageSize == pageSize. io.initNewPage(pageAddr, partMetaId, pageMem.pageSize()); - treeRoot = pageMem.allocatePage(METASTORAGE_CACHE_ID, partId, PageMemory.FLAG_DATA); - reuseListRoot = pageMem.allocatePage(METASTORAGE_CACHE_ID, partId, PageMemory.FLAG_DATA); + treeRoot = pageMem.allocatePage(METASTORAGE_CACHE_ID, partId, PageMemory.FLAG_AUX); + reuseListRoot = pageMem.allocatePage(METASTORAGE_CACHE_ID, partId, PageMemory.FLAG_AUX); - assert PageIdUtils.flag(treeRoot) == PageMemory.FLAG_DATA; - assert PageIdUtils.flag(reuseListRoot) == PageMemory.FLAG_DATA; + assert PageIdUtils.flag(treeRoot) == PageMemory.FLAG_AUX; + assert PageIdUtils.flag(reuseListRoot) == PageMemory.FLAG_AUX; io.setTreeRoot(pageAddr, treeRoot); io.setReuseListRoot(pageAddr, reuseListRoot); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java index afce4e2..7b1bb6e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/metastorage/MetastorageTree.java @@ -28,7 +28,7 @@ import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLoc import org.apache.ignite.internal.processors.failure.FailureProcessor; import org.jetbrains.annotations.Nullable; -import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_AUX; /** * @@ -79,6 +79,7 @@ public class MetastorageTree extends BPlusTree<MetastorageRow, MetastorageDataRo reuseList, MetastorageBPlusIO.INNER_IO_VERSIONS, MetastorageBPlusIO.LEAF_IO_VERSIONS, + FLAG_AUX, failureProcessor, lockLsnr ); @@ -115,6 +116,6 @@ public class MetastorageTree extends BPlusTree<MetastorageRow, MetastorageDataRo /** {@inheritDoc} */ @Override protected long allocatePageNoReuse() throws IgniteCheckedException { - return pageMem.allocatePage(grpId, partId, FLAG_DATA); + return pageMem.allocatePage(grpId, partId, FLAG_AUX); } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/migration/UpgradePendingTreeToPerPartitionTask.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/migration/UpgradePendingTreeToPerPartitionTask.java index 4499980..6d06673 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/migration/UpgradePendingTreeToPerPartitionTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/migration/UpgradePendingTreeToPerPartitionTask.java @@ -22,6 +22,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.IgniteException; import org.apache.ignite.IgniteLogger; import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.processors.cache.CacheGroupContext; @@ -150,7 +151,8 @@ public class UpgradePendingTreeToPerPartitionTask implements IgniteCallable<Bool pendingRootPage.pageId().pageId(), ((GridCacheOffheapManager)grp.offheap()).reuseListForIndex(null), false, - null + null, + PageIdAllocator.FLAG_IDX ); } finally { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java index 4872c6d..c6d4d87 100755 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/pagemem/PageMemoryImpl.java @@ -514,7 +514,7 @@ public class PageMemoryImpl implements PageMemoryEx { /** {@inheritDoc} */ @Override public long allocatePage(int grpId, int partId, byte flags) throws IgniteCheckedException { - assert flags == PageIdAllocator.FLAG_DATA && partId <= PageIdAllocator.MAX_PARTITION_ID || + assert flags != PageIdAllocator.FLAG_IDX && partId <= PageIdAllocator.MAX_PARTITION_ID || flags == PageIdAllocator.FLAG_IDX && partId == PageIdAllocator.INDEX_PARTITION : "flags = " + flags + ", partId = " + partId; @@ -536,12 +536,15 @@ public class PageMemoryImpl implements PageMemoryEx { DelayedDirtyPageStoreWrite delayedWriter = delayedPageReplacementTracker != null ? delayedPageReplacementTracker.delayedPageWrite() : null; - FullPageId fullId = new FullPageId(pageId, grpId); - seg.writeLock().lock(); - boolean isTrackingPage = - changeTracker != null && trackingIO.trackingPageFor(pageId, realPageSize(grpId)) == pageId; + boolean isTrackingPage = changeTracker != null && + PageIdUtils.pageIndex(trackingIO.trackingPageFor(pageId, realPageSize(grpId))) == PageIdUtils.pageIndex(pageId); + + if (isTrackingPage && PageIdUtils.flag(pageId) == PageIdAllocator.FLAG_AUX) + pageId = PageIdUtils.pageId(PageIdUtils.partId(pageId), PageIdAllocator.FLAG_DATA, PageIdUtils.pageIndex(pageId)); + + FullPageId fullId = new FullPageId(pageId, grpId); try { long relPtr = seg.loadedPages.get( diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/GroupPartitionId.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/GroupPartitionId.java index c236827..275fb55 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/GroupPartitionId.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/GroupPartitionId.java @@ -20,7 +20,7 @@ package org.apache.ignite.internal.processors.cache.persistence.partstate; import org.apache.ignite.internal.pagemem.FullPageId; import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; -import org.apache.ignite.internal.pagemem.PageMemory; +import org.apache.ignite.internal.pagemem.store.PageStore; import org.apache.ignite.internal.util.typedef.internal.S; import org.jetbrains.annotations.NotNull; @@ -53,7 +53,15 @@ public class GroupPartitionId implements Comparable<GroupPartitionId> { * @return flag to be used for partition */ public static byte getFlagByPartId(final int partId) { - return partId == PageIdAllocator.INDEX_PARTITION ? PageMemory.FLAG_IDX : PageMemory.FLAG_DATA; + return partId == PageIdAllocator.INDEX_PARTITION ? PageIdAllocator.FLAG_IDX : PageIdAllocator.FLAG_DATA; + } + + /** + * @param partId Partition ID. + * @return page store type to be used for partition + */ + public static byte getTypeByPartId(final int partId) { + return partId == PageIdAllocator.INDEX_PARTITION ? PageStore.TYPE_IDX : PageStore.TYPE_DATA; } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java index 0e9062a..acf8334 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstorage/PartitionMetaStorageImpl.java @@ -49,6 +49,7 @@ public class PartitionMetaStorageImpl<T extends Storable> extends AbstractFreeLi * @param wal Wal. * @param metaPageId Meta page id. * @param initNew Initialize new. + * @param pageFlag Default flag value for allocated pages. */ public PartitionMetaStorageImpl( int cacheId, String name, @@ -60,9 +61,10 @@ public class PartitionMetaStorageImpl<T extends Storable> extends AbstractFreeLi boolean initNew, PageLockListener lsnr, GridKernalContext ctx, - AtomicLong pageListCacheLimit + AtomicLong pageListCacheLimit, + byte pageFlag ) throws IgniteCheckedException { - super(cacheId, name, memMetrics, memPlc, reuseList, wal, metaPageId, initNew, lsnr, ctx, pageListCacheLimit); + super(cacheId, name, memMetrics, memPlc, reuseList, wal, metaPageId, initNew, lsnr, ctx, pageListCacheLimit, pageFlag); } /** diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java index 681485d..1d9f385 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/snapshot/IgniteSnapshotManager.java @@ -132,7 +132,7 @@ import static org.apache.ignite.internal.processors.cache.persistence.file.FileP import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.PART_FILE_TEMPLATE; import static org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager.getPartitionFile; import static org.apache.ignite.internal.processors.cache.persistence.filename.PdsConsistentIdProcessor.DB_DEFAULT_FOLDER; -import static org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId.getFlagByPartId; +import static org.apache.ignite.internal.processors.cache.persistence.partstate.GroupPartitionId.getTypeByPartId; import static org.apache.ignite.internal.util.IgniteUtils.isLocalNodeCoordinator; import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.END_SNAPSHOT; import static org.apache.ignite.internal.util.distributed.DistributedProcess.DistributedProcessType.START_SNAPSHOT; @@ -1206,7 +1206,7 @@ public class IgniteSnapshotManager extends GridCacheSharedManagerAdapter try (FileIO fileIo = ioFactory.create(delta, READ); FilePageStore pageStore = (FilePageStore)storeFactory .apply(pair.getGroupId(), false) - .createPageStore(getFlagByPartId(pair.getPartitionId()), + .createPageStore(getTypeByPartId(pair.getPartitionId()), snpPart::toPath, val -> {}) ) { diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java index 5e67b7c..ca92a71 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/BPlusTree.java @@ -754,6 +754,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements * @param reuseList Reuse list. * @param innerIos Inner IO versions. * @param leafIos Leaf IO versions. + * @param pageFlag Default flag value for allocated pages. * @param failureProcessor if the tree is corrupted. * @throws IgniteCheckedException If failed. */ @@ -768,6 +769,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements ReuseList reuseList, IOVersions<? extends BPlusInnerIO<L>> innerIos, IOVersions<? extends BPlusLeafIO<L>> leafIos, + byte pageFlag, @Nullable FailureProcessor failureProcessor, @Nullable PageLockListener lockLsnr ) throws IgniteCheckedException { @@ -780,6 +782,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements globalRmvId, metaPageId, reuseList, + pageFlag, failureProcessor, lockLsnr, DEFAULT_PAGE_IO_RESOLVER @@ -797,6 +800,7 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements * @param globalRmvId Remove ID. * @param metaPageId Meta page ID. * @param reuseList Reuse list. + * @param pageFlag Default flag value for allocated pages. * @param failureProcessor if the tree is corrupted. * @throws IgniteCheckedException If failed. */ @@ -809,11 +813,12 @@ public abstract class BPlusTree<L, T extends L> extends DataStructure implements AtomicLong globalRmvId, long metaPageId, ReuseList reuseList, + byte pageFlag, @Nullable FailureProcessor failureProcessor, @Nullable PageLockListener lsnr, PageIoResolver pageIoRslvr - ) { - super(cacheGrpId, grpName, pageMem, wal, lsnr, pageIoRslvr); + ) throws IgniteCheckedException { + super(cacheGrpId, grpName, pageMem, wal, lsnr, pageIoRslvr, pageFlag); assert !F.isEmpty(name); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java index b2f52a5..5fa1cdd 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/io/TrackingPageIO.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.cache.persistence.tree.io; import java.nio.ByteBuffer; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; import org.apache.ignite.internal.processors.cache.persistence.snapshot.TrackingPageIsCorruptedException; import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageHandler; @@ -356,7 +357,11 @@ public class TrackingPageIO extends PageIO { int pageIdx = ((PageIdUtils.pageIndex(pageId) - COUNT_OF_EXTRA_PAGE) / countOfPageToTrack(pageSize)) * countOfPageToTrack(pageSize) + COUNT_OF_EXTRA_PAGE; - long trackingPageId = PageIdUtils.pageId(PageIdUtils.partId(pageId), PageIdUtils.flag(pageId), pageIdx); + byte flag = PageIdUtils.partId(pageId) == PageIdAllocator.INDEX_PARTITION ? + PageIdAllocator.FLAG_IDX : + PageIdAllocator.FLAG_DATA; + + long trackingPageId = PageIdUtils.pageId(PageIdUtils.partId(pageId), flag, pageIdx); assert PageIdUtils.pageIndex(trackingPageId) <= PageIdUtils.pageIndex(pageId); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseList.java index aaab186..d2a1ba0 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseList.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseList.java @@ -18,6 +18,10 @@ package org.apache.ignite.internal.processors.cache.persistence.tree.reuse; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.internal.pagemem.FullPageId; +import org.apache.ignite.internal.pagemem.PageIdAllocator; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; +import org.jetbrains.annotations.Nullable; /** * Reuse list. @@ -40,4 +44,18 @@ public interface ReuseList { * @throws IgniteCheckedException If failed. */ public long recycledPagesCount() throws IgniteCheckedException; + + /** + * Converts recycled page id back to a usable id. Might modify page content as well if flag is changing. + * + * @param pageId Id of the recycled page. + * @param flag Flag value for the page. One of {@link PageIdAllocator#FLAG_DATA}, {@link PageIdAllocator#FLAG_IDX} + * or {@link PageIdAllocator#FLAG_AUX}. + * @param initIO Page IO to reinit reused page. + * @return Updated page id. + * @throws IgniteCheckedException If failed. + * + * @see FullPageId + */ + long initRecycledPage(long pageId, byte flag, @Nullable PageIO initIO) throws IgniteCheckedException; } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseListImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseListImpl.java index cf3897f..5d2789b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseListImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/tree/reuse/ReuseListImpl.java @@ -25,6 +25,7 @@ import org.apache.ignite.internal.metric.IoStatisticsHolderNoOp; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; import org.apache.ignite.internal.processors.cache.persistence.freelist.PagesList; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; import org.apache.ignite.internal.processors.cache.persistence.tree.util.PageLockListener; /** @@ -48,6 +49,7 @@ public class ReuseListImpl extends PagesList implements ReuseList { * @param wal Write ahead log manager. * @param metaPageId Metadata page ID. * @param initNew {@code True} if new metadata should be initialized. + * @param pageFlag Default flag value for allocated pages. * @throws IgniteCheckedException If failed. */ public ReuseListImpl( @@ -59,7 +61,8 @@ public class ReuseListImpl extends PagesList implements ReuseList { boolean initNew, PageLockListener lockLsnr, GridKernalContext ctx, - AtomicLong pageListCacheLimit + AtomicLong pageListCacheLimit, + byte pageFlag ) throws IgniteCheckedException { super( cacheId, @@ -69,7 +72,8 @@ public class ReuseListImpl extends PagesList implements ReuseList { wal, metaPageId, lockLsnr, - ctx + ctx, + pageFlag ); bucketCache = new PagesCache(pageListCacheLimit); @@ -97,6 +101,11 @@ public class ReuseListImpl extends PagesList implements ReuseList { } /** {@inheritDoc} */ + @Override public long initRecycledPage(long pageId, byte flag, PageIO initIO) throws IgniteCheckedException { + return initRecycledPage0(pageId, flag, initIO); + } + + /** {@inheritDoc} */ @Override public long recycledPagesCount() throws IgniteCheckedException { return storedPagesCount(0); } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java index e9d652c..e9a88ba 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/CacheDataTree.java @@ -84,6 +84,7 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> { * @param rowStore Row store. * @param metaPageId Meta page ID. * @param initNew Initialize new index. + * @param pageFlag Default flag value for allocated pages. * @throws IgniteCheckedException If failed. */ public CacheDataTree( @@ -93,7 +94,8 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> { CacheDataRowStore rowStore, long metaPageId, boolean initNew, - PageLockListener lockLsnr + PageLockListener lockLsnr, + byte pageFlag ) throws IgniteCheckedException { super( name, @@ -106,6 +108,7 @@ public class CacheDataTree extends BPlusTree<CacheSearchRow, CacheDataRow> { reuseList, innerIO(grp), leafIO(grp), + pageFlag, grp.shared().kernalContext().failure(), lockLsnr ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java index 9cfb2c6..6070aca 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/tree/PendingEntriesTree.java @@ -43,6 +43,7 @@ public class PendingEntriesTree extends BPlusTree<PendingRow, PendingRow> { * @param metaPageId Meta page ID. * @param reuseList Reuse list. * @param initNew Initialize new index. + * @param pageFlag Default flag value for allocated pages. * @throws IgniteCheckedException If failed. */ public PendingEntriesTree( @@ -52,7 +53,8 @@ public class PendingEntriesTree extends BPlusTree<PendingRow, PendingRow> { long metaPageId, ReuseList reuseList, boolean initNew, - PageLockListener lockLsnr + PageLockListener lockLsnr, + byte pageFlag ) throws IgniteCheckedException { super( name, @@ -65,6 +67,7 @@ public class PendingEntriesTree extends BPlusTree<PendingRow, PendingRow> { reuseList, grp.sharedGroup() ? CacheIdAwarePendingEntryInnerIO.VERSIONS : PendingEntryInnerIO.VERSIONS, grp.sharedGroup() ? CacheIdAwarePendingEntryLeafIO.VERSIONS : PendingEntryLeafIO.VERSIONS, + pageFlag, grp.shared().kernalContext().failure(), lockLsnr ); diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java index b93c122..c2ba3b1 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/verify/IdleVerifyUtility.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; - import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.pagemem.PageIdAllocator; @@ -43,6 +42,10 @@ import org.apache.ignite.internal.util.typedef.internal.SB; import org.apache.ignite.lang.IgniteInClosure; import org.jetbrains.annotations.Nullable; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_AUX; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_DATA; +import static org.apache.ignite.internal.pagemem.PageIdAllocator.FLAG_IDX; + /** * Utility class for idle verify command. */ @@ -75,7 +78,8 @@ public class IdleVerifyUtility { * @param pageStore Page store. * @param grpCtx Passed cache group context. * @param partId Partition id. - * @param pageType Page type. Possible types {@link PageIdAllocator#FLAG_DATA}, {@link PageIdAllocator#FLAG_IDX}. + * @param pageType Page type. Possible types {@link PageIdAllocator#FLAG_DATA}, {@link PageIdAllocator#FLAG_IDX} + * and {@link PageIdAllocator#FLAG_AUX}. * @throws IgniteCheckedException If reading page failed. * @throws GridNotIdleException If cluster not idle. */ @@ -83,11 +87,11 @@ public class IdleVerifyUtility { FilePageStore pageStore, CacheGroupContext grpCtx, int partId, - byte pageType + @Deprecated byte pageType ) throws IgniteCheckedException, GridNotIdleException { - assert pageType == PageIdAllocator.FLAG_DATA || pageType == PageIdAllocator.FLAG_IDX : pageType; + assert pageType == FLAG_DATA || pageType == FLAG_IDX || pageType == FLAG_AUX : pageType; - long pageId = PageIdUtils.pageId(partId, pageType, 0); + long pageId = PageIdUtils.pageId(partId, (byte)0, 0); ByteBuffer buf = ByteBuffer.allocateDirect(grpCtx.dataRegion().pageMemory().pageSize()); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsMetricsLocalMXBeanImplSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsMetricsLocalMXBeanImplSelfTest.java index 9f8a324..38a743a 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsMetricsLocalMXBeanImplSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/metric/IoStatisticsMetricsLocalMXBeanImplSelfTest.java @@ -123,7 +123,7 @@ public class IoStatisticsMetricsLocalMXBeanImplSelfTest extends GridCommonAbstra long cacheLogicalReadsCnt = mreg.<LongMetric>findMetric(LOGICAL_READS).value(); - assertEquals(cnt, cacheLogicalReadsCnt); + assertEquals(cnt - 1, cacheLogicalReadsCnt); // 1 is for reuse bucket stripe. long cachePhysicalReadsCnt = mreg.<LongMetric>findMetric(PHYSICAL_READS).value(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java index 825c867..087b20c 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/pagemem/impl/PageIdUtilsSelfTest.java @@ -18,7 +18,7 @@ package org.apache.ignite.internal.pagemem.impl; import java.util.Random; - +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; @@ -99,13 +99,15 @@ public class PageIdUtilsSelfTest extends GridCommonAbstractTest { @Test public void testPageIdFromLink() throws Exception { assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x00FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x10FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x01FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x11FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x80FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x88FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0x08FFFFFFFFFFFFFFL)); - assertEquals(0x00FFFFFFFFFFFFFFL, PageIdUtils.pageId(0xFFFFFFFFFFFFFFFFL)); + + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x0001FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x1001FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x0101FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x1101FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x8001FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x8801FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0x0801FFFFFFFFFFFFL)); + assertEquals(0x0001FFFFFFFFFFFFL, PageIdUtils.pageId(0xFF01FFFFFFFFFFFFL)); assertEquals(0x0002FFFFFFFFFFFFL, PageIdUtils.pageId(0x0002FFFFFFFFFFFFL)); assertEquals(0x1002FFFFFFFFFFFFL, PageIdUtils.pageId(0x1002FFFFFFFFFFFFL)); @@ -116,12 +118,21 @@ public class PageIdUtilsSelfTest extends GridCommonAbstractTest { assertEquals(0x0802FFFFFFFFFFFFL, PageIdUtils.pageId(0x0802FFFFFFFFFFFFL)); assertEquals(0xFF02FFFFFFFFFFFFL, PageIdUtils.pageId(0xFF02FFFFFFFFFFFFL)); - assertEquals(0L, PageIdUtils.pageId(0x0000000000000000L)); - assertEquals(0L, PageIdUtils.pageId(0x1000000000000000L)); - assertEquals(0L, PageIdUtils.pageId(0x0100000000000000L)); - assertEquals(0L, PageIdUtils.pageId(0x8000000000000000L)); - assertEquals(0L, PageIdUtils.pageId(0x0800000000000000L)); - assertEquals(0L, PageIdUtils.pageId(0xFF00000000000000L)); + assertEquals(0x0004FFFFFFFFFFFFL, PageIdUtils.pageId(0x0004FFFFFFFFFFFFL)); + assertEquals(0x1004FFFFFFFFFFFFL, PageIdUtils.pageId(0x1004FFFFFFFFFFFFL)); + assertEquals(0x0104FFFFFFFFFFFFL, PageIdUtils.pageId(0x0104FFFFFFFFFFFFL)); + assertEquals(0x1104FFFFFFFFFFFFL, PageIdUtils.pageId(0x1104FFFFFFFFFFFFL)); + assertEquals(0x8004FFFFFFFFFFFFL, PageIdUtils.pageId(0x8004FFFFFFFFFFFFL)); + assertEquals(0x8804FFFFFFFFFFFFL, PageIdUtils.pageId(0x8804FFFFFFFFFFFFL)); + assertEquals(0x0804FFFFFFFFFFFFL, PageIdUtils.pageId(0x0804FFFFFFFFFFFFL)); + assertEquals(0xFF04FFFFFFFFFFFFL, PageIdUtils.pageId(0xFF04FFFFFFFFFFFFL)); + + assertEquals(0x0000000000000000L, PageIdUtils.pageId(0x0000000000000000L)); + assertEquals(0x1000000000000000L, PageIdUtils.pageId(0x1000000000000000L)); + assertEquals(0x0100000000000000L, PageIdUtils.pageId(0x0100000000000000L)); + assertEquals(0x8000000000000000L, PageIdUtils.pageId(0x8000000000000000L)); + assertEquals(0x0800000000000000L, PageIdUtils.pageId(0x0800000000000000L)); + assertEquals(0xFF00000000000000L, PageIdUtils.pageId(0xFF00000000000000L)); } /** @@ -136,7 +147,7 @@ public class PageIdUtilsSelfTest extends GridCommonAbstractTest { int partId = rnd.nextInt(PageIdUtils.MAX_PART_ID + 1); int pageNum = rnd.nextInt(); - long pageId = PageIdUtils.pageId(partId, (byte) 0, pageNum); + long pageId = PageIdUtils.pageId(partId, PageIdAllocator.FLAG_DATA, pageNum); String msg = "For values [offset=" + U.hexLong(off) + ", fileId=" + U.hexLong(partId) + ", pageNum=" + U.hexLong(pageNum) + ']'; diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/PendingTreeCorruptionTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/PendingTreeCorruptionTest.java new file mode 100644 index 0000000..7a748e3 --- /dev/null +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/PendingTreeCorruptionTest.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.cache.persistence; + +import java.util.concurrent.TimeUnit; +import javax.cache.expiry.AccessedExpiryPolicy; +import javax.cache.expiry.Duration; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.cluster.ClusterState; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; +import org.apache.ignite.configuration.DataStorageConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.internal.IgniteEx; +import org.apache.ignite.internal.processors.cache.CacheGroupContext; +import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManager; +import org.apache.ignite.internal.processors.cache.IgniteCacheOffheapManagerImpl; +import org.apache.ignite.internal.processors.cache.tree.PendingEntriesTree; +import org.apache.ignite.internal.processors.cache.tree.PendingRow; +import org.apache.ignite.internal.util.lang.GridCursor; +import org.apache.ignite.internal.util.typedef.internal.CU; +import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static java.util.concurrent.TimeUnit.MINUTES; + +/** */ +public class PendingTreeCorruptionTest extends GridCommonAbstractTest { + /** */ + @Before + public void before() throws Exception { + stopAllGrids(); + + cleanPersistenceDir(); + } + + /** */ + @After + public void after() throws Exception { + stopAllGrids(); + + cleanPersistenceDir(); + } + + /** {@inheritDoc} */ + @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { + IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName); + + cfg.setConsistentId(igniteInstanceName); + + cfg.setDataStorageConfiguration(new DataStorageConfiguration() + .setDefaultDataRegionConfiguration(new DataRegionConfiguration() + .setPersistenceEnabled(true) + ) + .setWalSegments(3) + .setWalSegmentSize(512 * 1024) + ); + + return cfg; + } + + /** */ + @Test + public void testCorruptionWhileLoadingData() throws Exception { + IgniteEx ig = startGrid(0); + + ig.cluster().state(ClusterState.ACTIVE); + + String expireCacheName = "cacheWithExpire"; + String regularCacheName = "cacheWithoutExpire"; + String grpName = "cacheGroup"; + + IgniteCache<Object, Object> expireCache = ig.getOrCreateCache( + new CacheConfiguration<>(expireCacheName) + .setExpiryPolicyFactory(AccessedExpiryPolicy.factoryOf(new Duration(MINUTES, 10))) + .setGroupName(grpName) + ); + + IgniteCache<Object, Object> regularCache = ig.getOrCreateCache( + new CacheConfiguration<>(regularCacheName) + .setGroupName(grpName) + ); + + // This will initialize partition and cache structures. + expireCache.put(0, 0); + expireCache.remove(0); + + int expireCacheId = CU.cacheGroupId(expireCacheName, grpName); + + CacheGroupContext grp = ig.context().cache().cacheGroup(CU.cacheId(grpName)); + IgniteCacheOffheapManager.CacheDataStore store = ((IgniteCacheOffheapManagerImpl)grp.offheap()).dataStore(0); + + // Get pending tree of expire cache. + PendingEntriesTree pendingTree = store.pendingTree(); + + long year = TimeUnit.DAYS.toMillis(365); + long expiration = System.currentTimeMillis() + year; + + ig.context().cache().context().database().checkpointReadLock(); + + try { + // Carefully calculated number. Just enough for the first split to happen, but not more. + for (int i = 0; i < 202; i++) + pendingTree.putx(new PendingRow(expireCacheId, expiration, expiration + i)); // link != 0 + + // Open cursor, it'll cache first leaf of the tree. + GridCursor<PendingRow> cur = pendingTree.find( + null, + new PendingRow(expireCacheId, expiration + year, 0), + PendingEntriesTree.WITHOUT_KEY + ); + + // Required for "do" loop to work. + assertTrue(cur.next()); + + int cnt = 0; + + // Emulate real expiry loop but with a more precise control. + do { + PendingRow row = cur.get(); + + pendingTree.removex(row); + + // Another carefully calculated moment. Here the page cache is exhausted AND the real page is merged + // with its sibling, meaning that cached "nextPageId" points to empty page from reuse list. + if (row.link - row.expireTime == 100) { + // Put into another cache will take a page from reuse list first. This means that cached + // "nextPageId" points to a data page. + regularCache.put(0, 0); + } + + cnt++; + } + while (cur.next()); + + assertEquals(202, cnt); + } + finally { + ig.context().cache().context().database().checkpointReadUnlock(); + } + } +} diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/CheckpointBufferDeadlockTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/CheckpointBufferDeadlockTest.java index 660c7ff..ca808ad 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/CheckpointBufferDeadlockTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/cache/persistence/db/CheckpointBufferDeadlockTest.java @@ -51,6 +51,7 @@ import org.apache.ignite.internal.processors.cache.persistence.file.FileIOFactor import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager; import org.apache.ignite.internal.processors.cache.persistence.file.RandomAccessFileIOFactory; import org.apache.ignite.internal.processors.cache.persistence.pagemem.PageMemoryImpl; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; import org.apache.ignite.internal.util.typedef.internal.CU; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.ListeningTestLogger; @@ -236,6 +237,17 @@ public class CheckpointBufferDeadlockTest extends GridCommonAbstractTest { long pageId = PageIdUtils.pageId(0, PageIdAllocator.FLAG_DATA, pageIdx); + long page = pageMem.acquirePage(CU.cacheId(cacheName), pageId); + + try { + // We do not know correct flag(FLAG_DATA or FLAG_AUX). Skip page if no luck. + if (pageId != PageIO.getPageId(page + PageMemoryImpl.PAGE_OVERHEAD)) + continue; + } + finally { + pageMem.releasePage(CU.cacheId(cacheName), pageId, page); + } + pickedPagesSet.add(new FullPageId(pageId, CU.cacheId(cacheName))); } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeFakeReuseSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeFakeReuseSelfTest.java index cab54a4..db00de3 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeFakeReuseSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeFakeReuseSelfTest.java @@ -20,6 +20,7 @@ package org.apache.ignite.internal.processors.database; import java.util.concurrent.ConcurrentLinkedDeque; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.pagemem.PageMemory; +import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseBag; import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList; @@ -59,5 +60,10 @@ public class BPlusTreeFakeReuseSelfTest extends BPlusTreeSelfTest { @Override public long recycledPagesCount() throws IgniteCheckedException { return deque.size(); } + + /** {@inheritDoc} */ + @Override public long initRecycledPage(long pageId, byte flag, PageIO initIO) throws IgniteCheckedException { + return pageId; + } } } diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeReuseSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeReuseSelfTest.java index 8d50fad..94b3db6 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeReuseSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeReuseSelfTest.java @@ -21,6 +21,7 @@ import java.util.HashSet; import java.util.Set; import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.internal.GridKernalContext; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO; @@ -83,7 +84,7 @@ public class BPlusTreeReuseSelfTest extends BPlusTreeSelfTest { boolean initNew, GridKernalContext ctx ) throws IgniteCheckedException { - super(cacheId, name, pageMem, wal, metaPageId, initNew, new TestPageLockListener(), ctx, null); + super(cacheId, name, pageMem, wal, metaPageId, initNew, new TestPageLockListener(), ctx, null, PageIdAllocator.FLAG_IDX); } /** diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java index 82f11ad..9465dc7 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/BPlusTreeSelfTest.java @@ -2773,6 +2773,7 @@ public class BPlusTreeSelfTest extends GridCommonAbstractTest { reuseList, new IOVersions<>(new LongInnerIO(canGetRow)), new IOVersions<>(new LongLeafIO()), + PageIdAllocator.FLAG_IDX, new FailureProcessor(new GridTestKernalContext(log)) { @Override public boolean process(FailureContext failureCtx) { lockTrackerManager.dumpLocksToLog(); diff --git a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java index a6ce732..1c0f33d 100644 --- a/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java +++ b/modules/core/src/test/java/org/apache/ignite/internal/processors/database/CacheFreeListSelfTest.java @@ -530,7 +530,8 @@ public class CacheFreeListSelfTest extends GridCommonAbstractTest { true, null, new GridTestKernalContext(log), - null + null, + PageIdAllocator.FLAG_IDX ); } diff --git a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java index dfca746..be885e0 100644 --- a/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java +++ b/modules/core/src/test/java/org/apache/ignite/testsuites/IgnitePdsTestSuite4.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsRemoveDu import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsRestartAfterFailedToWriteMetaPageTest; import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsSpuriousRebalancingOnNodeJoinTest; import org.apache.ignite.internal.processors.cache.persistence.IgnitePdsTaskCancelingTest; +import org.apache.ignite.internal.processors.cache.persistence.PendingTreeCorruptionTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsCacheWalDisabledOnRebalancingTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsPageReplacementDuringPartitionClearTest; import org.apache.ignite.internal.processors.cache.persistence.db.IgnitePdsPartitionPreloadTest; @@ -121,6 +122,8 @@ public class IgnitePdsTestSuite4 { GridTestUtils.addTestIfNeeded(suite, WarmUpSelfTest.class, ignoredTests); GridTestUtils.addTestIfNeeded(suite, LoadAllWarmUpStrategySelfTest.class, ignoredTests); + GridTestUtils.addTestIfNeeded(suite, PendingTreeCorruptionTest.class, ignoredTests); + return suite; } 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 7a31059..0ded892 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 @@ -60,6 +60,7 @@ import org.apache.ignite.internal.managers.communication.GridMessageListener; import org.apache.ignite.internal.managers.eventstorage.GridLocalEventListener; import org.apache.ignite.internal.mxbean.SqlQueryMXBean; import org.apache.ignite.internal.mxbean.SqlQueryMXBeanImpl; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.store.IgnitePageStoreManager; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; @@ -2447,6 +2448,7 @@ public class IgniteH2Indexing implements GridQueryIndexing { reuseList, H2ExtrasInnerIO.getVersions(inlineSize, mvccEnabled), H2ExtrasLeafIO.getVersions(inlineSize, mvccEnabled), + PageIdAllocator.FLAG_IDX, ctx.failure(), lockLsnr ) { diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java index 9c6ca13..99a0add 100644 --- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java +++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/database/H2Tree.java @@ -30,6 +30,7 @@ import org.apache.ignite.SystemProperty; import org.apache.ignite.failure.FailureType; import org.apache.ignite.internal.metric.IoStatisticsHolder; import org.apache.ignite.internal.pagemem.FullPageId; +import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; import org.apache.ignite.internal.pagemem.PageMemory; import org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager; @@ -221,6 +222,7 @@ public class H2Tree extends BPlusTree<H2Row, H2Row> { globalRmvId, metaPageId, reuseList, + PageIdAllocator.FLAG_IDX, failureProcessor, null, pageIoRslvr