You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ag...@apache.org on 2020/11/17 10:32:26 UTC
[ignite] branch master updated: IGNITE-12489 Fix persistence
corruption caused by invalid tag check (flags were not rotated for some
pages) - Fixes #8358.
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 <nt...@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 <al...@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