Repository: ignite Updated Branches: refs/heads/ignite-2.7 c880965ac -> d14a9c635
IGNITE-9612 Improve checkpoint mark phase speed - Fixes #4971. Signed-off-by: Dmitriy Govorukhin <[email protected]> (cherry picked from commit 6041cda5a0b7331c33ec643d0c8ccbd77a120a86) Signed-off-by: Dmitriy Govorukhin <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d14a9c63 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d14a9c63 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d14a9c63 Branch: refs/heads/ignite-2.7 Commit: d14a9c635a0dad7899bdd56aec82edfb55422231 Parents: c880965 Author: ascherbakoff <[email protected]> Authored: Sat Oct 13 21:35:36 2018 +0300 Committer: Dmitriy Govorukhin <[email protected]> Committed: Sat Oct 13 21:44:12 2018 +0300 ---------------------------------------------------------------------- .../persistence/GridCacheOffheapManager.java | 32 +++++++++--- .../partstate/PartitionAllocationMap.java | 55 +++++++++++++------- 2 files changed, 62 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d14a9c63/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/GridCacheOffheapManager.java ---------------------------------------------------------------------- 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 c6f8415..c7a6e97 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 @@ -171,7 +171,19 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple Executor execSvc = ctx.executor(); - if (ctx.nextSnapshot() && ctx.needToSnapshot(grp.cacheOrGroupName())) { + boolean needSnapshot = ctx.nextSnapshot() && ctx.needToSnapshot(grp.cacheOrGroupName()); + + boolean hasNonEmptyGroups = false; + + for (CacheDataStore store : partDataStores.values()) { + if (notEmpty(store)) { + hasNonEmptyGroups = true; + + break; + } + } + + if (needSnapshot && hasNonEmptyGroups) { if (execSvc == null) updateSnapshotTag(ctx); else { @@ -190,7 +202,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple reuseList.saveMetadata(); for (CacheDataStore store : partDataStores.values()) - saveStoreMetadata(store, ctx, false); + saveStoreMetadata(store, ctx, false, needSnapshot); } else { execSvc.execute(() -> { @@ -205,7 +217,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple for (CacheDataStore store : partDataStores.values()) execSvc.execute(() -> { try { - saveStoreMetadata(store, ctx, false); + saveStoreMetadata(store, ctx, false, needSnapshot); } catch (IgniteCheckedException e) { throw new IgniteException(e); @@ -215,18 +227,24 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple } /** + * @return {@code True} is group is not empty. + */ + private boolean notEmpty(CacheDataStore store) { + return store.rowStore() != null && (store.fullSize() > 0 || store.updateCounter() > 0); + } + + /** * @param store Store to save metadata. * @throws IgniteCheckedException If failed. */ private void saveStoreMetadata( CacheDataStore store, Context ctx, - boolean beforeDestroy + boolean beforeDestroy, + boolean needSnapshot ) throws IgniteCheckedException { RowStore rowStore0 = store.rowStore(); - boolean needSnapshot = ctx != null && ctx.nextSnapshot() && ctx.needToSnapshot(grp.cacheOrGroupName()); - if (rowStore0 != null) { CacheFreeListImpl freeList = (CacheFreeListImpl)rowStore0.freeList(); @@ -617,7 +635,7 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple ctx.database().checkpointReadLock(); try { - saveStoreMetadata(store, null, true); + saveStoreMetadata(store, null, true, false); } finally { ctx.database().checkpointReadUnlock(); http://git-wip-us.apache.org/repos/asf/ignite/blob/d14a9c63/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/PartitionAllocationMap.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/PartitionAllocationMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/PartitionAllocationMap.java index cab90c5..808ab41 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/PartitionAllocationMap.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/partstate/PartitionAllocationMap.java @@ -20,7 +20,8 @@ package org.apache.ignite.internal.processors.cache.persistence.partstate; import java.util.Map; import java.util.NavigableMap; import java.util.Set; -import java.util.concurrent.ConcurrentSkipListMap; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; import org.apache.ignite.internal.pagemem.FullPageId; import org.apache.ignite.internal.pagemem.PageIdAllocator; import org.apache.ignite.internal.pagemem.PageIdUtils; @@ -37,7 +38,11 @@ import org.jetbrains.annotations.Nullable; public class PartitionAllocationMap { /** Maps following pairs: (groupId, partId) -> (lastAllocatedCount, allocatedCount) */ @GridToStringInclude - private final NavigableMap<GroupPartitionId, PagesAllocationRange> map = new ConcurrentSkipListMap<>(); + private final Map<GroupPartitionId, PagesAllocationRange> writeMap = new ConcurrentHashMap<>(); + + /** Map used by snapshot executor. */ + @GridToStringInclude + private NavigableMap<GroupPartitionId, PagesAllocationRange> readMap; /** Partitions forced to be skipped. */ @GridToStringInclude @@ -51,14 +56,14 @@ public class PartitionAllocationMap { * @return value or null */ @Nullable public PagesAllocationRange get(GroupPartitionId key) { - return map.get(key); + return readMap.get(key); } /** * @param fullPageId Full page id. */ @Nullable public PagesAllocationRange get(FullPageId fullPageId) { - return map.get(createCachePartId(fullPageId)); + return readMap.get(createCachePartId(fullPageId)); } /** @@ -73,27 +78,27 @@ public class PartitionAllocationMap { /** @return <tt>true</tt> if this map contains no key-value mappings */ public boolean isEmpty() { - return map.isEmpty(); + return readMap.isEmpty(); } /** @return the number of key-value mappings in this map. */ public int size() { - return map.size(); + return readMap.size(); } /** @return keys (all caches partitions) */ public Set<GroupPartitionId> keySet() { - return map.keySet(); + return readMap.keySet(); } /** @return values (allocation ranges) */ public Iterable<PagesAllocationRange> values() { - return map.values(); + return readMap.values(); } /** @return Returns the first (lowest) key currently in this map. */ public GroupPartitionId firstKey() { - return map.firstKey(); + return readMap.firstKey(); } /** @@ -103,11 +108,7 @@ public class PartitionAllocationMap { * @return {@code true} if skipped partition was added to the ignore list during this call. */ public boolean forceSkipIndexPartition(int grpId) { - GroupPartitionId idxId = new GroupPartitionId(grpId, PageIdAllocator.INDEX_PARTITION); - - map.remove(idxId); - - return skippedParts.add(idxId); + return skippedParts.add(new GroupPartitionId(grpId, PageIdAllocator.INDEX_PARTITION)); } /** @@ -117,17 +118,17 @@ public class PartitionAllocationMap { * @return first found key which is greater than provided */ @Nullable public GroupPartitionId nextKey(@NotNull final GroupPartitionId key) { - return map.navigableKeySet().higher(key); + return readMap.navigableKeySet().higher(key); } /** @return set view of the mappings contained in this map, sorted in ascending key order */ public Set<Map.Entry<GroupPartitionId, PagesAllocationRange>> entrySet() { - return map.entrySet(); + return readMap.entrySet(); } /** @return <tt>true</tt> if this map contains a mapping for the specified key */ public boolean containsKey(GroupPartitionId key) { - return map.containsKey(key); + return readMap.containsKey(key); } /** @@ -137,7 +138,25 @@ public class PartitionAllocationMap { * <tt>key</tt>. */ public PagesAllocationRange put(GroupPartitionId key, PagesAllocationRange val) { - return !skippedParts.contains(key) ? map.put(key, val) : null; + return writeMap.put(key, val); + } + + /** + * Prepare map for snapshot. + */ + public void prepareForSnapshot() { + if (readMap != null) + return; + + readMap = new TreeMap<>(); + + for (Map.Entry<GroupPartitionId, PagesAllocationRange> entry : writeMap.entrySet()) { + if (!skippedParts.contains(entry.getKey())) + readMap.put(entry.getKey(), entry.getValue()); + } + + skippedParts.clear(); + writeMap.clear(); } /** {@inheritDoc} */
