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 2017/10/20 07:32:18 UTC

[09/11] ignite git commit: IGNITE-6030 Allow enabling persistence per data region

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoStoreImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoStoreImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoStoreImpl.java
index 8f146dc..6ba68c2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoStoreImpl.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/pagemem/impl/PageMemoryNoStoreImpl.java
@@ -27,14 +27,14 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.ignite.IgniteException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.IgniteSystemProperties;
-import org.apache.ignite.configuration.MemoryPolicyConfiguration;
+import org.apache.ignite.configuration.DataRegionConfiguration;
 import org.apache.ignite.internal.mem.DirectMemoryProvider;
 import org.apache.ignite.internal.mem.DirectMemoryRegion;
 import org.apache.ignite.internal.mem.IgniteOutOfMemoryException;
 import org.apache.ignite.internal.pagemem.PageIdUtils;
 import org.apache.ignite.internal.pagemem.PageMemory;
 import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
-import org.apache.ignite.internal.processors.cache.persistence.MemoryMetricsImpl;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegionMetricsImpl;
 import org.apache.ignite.internal.processors.cache.persistence.tree.io.PageIO;
 import org.apache.ignite.internal.util.GridUnsafe;
 import org.apache.ignite.internal.util.IgniteUtils;
@@ -125,11 +125,11 @@ public class PageMemoryNoStoreImpl implements PageMemory {
     /** Direct memory allocator. */
     private final DirectMemoryProvider directMemoryProvider;
 
-    /** Name of MemoryPolicy this PageMemory is associated with. */
-    private final MemoryPolicyConfiguration memoryPolicyCfg;
+    /** Name of DataRegion this PageMemory is associated with. */
+    private final DataRegionConfiguration dataRegionCfg;
 
     /** Object to collect memory usage metrics. */
-    private final MemoryMetricsImpl memMetrics;
+    private final DataRegionMetricsImpl memMetrics;
 
     /** */
     private AtomicLong freePageListHead = new AtomicLong(INVALID_REL_PTR);
@@ -163,7 +163,7 @@ public class PageMemoryNoStoreImpl implements PageMemory {
      * @param directMemoryProvider Memory allocator to use.
      * @param sharedCtx Cache shared context.
      * @param pageSize Page size.
-     * @param memPlcCfg Memory Policy configuration.
+     * @param dataRegionCfg Data region configuration.
      * @param memMetrics Memory Metrics.
      * @param trackAcquiredPages If {@code true} tracks number of allocated pages (for tests purpose only).
      */
@@ -172,8 +172,8 @@ public class PageMemoryNoStoreImpl implements PageMemory {
         DirectMemoryProvider directMemoryProvider,
         GridCacheSharedContext<?, ?> sharedCtx,
         int pageSize,
-        MemoryPolicyConfiguration memPlcCfg,
-        MemoryMetricsImpl memMetrics,
+        DataRegionConfiguration dataRegionCfg,
+        DataRegionMetricsImpl memMetrics,
         boolean trackAcquiredPages
     ) {
         assert log != null || sharedCtx != null;
@@ -183,21 +183,21 @@ public class PageMemoryNoStoreImpl implements PageMemory {
         this.directMemoryProvider = directMemoryProvider;
         this.trackAcquiredPages = trackAcquiredPages;
         this.memMetrics = memMetrics;
-        memoryPolicyCfg = memPlcCfg;
+        this.dataRegionCfg = dataRegionCfg;
 
         sysPageSize = pageSize + PAGE_OVERHEAD;
 
         assert sysPageSize % 8 == 0 : sysPageSize;
 
-        totalPages = (int)(memPlcCfg.getMaxSize() / sysPageSize);
+        totalPages = (int)(dataRegionCfg.getMaxSize() / sysPageSize);
 
         rwLock = new OffheapReadWriteLock(lockConcLvl);
     }
 
     /** {@inheritDoc} */
     @Override public void start() throws IgniteException {
-        long startSize = memoryPolicyCfg.getInitialSize();
-        long maxSize = memoryPolicyCfg.getMaxSize();
+        long startSize = dataRegionCfg.getInitialSize();
+        long maxSize = dataRegionCfg.getMaxSize();
 
         long[] chunks = new long[SEG_CNT];
 
@@ -290,9 +290,9 @@ public class PageMemoryNoStoreImpl implements PageMemory {
 
         if (relPtr == INVALID_REL_PTR)
             throw new IgniteOutOfMemoryException("Not enough memory allocated " +
-                "(consider increasing memory policy size or enabling evictions) " +
-                "[policyName=" + memoryPolicyCfg.getName() +
-                ", size=" + U.readableSize(memoryPolicyCfg.getMaxSize(), true) + "]"
+                "(consider increasing data region size or enabling evictions) " +
+                "[policyName=" + dataRegionCfg.getName() +
+                ", size=" + U.readableSize(dataRegionCfg.getMaxSize(), true) + "]"
             );
 
         assert (relPtr & ~PageIdUtils.PAGE_IDX_MASK) == 0 : U.hexLong(relPtr & ~PageIdUtils.PAGE_IDX_MASK);
@@ -615,7 +615,7 @@ public class PageMemoryNoStoreImpl implements PageMemory {
 
             if (oldRef != null) {
                 if (log.isInfoEnabled())
-                    log.info("Allocated next memory segment [plcName=" + memoryPolicyCfg.getName() +
+                    log.info("Allocated next memory segment [plcName=" + dataRegionCfg.getName() +
                         ", chunkSize=" + U.readableSize(region.size(), true) + ']');
             }
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
index a413ade..eaaa24d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheAffinitySharedManager.java
@@ -2592,7 +2592,9 @@ public class CacheAffinitySharedManager<K, V> extends GridCacheSharedManagerAdap
      * @param sql SQL flag.
      */
     private void saveCacheConfiguration(CacheConfiguration<?, ?> cfg, boolean sql) {
-        if (cctx.pageStore() != null && cctx.database().persistenceEnabled() && !cctx.kernalContext().clientNode()) {
+        if (cctx.pageStore() != null && cctx.database().persistenceEnabled() &&
+            CU.isPersistentCache(cfg, cctx.gridConfig().getDataStorageConfiguration()) &&
+            !cctx.kernalContext().clientNode()) {
             try {
                 StoredCacheData data = new StoredCacheData(cfg);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
index 5e5e02e..18acacf 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupContext.java
@@ -42,8 +42,8 @@ import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtAffini
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopology;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtPartitionTopologyImpl;
 import org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPreloader;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheOffheapManager;
-import org.apache.ignite.internal.processors.cache.persistence.MemoryPolicy;
 import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList;
 import org.apache.ignite.internal.processors.cache.persistence.tree.reuse.ReuseList;
 import org.apache.ignite.internal.processors.cache.query.continuous.CounterSkipContext;
@@ -126,7 +126,7 @@ public class CacheGroupContext {
     private GridCachePreloader preldr;
 
     /** */
-    private final MemoryPolicy memPlc;
+    private final DataRegion dataRegion;
 
     /** */
     private final CacheObjectContext cacheObjCtx;
@@ -150,7 +150,7 @@ public class CacheGroupContext {
      * @param cacheType Cache type.
      * @param ccfg Cache configuration.
      * @param affNode Affinity node flag.
-     * @param memPlc Memory policy.
+     * @param dataRegion data region.
      * @param cacheObjCtx Cache object context.
      * @param freeList Free list.
      * @param reuseList Reuse list.
@@ -163,13 +163,13 @@ public class CacheGroupContext {
         CacheType cacheType,
         CacheConfiguration ccfg,
         boolean affNode,
-        MemoryPolicy memPlc,
+        DataRegion dataRegion,
         CacheObjectContext cacheObjCtx,
         FreeList freeList,
         ReuseList reuseList,
         AffinityTopologyVersion locStartVer) {
         assert ccfg != null;
-        assert memPlc != null || !affNode;
+        assert dataRegion != null || !affNode;
         assert grpId != 0 : "Invalid group ID [cache=" + ccfg.getName() + ", grpName=" + ccfg.getGroupName() + ']';
 
         this.grpId = grpId;
@@ -177,7 +177,7 @@ public class CacheGroupContext {
         this.ctx = ctx;
         this.ccfg = ccfg;
         this.affNode = affNode;
-        this.memPlc = memPlc;
+        this.dataRegion = dataRegion;
         this.cacheObjCtx = cacheObjCtx;
         this.freeList = freeList;
         this.reuseList = reuseList;
@@ -188,7 +188,7 @@ public class CacheGroupContext {
 
         depEnabled = ctx.kernalContext().deploy().enabled() && !ctx.kernalContext().cacheObjects().isBinaryEnabled(ccfg);
 
-        storeCacheId = affNode && memPlc.config().getPageEvictionMode() != DataPageEvictionMode.DISABLED;
+        storeCacheId = affNode && dataRegion.config().getPageEvictionMode() != DataPageEvictionMode.DISABLED;
 
         log = ctx.kernalContext().log(getClass());
 
@@ -523,10 +523,10 @@ public class CacheGroupContext {
     }
 
     /**
-     * @return Memory policy.
+     * @return data region.
      */
-    public MemoryPolicy memoryPolicy() {
-        return memPlc;
+    public DataRegion dataRegion() {
+        return dataRegion;
     }
 
     /**
@@ -862,7 +862,7 @@ public class CacheGroupContext {
         else
             preldr = new GridCachePreloaderAdapter(this);
 
-        if (ctx.kernalContext().config().getPersistentStoreConfiguration() != null) {
+        if (persistenceEnabled()) {
             try {
                 offheapMgr = new GridCacheOffheapManager();
             }
@@ -879,6 +879,13 @@ public class CacheGroupContext {
     }
 
     /**
+     * @return Persistence enabled flag.
+     */
+    public boolean persistenceEnabled() {
+        return dataRegion != null && dataRegion.config().isPersistenceEnabled();
+    }
+
+    /**
      * @param nodeId Node ID.
      * @param req Request.
      */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupData.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupData.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupData.java
index 99b7b1e..617db56 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupData.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupData.java
@@ -59,14 +59,18 @@ public class CacheGroupData implements Serializable {
     /** */
     private long flags;
 
+    /** Persistence enabled flag. */
+    private final boolean persistenceEnabled;
+
     /**
      * @param cacheCfg Cache configuration.
      * @param grpName Group name.
-     * @param grpId  Group ID.
+     * @param grpId Group ID.
      * @param rcvdFrom Node ID cache group received from.
      * @param startTopVer Start version for dynamically started group.
      * @param deploymentId Deployment ID.
      * @param caches Cache group caches.
+     * @param persistenceEnabled Persistence enabled flag.
      */
     CacheGroupData(
         CacheConfiguration cacheCfg,
@@ -76,7 +80,8 @@ public class CacheGroupData implements Serializable {
         @Nullable AffinityTopologyVersion startTopVer,
         IgniteUuid deploymentId,
         Map<String, Integer> caches,
-        long flags) {
+        long flags,
+        boolean persistenceEnabled) {
         assert cacheCfg != null;
         assert grpId != 0 : cacheCfg.getName();
         assert deploymentId != null : cacheCfg.getName();
@@ -89,6 +94,7 @@ public class CacheGroupData implements Serializable {
         this.deploymentId = deploymentId;
         this.caches = caches;
         this.flags = flags;
+        this.persistenceEnabled = persistenceEnabled;
     }
 
     /**
@@ -140,6 +146,13 @@ public class CacheGroupData implements Serializable {
         return caches;
     }
 
+    /**
+     * @return Persistence enabled flag.
+     */
+    public boolean persistenceEnabled() {
+        return persistenceEnabled;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(CacheGroupData.class, this);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupDescriptor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupDescriptor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupDescriptor.java
index 20301a6..86e330e 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupDescriptor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheGroupDescriptor.java
@@ -58,14 +58,18 @@ public class CacheGroupDescriptor {
     /** */
     private AffinityTopologyVersion rcvdFromVer;
 
+    /** Persistence enabled flag. */
+    private final boolean persistenceEnabled;
+
     /**
      * @param cacheCfg Cache configuration.
      * @param grpName Group name.
-     * @param grpId  Group ID.
+     * @param grpId Group ID.
      * @param rcvdFrom Node ID cache group received from.
      * @param startTopVer Start version for dynamically started group.
      * @param deploymentId Deployment ID.
      * @param caches Cache group caches.
+     * @param persistenceEnabled Persistence enabled flag.
      */
     CacheGroupDescriptor(
         CacheConfiguration cacheCfg,
@@ -74,7 +78,8 @@ public class CacheGroupDescriptor {
         UUID rcvdFrom,
         @Nullable AffinityTopologyVersion startTopVer,
         IgniteUuid deploymentId,
-        Map<String, Integer> caches) {
+        Map<String, Integer> caches,
+        boolean persistenceEnabled) {
         assert cacheCfg != null;
         assert grpId != 0;
 
@@ -85,6 +90,7 @@ public class CacheGroupDescriptor {
         this.deploymentId = deploymentId;
         this.cacheCfg = new CacheConfiguration<>(cacheCfg);
         this.caches = caches;
+        this.persistenceEnabled = persistenceEnabled;
     }
 
     /**
@@ -202,7 +208,7 @@ public class CacheGroupDescriptor {
      * @param otherDesc CacheGroup descriptor that must be merged with this one.
      */
     void mergeWith(CacheGroupDescriptor otherDesc) {
-        assert otherDesc != null && otherDesc.config() != null: otherDesc;
+        assert otherDesc != null && otherDesc.config() != null : otherDesc;
 
         CacheConfiguration otherCfg = otherDesc.config();
 
@@ -221,6 +227,13 @@ public class CacheGroupDescriptor {
         return startTopVer;
     }
 
+    /**
+     * @return Persistence enabled flag.
+     */
+    public boolean persistenceEnabled() {
+        return persistenceEnabled;
+    }
+
     /** {@inheritDoc} */
     @Override public String toString() {
         return S.toString(CacheGroupDescriptor.class, this, "cacheName", cacheCfg.getName());

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
index b4cc9c5..8382821 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/ClusterCachesInfo.java
@@ -912,7 +912,8 @@ class ClusterCachesInfo {
                 grpDesc.startTopologyVersion(),
                 grpDesc.deploymentId(),
                 grpDesc.caches(),
-                0);
+                0,
+                grpDesc.persistenceEnabled());
 
             cacheGrps.put(grpDesc.groupId(), grpData);
         }
@@ -990,7 +991,8 @@ class ClusterCachesInfo {
                 grpData.receivedFrom(),
                 grpData.startTopologyVersion(),
                 grpData.deploymentId(),
-                grpData.caches());
+                grpData.caches(),
+                grpData.persistenceEnabled());
 
             if (locCacheGrps.containsKey(grpDesc.groupId())) {
                 CacheGroupDescriptor locGrpCfg = locCacheGrps.get(grpDesc.groupId());
@@ -1508,7 +1510,8 @@ class ClusterCachesInfo {
             rcvdFrom,
             curTopVer != null ? curTopVer.nextMinorVersion() : null,
             deploymentId,
-            caches);
+            caches,
+            CU.isPersistentCache(startedCacheCfg, ctx.config().getDataStorageConfiguration()));
 
         CacheGroupDescriptor old = registeredCacheGrps.put(grpId, grpDesc);
 
@@ -1560,8 +1563,8 @@ class ClusterCachesInfo {
         CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, "nodeFilter", "Node filter",
             attr1.nodeFilterClassName(), attr2.nodeFilterClassName(), true);
 
-        CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, "memoryPolicyName", "Memory policy",
-            cfg.getMemoryPolicyName(), startCfg.getMemoryPolicyName(), true);
+        CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, "dataRegionName", "Data region",
+            cfg.getDataRegionName(), startCfg.getDataRegionName(), true);
 
         CU.validateCacheGroupsAttributesMismatch(log, cfg, startCfg, "topologyValidator", "Topology validator",
             attr1.topologyValidatorClassName(), attr2.topologyValidatorClassName(), true);

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 8c5d6f2..9bdce35 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -58,7 +58,6 @@ import org.apache.ignite.cache.CacheMetrics;
 import org.apache.ignite.cache.CachePeekMode;
 import org.apache.ignite.cache.affinity.Affinity;
 import org.apache.ignite.cluster.ClusterGroup;
-import org.apache.ignite.cluster.ClusterGroupEmptyException;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.cluster.ClusterTopologyException;
 import org.apache.ignite.compute.ComputeJob;
@@ -2035,7 +2034,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
                                             GridCacheEntryEx entry = null;
 
                                             try {
-                                                ctx.shared().database().ensureFreeSpace(ctx.memoryPolicy());
+                                                ctx.shared().database().ensureFreeSpace(ctx.dataRegion());
 
                                                 entry = entryEx(key);
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
index 120007f..34d3c97 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheContext.java
@@ -71,7 +71,7 @@ import org.apache.ignite.internal.processors.cache.distributed.near.GridNearTran
 import org.apache.ignite.internal.processors.cache.dr.GridCacheDrManager;
 import org.apache.ignite.internal.processors.cache.jta.CacheJtaManagerAdapter;
 import org.apache.ignite.internal.processors.cache.local.GridLocalCache;
-import org.apache.ignite.internal.processors.cache.persistence.MemoryPolicy;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
 import org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager;
 import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryManager;
 import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
@@ -736,10 +736,10 @@ public class GridCacheContext<K, V> implements Externalizable {
     }
 
     /**
-     * @return Memory policy.
+     * @return Data region.
      */
-    public MemoryPolicy memoryPolicy() {
-        return grp.memoryPolicy();
+    public DataRegion dataRegion() {
+        return grp.dataRegion();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index 5c3fe1f..e46e4d2 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -48,7 +48,7 @@ import org.apache.ignite.internal.processors.cache.extras.GridCacheObsoleteEntry
 import org.apache.ignite.internal.processors.cache.extras.GridCacheTtlEntryExtras;
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRowAdapter;
-import org.apache.ignite.internal.processors.cache.persistence.MemoryPolicy;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
 import org.apache.ignite.internal.processors.cache.query.continuous.CacheContinuousQueryListener;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
 import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
@@ -2543,7 +2543,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
 
             boolean update;
 
-            boolean walEnabled = !cctx.isNear() && cctx.shared().wal() != null;
+            boolean walEnabled = !cctx.isNear() && cctx.group().persistenceEnabled();
 
             if (cctx.shared().database().persistenceEnabled()) {
                 unswap(false);
@@ -3204,7 +3204,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
         assert cctx.atomic();
 
         try {
-            if (cctx.shared().wal() != null)
+            if (cctx.group().persistenceEnabled())
                 cctx.shared().wal().log(new DataRecord(new DataEntry(
                     cctx.cacheId(),
                     key,
@@ -3326,13 +3326,13 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
     }
 
     /**
-     * Evicts necessary number of data pages if per-page eviction is configured in current {@link MemoryPolicy}.
+     * Evicts necessary number of data pages if per-page eviction is configured in current {@link DataRegion}.
      */
     private void ensureFreeSpace() throws IgniteCheckedException {
         // Deadlock alert: evicting data page causes removing (and locking) all entries on the page one by one.
         assert !Thread.holdsLock(this);
 
-        cctx.shared().database().ensureFreeSpace(cctx.memoryPolicy());
+        cctx.shared().database().ensureFreeSpace(cctx.dataRegion());
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
index f3759e0..ad8f74a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheProcessor.java
@@ -49,6 +49,7 @@ import org.apache.ignite.cache.store.CacheStore;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
 import org.apache.ignite.cluster.ClusterNode;
 import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
 import org.apache.ignite.configuration.DeploymentMode;
 import org.apache.ignite.configuration.FileSystemConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
@@ -88,7 +89,7 @@ import org.apache.ignite.internal.processors.cache.local.GridLocalCache;
 import org.apache.ignite.internal.processors.cache.local.atomic.GridLocalAtomicCache;
 import org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
 import org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDatabaseSharedManager;
-import org.apache.ignite.internal.processors.cache.persistence.MemoryPolicy;
+import org.apache.ignite.internal.processors.cache.persistence.DataRegion;
 import org.apache.ignite.internal.processors.cache.persistence.file.FilePageStoreManager;
 import org.apache.ignite.internal.processors.cache.persistence.freelist.FreeList;
 import org.apache.ignite.internal.processors.cache.persistence.snapshot.IgniteCacheSnapshotManager;
@@ -139,6 +140,7 @@ import org.apache.ignite.lang.IgniteUuid;
 import org.apache.ignite.lifecycle.LifecycleAware;
 import org.apache.ignite.marshaller.Marshaller;
 import org.apache.ignite.marshaller.MarshallerUtils;
+import org.apache.ignite.marshaller.jdk.JdkMarshaller;
 import org.apache.ignite.mxbean.IgniteMBeanAware;
 import org.apache.ignite.spi.IgniteNodeValidationResult;
 import org.apache.ignite.spi.discovery.DiscoveryDataBag;
@@ -350,7 +352,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
      * @return {@code true} if cache is starting on client node and this node is affinity node for the cache.
      */
     private boolean storesLocallyOnClient(IgniteConfiguration c, CacheConfiguration cc) {
-        if (c.isClientMode() && c.getMemoryConfiguration() == null) {
+        if (c.isClientMode() && c.getDataStorageConfiguration() == null) {
             if (cc.getCacheMode() == LOCAL)
                 return true;
 
@@ -385,8 +387,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         }
 
         if (storesLocallyOnClient(c, cc))
-            throw new IgniteCheckedException("MemoryPolicy for client caches must be explicitly configured " +
-                "on client node startup. Use MemoryConfiguration to configure MemoryPolicy.");
+            throw new IgniteCheckedException("DataRegion for client caches must be explicitly configured " +
+                "on client node startup. Use DataStorageConfiguration to configure DataRegion.");
 
         if (cc.getCacheMode() == LOCAL && !cc.getAffinity().getClass().equals(LocalAffinityFunction.class))
             U.warn(log, "AffinityFunction configuration parameter will be ignored for local cache [cacheName=" +
@@ -679,8 +681,8 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
             CacheType cacheType = cacheType(cacheName);
 
-            if (cacheType != CacheType.USER && cfg.getMemoryPolicyName() == null)
-                cfg.setMemoryPolicyName(sharedCtx.database().systemMemoryPolicyName());
+            if (cacheType != CacheType.USER && cfg.getDataRegionName() == null)
+                cfg.setDataRegionName(sharedCtx.database().systemDateRegionName());
 
             if (!cacheType.userCache())
                 stopSeq.addLast(cacheName);
@@ -1112,12 +1114,10 @@ public class GridCacheProcessor extends GridProcessorAdapter {
 
         cacheCtx.onStarted();
 
-        String memPlcName = cfg.getMemoryPolicyName();
-
-        if (memPlcName == null
-            && ctx.config().getMemoryConfiguration() != null)
-            memPlcName = ctx.config().getMemoryConfiguration().getDefaultMemoryPolicyName();
+        String memPlcName = cfg.getDataRegionName();
 
+        if (memPlcName == null && ctx.config().getDataStorageConfiguration() != null)
+            memPlcName = ctx.config().getDataStorageConfiguration().getDefaultDataRegionConfiguration().getName();
 
         if (log.isInfoEnabled()) {
             log.info("Started cache [name=" + cfg.getName() +
@@ -1841,9 +1841,9 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         throws IgniteCheckedException {
         CacheConfiguration cfg = new CacheConfiguration(desc.config());
 
-        String memPlcName = cfg.getMemoryPolicyName();
+        String memPlcName = cfg.getDataRegionName();
 
-        MemoryPolicy memPlc = sharedCtx.database().memoryPolicy(memPlcName);
+        DataRegion memPlc = sharedCtx.database().dataRegion(memPlcName);
         FreeList freeList = sharedCtx.database().freeList(memPlcName);
         ReuseList reuseList = sharedCtx.database().reuseList(memPlcName);
 
@@ -2188,7 +2188,7 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         IgnitePageStoreManager pageStoreMgr = null;
         IgniteWriteAheadLogManager walMgr = null;
 
-        if (ctx.config().isPersistentStoreEnabled() && !ctx.clientNode()) {
+        if (CU.isPersistenceEnabled(ctx.config()) && !ctx.clientNode()) {
             if (ctx.clientNode()) {
                 U.warn(log, "Persistent Store is not supported on client nodes (Persistent Store's" +
                     " configuration will be ignored).");
@@ -3062,15 +3062,32 @@ public class GridCacheProcessor extends GridProcessorAdapter {
         if (ctx.config().isClientMode() || locNode.isDaemon() || rmt.isClient() || rmt.isDaemon())
             return;
 
-        MemoryConfiguration memCfg = rmt.attribute(IgniteNodeAttributes.ATTR_MEMORY_CONFIG);
+        DataStorageConfiguration dsCfg = null;
+
+        Object dsCfgBytes = rmt.attribute(IgniteNodeAttributes.ATTR_DATA_STORAGE_CONFIG);
+
+        if (dsCfgBytes instanceof byte[])
+            dsCfg = new JdkMarshaller().unmarshal((byte[])dsCfgBytes, U.resolveClassLoader(ctx.config()));
+
+        if (dsCfg == null) {
+            // Try to use legacy memory configuration.
+            MemoryConfiguration memCfg = rmt.attribute(IgniteNodeAttributes.ATTR_MEMORY_CONFIG);
+
+            if (memCfg != null) {
+                dsCfg = new DataStorageConfiguration();
+
+                // All properties that are used in validation should be converted here.
+                dsCfg.setPageSize(memCfg.getPageSize());
+            }
+        }
 
-        if (memCfg != null) {
-            MemoryConfiguration locMemCfg = ctx.config().getMemoryConfiguration();
+        if (dsCfg != null) {
+            DataStorageConfiguration locDsCfg = ctx.config().getDataStorageConfiguration();
 
-            if (memCfg.getPageSize() != locMemCfg.getPageSize()) {
+            if (dsCfg.getPageSize() != locDsCfg.getPageSize()) {
                 throw new IgniteCheckedException("Memory configuration mismatch (fix configuration or set -D" +
                     IGNITE_SKIP_CONFIGURATION_CONSISTENCY_CHECK + "=true system property) [rmtNodeId=" + rmt.id() +
-                    ", locPageSize = " + locMemCfg.getPageSize() + ", rmtPageSize = " + memCfg.getPageSize() + "]");
+                    ", locPageSize = " + locDsCfg.getPageSize() + ", rmtPageSize = " + dsCfg.getPageSize() + "]");
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
index 4f76875..26e2254 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheUtils.java
@@ -53,6 +53,8 @@ import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction;
 import org.apache.ignite.cache.store.CacheStoreSessionListener;
 import org.apache.ignite.cluster.ClusterNode;
 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.configuration.TransactionConfiguration;
 import org.apache.ignite.internal.GridKernalContext;
@@ -1673,4 +1675,57 @@ public class GridCacheUtils {
             cfg.clearQueryEntities().setQueryEntities(normalEntities);
         }
     }
+
+    /**
+     * Checks if cache configuration belongs to persistent cache.
+     *
+     * @param ccfg Cache configuration.
+     * @param dsCfg Data storage config.
+     */
+    public static boolean isPersistentCache(CacheConfiguration ccfg, DataStorageConfiguration dsCfg) {
+        if (dsCfg == null)
+            return false;
+
+        String regName = ccfg.getDataRegionName();
+
+        if (regName == null || regName.equals(dsCfg.getDefaultDataRegionConfiguration().getName()))
+            return dsCfg.getDefaultDataRegionConfiguration().isPersistenceEnabled();
+
+        if (dsCfg.getDataRegionConfigurations() != null) {
+            for (DataRegionConfiguration drConf : dsCfg.getDataRegionConfigurations()) {
+                if (regName.equals(drConf.getName()))
+                    return drConf.isPersistenceEnabled();
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * @return {@code true} if persistence is enabled for at least one data region, {@code false} if not.
+     */
+    public static boolean isPersistenceEnabled(IgniteConfiguration cfg) {
+        if (cfg.getDataStorageConfiguration() == null)
+            return false;
+
+        DataRegionConfiguration dfltReg = cfg.getDataStorageConfiguration().getDefaultDataRegionConfiguration();
+
+        if (dfltReg == null)
+            return false;
+
+        if (dfltReg.isPersistenceEnabled())
+            return true;
+
+        DataRegionConfiguration[] regCfgs = cfg.getDataStorageConfiguration().getDataRegionConfigurations();
+
+        if (regCfgs == null)
+            return false;
+
+        for (DataRegionConfiguration regCfg : regCfgs) {
+            if (regCfg.isPersistenceEnabled())
+                return true;
+        }
+
+        return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheOffheapManagerImpl.java
----------------------------------------------------------------------
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 4844686..7944c50 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
@@ -148,7 +148,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
             pendingEntries = new PendingEntriesTree(
                 grp,
                 name,
-                grp.memoryPolicy().pageMemory(),
+                grp.dataRegion().pageMemory(),
                 rootPage,
                 grp.reuseList(),
                 true);
@@ -794,7 +794,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
         long pageId;
 
         if (reuseList == null || (pageId = reuseList.takeRecycledPage()) == 0L)
-            pageId = grp.memoryPolicy().pageMemory().allocatePage(grp.groupId(), INDEX_PARTITION, FLAG_IDX);
+            pageId = grp.dataRegion().pageMemory().allocatePage(grp.groupId(), INDEX_PARTITION, FLAG_IDX);
 
         return pageId;
     }
@@ -1435,7 +1435,7 @@ public class IgniteCacheOffheapManagerImpl implements IgniteCacheOffheapManager
             if (row != null) {
                 row.key(key);
 
-                grp.memoryPolicy().evictionTracker().touchPage(row.link());
+                grp.dataRegion().evictionTracker().touchPage(row.link());
             }
 
             return row;

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
index 420cde5..19514c0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/binary/BinaryMetadataFileStore.java
@@ -24,6 +24,7 @@ import org.apache.ignite.IgniteCheckedException;
 import org.apache.ignite.IgniteLogger;
 import org.apache.ignite.internal.GridKernalContext;
 import org.apache.ignite.internal.binary.BinaryMetadata;
+import org.apache.ignite.internal.util.typedef.internal.CU;
 import org.apache.ignite.internal.util.typedef.internal.U;
 import org.jetbrains.annotations.Nullable;
 
@@ -62,7 +63,7 @@ class BinaryMetadataFileStore {
         this.ctx = ctx;
         this.log = log;
 
-        if (!ctx.config().isPersistentStoreEnabled())
+        if (!CU.isPersistenceEnabled(ctx.config()))
             return;
 
         if (binaryMetadataFileStoreDir != null)
@@ -85,7 +86,7 @@ class BinaryMetadataFileStore {
      * @param binMeta Binary metadata to be written to disk.
      */
     void saveMetadata(BinaryMetadata binMeta) {
-        if (!ctx.config().isPersistentStoreEnabled())
+        if (!CU.isPersistenceEnabled(ctx.config()))
             return;
 
         try {
@@ -107,7 +108,7 @@ class BinaryMetadataFileStore {
      * Restores metadata on startup of {@link CacheObjectBinaryProcessorImpl} but before starting discovery.
      */
     void restoreMetadata() {
-        if (!ctx.config().isPersistentStoreEnabled())
+        if (!CU.isPersistenceEnabled(ctx.config()))
             return;
 
         for (File file : workDir.listFiles()) {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index e5bcc46..7a10c10 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -556,7 +556,8 @@ public abstract class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
 
                                             GridCacheVersion dhtVer = cached.isNear() ? writeVersion() : null;
 
-                                            if (!near() && cctx.wal() != null && op != NOOP && op != RELOAD && op != READ) {
+                                            if (!near() && cacheCtx.group().persistenceEnabled() &&
+                                                op != NOOP && op != RELOAD && op != READ) {
                                                 if (dataEntries == null)
                                                     dataEntries = new ArrayList<>(entries.size());
 
@@ -741,7 +742,7 @@ public abstract class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
                                 }
                             }
 
-                            if (!near() && cctx.wal() != null)
+                            if (!near() && !F.isEmpty(dataEntries) && cctx.wal() != null)
                                 cctx.wal().log(new DataRecord(dataEntries));
 
                             if (ptr != null)

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
index c363729..cedd466 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtLocalPartition.java
@@ -500,7 +500,7 @@ public class GridDhtLocalPartition extends GridCacheConcurrentMapImpl implements
      * @return {@code true} if cas succeeds.
      */
     private boolean casState(long state, GridDhtPartitionState toState) {
-        if (ctx.database().persistenceEnabled()) {
+        if (ctx.database().persistenceEnabled() && grp.dataRegion().config().isPersistenceEnabled()) {
             synchronized (this) {
                 boolean update = this.state.compareAndSet(state, setPartState(state, toState));
 

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
index 30614a3..5095f45 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/atomic/GridDhtAtomicCache.java
@@ -61,7 +61,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheReturn;
 import org.apache.ignite.internal.processors.cache.GridCacheUpdateAtomicResult;
 import org.apache.ignite.internal.processors.cache.IgniteCacheExpiryPolicy;
 import org.apache.ignite.internal.processors.cache.KeyCacheObject;
-import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
 import org.apache.ignite.internal.processors.cache.persistence.CacheDataRow;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter;
 import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
@@ -1699,7 +1698,7 @@ public class GridDhtAtomicCache<K, V> extends GridDhtCacheAdapter<K, V> {
         ctx.shared().database().checkpointReadLock();
 
         try {
-            ctx.shared().database().ensureFreeSpace(ctx.memoryPolicy());
+            ctx.shared().database().ensureFreeSpace(ctx.dataRegion());
 
             // If batch store update is enabled, we need to lock all entries.
             // First, need to acquire locks on cache entries, then check filter.

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
index 1bffac4..dcb167d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearGetRequest.java
@@ -47,7 +47,7 @@ import org.apache.ignite.plugin.extensions.communication.MessageWriter;
 import org.jetbrains.annotations.NotNull;
 
 /**
- * Get request. Responsible for obtaining entry from primary node. 'Near' means 'Primary' here, not 'Near Cache'.
+ * Get request. Responsible for obtaining entry from primary node. 'Near' means 'Initiating node' here, not 'Near Cache'.
  */
 public class GridNearGetRequest extends GridCacheIdMessage implements GridCacheDeployable,
     GridCacheVersionable {

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
index b48693d..f736cae 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearLockRequest.java
@@ -40,7 +40,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
- * Near cache lock request.
+ * Near cache lock request to primary node. 'Near' means 'Initiating node' here, not 'Near Cache'.
  */
 public class GridNearLockRequest extends GridDistributedLockRequest {
     /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index e73f34b..085f0b7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -2682,7 +2682,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter implements GridTimeou
                                 GridCacheEntryEx entry = cacheCtx.cache().entryEx(key, topVer);
 
                                 try {
-                                    cacheCtx.shared().database().ensureFreeSpace(cacheCtx.memoryPolicy());
+                                    cacheCtx.shared().database().ensureFreeSpace(cacheCtx.dataRegion());
 
                                     EntryGetResult verVal = entry.versionedValue(cacheVal,
                                         ver,

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
index e352c87..063eb27 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
@@ -36,7 +36,7 @@ import org.apache.ignite.plugin.extensions.communication.MessageWriter;
 import org.jetbrains.annotations.Nullable;
 
 /**
- * Near transaction prepare request.
+ * Near transaction prepare request to primary node. 'Near' means 'Initiating node' here, not 'Near Cache'.
  */
 public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
     /** */

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
index 40d1fac..599a58c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/local/atomic/GridLocalAtomicCache.java
@@ -830,7 +830,7 @@ public class GridLocalAtomicCache<K, V> extends GridLocalCache<K, V> {
 
         CacheEntryPredicate[] filters = CU.filterArray(filter);
 
-        ctx.shared().database().ensureFreeSpace(ctx.memoryPolicy());
+        ctx.shared().database().ensureFreeSpace(ctx.dataRegion());
 
         if (writeThrough && keys.size() > 1) {
             return updateWithBatch(op,

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
index 4d75475..0fd8323 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/CacheDataRowAdapter.java
@@ -98,7 +98,7 @@ public class CacheDataRowAdapter implements CacheDataRow {
      * @throws IgniteCheckedException If failed.
      */
     public final void initFromLink(CacheGroupContext grp, RowData rowData) throws IgniteCheckedException {
-        initFromLink(grp, grp.shared(), grp.memoryPolicy().pageMemory(), rowData);
+        initFromLink(grp, grp.shared(), grp.dataRegion().pageMemory(), rowData);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegion.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegion.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegion.java
new file mode 100644
index 0000000..0b0bf2b
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegion.java
@@ -0,0 +1,84 @@
+/*
+ * 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 org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.internal.pagemem.PageMemory;
+import org.apache.ignite.internal.processors.cache.persistence.evict.PageEvictionTracker;
+
+/**
+ * Data region provides access to objects configured with {@link DataRegionConfiguration} configuration.
+ */
+public class DataRegion {
+    /** */
+    private final PageMemory pageMem;
+
+    /** */
+    private final DataRegionMetricsImpl memMetrics;
+
+    /** */
+    private final DataRegionConfiguration cfg;
+
+    /** */
+    private final PageEvictionTracker evictionTracker;
+
+    /**
+     * @param pageMem PageMemory instance.
+     * @param memMetrics DataRegionMetrics instance.
+     * @param cfg Configuration of given DataRegion.
+     * @param evictionTracker Eviction tracker.
+     */
+    public DataRegion(
+        PageMemory pageMem,
+        DataRegionConfiguration cfg,
+        DataRegionMetricsImpl memMetrics,
+        PageEvictionTracker evictionTracker
+    ) {
+        this.pageMem = pageMem;
+        this.memMetrics = memMetrics;
+        this.cfg = cfg;
+        this.evictionTracker = evictionTracker;
+    }
+
+    /**
+     *
+     */
+    public PageMemory pageMemory() {
+        return pageMem;
+    }
+
+    /**
+     * @return Config.
+     */
+    public DataRegionConfiguration config() {
+        return cfg;
+    }
+
+    /**
+     * @return Memory Metrics.
+     */
+    public DataRegionMetricsImpl memoryMetrics() {
+        return memMetrics;
+    }
+
+    /**
+     *
+     */
+    public PageEvictionTracker evictionTracker() {
+        return evictionTracker;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
new file mode 100644
index 0000000..1d570f9
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsImpl.java
@@ -0,0 +1,286 @@
+/*
+ * 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 org.apache.ignite.DataRegionMetrics;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.internal.pagemem.PageMemory;
+import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.lang.IgniteOutClosure;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.LongAdder8;
+
+/**
+ *
+ */
+public class DataRegionMetricsImpl implements DataRegionMetrics {
+    /** */
+    private final IgniteOutClosure<Float> fillFactorProvider;
+
+    /** */
+    private final LongAdder8 totalAllocatedPages = new LongAdder8();
+
+    /**
+     * Counter for number of pages occupied by large entries (one entry is larger than one page).
+     */
+    private final LongAdder8 largeEntriesPages = new LongAdder8();
+
+    /** Counter for number of dirty pages. */
+    private LongAdder8 dirtyPages = new LongAdder8();
+
+    /** */
+    private volatile boolean metricsEnabled;
+
+    /** */
+    private boolean persistenceEnabled;
+
+    /** */
+    private volatile int subInts;
+
+    /** Allocation rate calculator. */
+    private volatile HitRateMetrics allocRate = new HitRateMetrics(60_000, 5);
+
+    /** */
+    private volatile HitRateMetrics pageReplaceRate = new HitRateMetrics(60_000, 5);
+
+    /** */
+    private final DataRegionConfiguration memPlcCfg;
+
+    /** */
+    private PageMemory pageMem;
+
+    /** Time interval (in milliseconds) when allocations/evictions are counted to calculate rate. */
+    private volatile long rateTimeInterval;
+
+    /**
+     * @param memPlcCfg DataRegionConfiguration.
+    */
+    public DataRegionMetricsImpl(DataRegionConfiguration memPlcCfg) {
+        this(memPlcCfg, null);
+    }
+
+    /**
+     * @param memPlcCfg DataRegionConfiguration.
+     */
+    public DataRegionMetricsImpl(DataRegionConfiguration memPlcCfg, @Nullable IgniteOutClosure<Float> fillFactorProvider) {
+        this.memPlcCfg = memPlcCfg;
+        this.fillFactorProvider = fillFactorProvider;
+
+        metricsEnabled = memPlcCfg.isMetricsEnabled();
+
+        rateTimeInterval = memPlcCfg.getMetricsRateTimeInterval();
+
+        subInts = memPlcCfg.getMetricsSubIntervalCount();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return U.maskName(memPlcCfg.getName());
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getTotalAllocatedPages() {
+        return metricsEnabled ? totalAllocatedPages.longValue() : 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getAllocationRate() {
+        if (!metricsEnabled)
+            return 0;
+
+        return ((float) allocRate.getRate()) / rateTimeInterval;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getEvictionRate() {
+        return 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getLargeEntriesPagesPercentage() {
+        if (!metricsEnabled)
+            return 0;
+
+        return totalAllocatedPages.longValue() != 0 ?
+                (float) largeEntriesPages.doubleValue() / totalAllocatedPages.longValue()
+                : 0;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesFillFactor() {
+        if (!metricsEnabled || fillFactorProvider == null)
+            return 0;
+
+        return fillFactorProvider.apply();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getDirtyPages() {
+        if (!metricsEnabled || !persistenceEnabled)
+            return 0;
+
+        return dirtyPages.longValue();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesReplaceRate() {
+        if (!metricsEnabled || !persistenceEnabled)
+            return 0;
+
+        return ((float) pageReplaceRate.getRate()) / rateTimeInterval;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getPhysicalMemoryPages() {
+        if (!metricsEnabled || !persistenceEnabled)
+            return 0;
+
+        assert pageMem != null;
+
+        return pageMem.loadedPages();
+    }
+
+    /**
+     * Updates pageReplaceRate metric.
+     */
+    public void updatePageReplaceRate() {
+        if (metricsEnabled)
+            pageReplaceRate.onHit();
+    }
+
+    /**
+     * Increments dirtyPages counter.
+     */
+    public void incrementDirtyPages() {
+        if (metricsEnabled)
+            dirtyPages.increment();
+    }
+
+    /**
+     * Decrements dirtyPages counter.
+     */
+    public void decrementDirtyPages() {
+        if (metricsEnabled)
+            dirtyPages.decrement();
+    }
+
+    /**
+     * Resets dirtyPages counter to zero.
+     */
+    public void resetDirtyPages() {
+        if (metricsEnabled)
+            dirtyPages.reset();
+    }
+
+    /**
+     * Increments totalAllocatedPages counter.
+     */
+    public void incrementTotalAllocatedPages() {
+        if (metricsEnabled) {
+            totalAllocatedPages.increment();
+
+            updateAllocationRateMetrics();
+        }
+    }
+
+    /**
+     *
+     */
+    private void updateAllocationRateMetrics() {
+        allocRate.onHit();
+    }
+
+    /**
+     * @param intervalNum Interval number.
+     */
+    private long subInt(int intervalNum) {
+        return (rateTimeInterval * intervalNum) / subInts;
+    }
+
+    /**
+     *
+     */
+    public void incrementLargeEntriesPages() {
+        if (metricsEnabled)
+            largeEntriesPages.increment();
+    }
+
+    /**
+     *
+     */
+    public void decrementLargeEntriesPages() {
+        if (metricsEnabled)
+            largeEntriesPages.decrement();
+    }
+
+    /**
+     * Enable metrics.
+     */
+    public void enableMetrics() {
+        metricsEnabled = true;
+    }
+
+    /**
+     * Disable metrics.
+     */
+    public void disableMetrics() {
+        metricsEnabled = false;
+    }
+
+    /**
+     * @param persistenceEnabled Persistence enabled.
+     */
+    public void persistenceEnabled(boolean persistenceEnabled) {
+        this.persistenceEnabled = persistenceEnabled;
+    }
+
+    /**
+     * @param pageMem Page mem.
+     */
+    public void pageMemory(PageMemory pageMem) {
+        this.pageMem = pageMem;
+    }
+
+    /**
+     * @param rateTimeInterval Time interval (in milliseconds) used to calculate allocation/eviction rate.
+     */
+    public void rateTimeInterval(long rateTimeInterval) {
+        this.rateTimeInterval = rateTimeInterval;
+
+        allocRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+        pageReplaceRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+    }
+
+    /**
+     * Sets number of subintervals the whole rateTimeInterval will be split into to calculate allocation rate.
+     *
+     * @param subInts Number of subintervals.
+     */
+    public void subIntervals(int subInts) {
+        assert subInts > 0;
+
+        if (this.subInts == subInts)
+            return;
+
+        if (rateTimeInterval / subInts < 10)
+            subInts = (int) rateTimeInterval / 10;
+
+        allocRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+        pageReplaceRate = new HitRateMetrics((int) rateTimeInterval, subInts);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
new file mode 100644
index 0000000..141d0dc
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsMXBeanImpl.java
@@ -0,0 +1,131 @@
+/*
+ * 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 org.apache.ignite.DataRegionMetrics;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.mxbean.DataRegionMetricsMXBean;
+
+/**
+ * MBean to expose {@link DataRegionMetrics} through JMX interface.
+ */
+class DataRegionMetricsMXBeanImpl implements DataRegionMetricsMXBean {
+    /** */
+    private final DataRegionMetricsImpl memMetrics;
+
+    /** */
+    private final DataRegionConfiguration dataRegCfg;
+
+    /**
+     * @param memMetrics DataRegionMetrics instance to expose through JMX interface.
+     * @param dataRegCfg Configuration of data region this MX Bean is created for.
+     */
+    DataRegionMetricsMXBeanImpl(DataRegionMetricsImpl memMetrics,
+        DataRegionConfiguration dataRegCfg
+    ) {
+        this.memMetrics = memMetrics;
+        this.dataRegCfg = dataRegCfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getAllocationRate() {
+        return memMetrics.getAllocationRate();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getEvictionRate() {
+        return memMetrics.getEvictionRate();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getLargeEntriesPagesPercentage() {
+        return memMetrics.getLargeEntriesPagesPercentage();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesFillFactor() {
+        return memMetrics.getPagesFillFactor();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getTotalAllocatedPages() {
+        return memMetrics.getTotalAllocatedPages();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getDirtyPages() {
+        return memMetrics.getDirtyPages();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesReplaceRate() {
+        return memMetrics.getPagesReplaceRate();
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getPhysicalMemoryPages() {
+        return memMetrics.getPhysicalMemoryPages();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void rateTimeInterval(long rateTimeInterval) {
+        if (rateTimeInterval < 1000)
+            throw new IllegalArgumentException("rateTimeInterval property must be positive " +
+                "and greater than 1_000 milliseconds (one second)");
+
+        memMetrics.rateTimeInterval(rateTimeInterval);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void subIntervals(int subInts) {
+        if (subInts <= 1)
+            throw new IllegalArgumentException("subIntervals property must be positive " +
+                "and greater than one");
+
+        memMetrics.subIntervals(subInts);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void enableMetrics() {
+        memMetrics.enableMetrics();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void disableMetrics() {
+        memMetrics.disableMetrics();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return memMetrics.getName();
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getInitialSize() {
+        return (int) (dataRegCfg.getInitialSize() / (1024 * 1024));
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getMaxSize() {
+        return (int) (dataRegCfg.getMaxSize() / (1024 * 1024));
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getSwapPath() {
+        return dataRegCfg.getSwapPath();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
new file mode 100644
index 0000000..c39fdb0d
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataRegionMetricsSnapshot.java
@@ -0,0 +1,112 @@
+/*
+ * 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 org.apache.ignite.DataRegionMetrics;
+
+/**
+ *
+ */
+public class DataRegionMetricsSnapshot implements DataRegionMetrics {
+    /** */
+    private String name;
+
+    /** */
+    private long totalAllocatedPages;
+
+    /** */
+    private float allocationRate;
+
+    /** */
+    private float evictionRate;
+
+    /** */
+    private float largeEntriesPagesPercentage;
+
+    /** */
+    private float pagesFillFactor;
+
+    /** */
+    private long dirtyPages;
+
+    /** */
+    private float pageReplaceRate;
+
+    /** */
+    private long physicalMemoryPages;
+
+    /**
+     * @param metrics Metrics instance to take a copy.
+     */
+    public DataRegionMetricsSnapshot(DataRegionMetrics metrics) {
+        name = metrics.getName();
+        totalAllocatedPages = metrics.getTotalAllocatedPages();
+        allocationRate = metrics.getAllocationRate();
+        evictionRate = metrics.getEvictionRate();
+        largeEntriesPagesPercentage = metrics.getLargeEntriesPagesPercentage();
+        pagesFillFactor = metrics.getPagesFillFactor();
+        dirtyPages = metrics.getDirtyPages();
+        pageReplaceRate = metrics.getPagesReplaceRate();
+        physicalMemoryPages = metrics.getPhysicalMemoryPages();
+    }
+
+    /** {@inheritDoc} */
+    @Override public String getName() {
+        return name;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getTotalAllocatedPages() {
+        return totalAllocatedPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getAllocationRate() {
+        return allocationRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getEvictionRate() {
+        return evictionRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getLargeEntriesPagesPercentage() {
+        return largeEntriesPagesPercentage;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesFillFactor() {
+        return pagesFillFactor;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getDirtyPages() {
+        return dirtyPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getPagesReplaceRate() {
+        return pageReplaceRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getPhysicalMemoryPages() {
+        return physicalMemoryPages;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsImpl.java
new file mode 100644
index 0000000..16707aa
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsImpl.java
@@ -0,0 +1,297 @@
+/*
+ * 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 org.apache.ignite.internal.pagemem.wal.IgniteWriteAheadLogManager;
+import org.apache.ignite.internal.processors.cache.ratemetrics.HitRateMetrics;
+import org.apache.ignite.mxbean.DataStorageMetricsMXBean;
+
+/**
+ *
+ */
+public class DataStorageMetricsImpl implements DataStorageMetricsMXBean {
+    /** */
+    private volatile HitRateMetrics walLoggingRate;
+
+    /** */
+    private volatile HitRateMetrics walWritingRate;
+
+    /** */
+    private volatile HitRateMetrics walFsyncTimeDuration;
+
+    /** */
+    private volatile HitRateMetrics walFsyncTimeNumber;
+
+    /** */
+    private volatile long lastCpLockWaitDuration;
+
+    /** */
+    private volatile long lastCpMarkDuration;
+
+    /** */
+    private volatile long lastCpPagesWriteDuration;
+
+    /** */
+    private volatile long lastCpDuration;
+
+    /** */
+    private volatile long lastCpFsyncDuration;
+
+    /** */
+    private volatile long lastCpTotalPages;
+
+    /** */
+    private volatile long lastCpDataPages;
+
+    /** */
+    private volatile long lastCpCowPages;
+
+    /** */
+    private volatile long rateTimeInterval;
+
+    /** */
+    private volatile int subInts;
+
+    /** */
+    private volatile boolean metricsEnabled;
+
+    /** */
+    private IgniteWriteAheadLogManager wal;
+
+    /**
+     * @param metricsEnabled Metrics enabled flag.
+     * @param rateTimeInterval Rate time interval.
+     * @param subInts Number of sub-intervals.
+     */
+    public DataStorageMetricsImpl(
+        boolean metricsEnabled,
+        long rateTimeInterval,
+        int subInts
+    ) {
+        this.metricsEnabled = metricsEnabled;
+        this.rateTimeInterval = rateTimeInterval;
+        this.subInts = subInts;
+
+        resetRates();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalLoggingRate() {
+        if (!metricsEnabled)
+            return 0;
+
+        return ((float)walLoggingRate.getRate()) / rateTimeInterval;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalWritingRate() {
+        if (!metricsEnabled)
+            return 0;
+
+        return ((float)walWritingRate.getRate()) / rateTimeInterval;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getWalArchiveSegments() {
+        if (!metricsEnabled)
+            return 0;
+
+        return wal.walArchiveSegments();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalFsyncTimeAverage() {
+        if (!metricsEnabled)
+            return 0;
+
+        long numRate = walFsyncTimeNumber.getRate();
+
+        if (numRate == 0)
+            return 0;
+
+        return (float)walFsyncTimeDuration.getRate() / numRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointingDuration() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointLockWaitDuration() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpLockWaitDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointMarkDuration() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpMarkDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointPagesWriteDuration() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpPagesWriteDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointFsyncDuration() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpFsyncDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointTotalPagesNumber() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpTotalPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointDataPagesNumber() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpDataPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointCopiedOnWritePagesNumber() {
+        if (!metricsEnabled)
+            return 0;
+
+        return lastCpCowPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void enableMetrics() {
+        metricsEnabled = true;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void disableMetrics() {
+        metricsEnabled = false;
+    }
+
+    /** {@inheritDoc} */
+    @Override public void rateTimeInterval(long rateTimeInterval) {
+        this.rateTimeInterval = rateTimeInterval;
+
+        resetRates();
+    }
+
+    /** {@inheritDoc} */
+    @Override public void subIntervals(int subInts) {
+        this.subInts = subInts;
+
+        resetRates();
+    }
+
+    /**
+     * @param wal Write-ahead log manager.
+     */
+    public void wal(IgniteWriteAheadLogManager wal) {
+        this.wal = wal;
+    }
+
+    /**
+     * @return Metrics enabled flag.
+     */
+    public boolean metricsEnabled() {
+        return metricsEnabled;
+    }
+
+    /**
+     * @param lockWaitDuration Lock wait duration.
+     * @param markDuration Mark duration.
+     * @param pagesWriteDuration Pages write duration.
+     * @param fsyncDuration Total checkpoint fsync duration.
+     * @param duration Total checkpoint duration.
+     * @param totalPages Total number of all pages in checkpoint.
+     * @param dataPages Total number of data pages in checkpoint.
+     * @param cowPages Total number of COW-ed pages in checkpoint.
+     */
+    public void onCheckpoint(
+        long lockWaitDuration,
+        long markDuration,
+        long pagesWriteDuration,
+        long fsyncDuration,
+        long duration,
+        long totalPages,
+        long dataPages,
+        long cowPages
+    ) {
+        if (metricsEnabled) {
+            lastCpLockWaitDuration = lockWaitDuration;
+            lastCpMarkDuration = markDuration;
+            lastCpPagesWriteDuration = pagesWriteDuration;
+            lastCpFsyncDuration = fsyncDuration;
+            lastCpDuration = duration;
+            lastCpTotalPages = totalPages;
+            lastCpDataPages = dataPages;
+            lastCpCowPages = cowPages;
+        }
+    }
+
+    /**
+     *
+     */
+    public void onWalRecordLogged() {
+        walLoggingRate.onHit();
+    }
+
+    /**
+     * @param size Size written.
+     */
+    public void onWalBytesWritten(int size) {
+        walWritingRate.onHits(size);
+    }
+
+    /**
+     * @param nanoTime Fsync nano time.
+     */
+    public void onFsync(long nanoTime) {
+        long microseconds = nanoTime / 1_000;
+
+        walFsyncTimeDuration.onHits(microseconds);
+        walFsyncTimeNumber.onHit();
+    }
+
+    /**
+     *
+     */
+    private void resetRates() {
+        walLoggingRate = new HitRateMetrics((int)rateTimeInterval, subInts);
+        walWritingRate = new HitRateMetrics((int)rateTimeInterval, subInts);
+
+        walFsyncTimeDuration = new HitRateMetrics((int)rateTimeInterval, subInts);
+        walFsyncTimeNumber = new HitRateMetrics((int)rateTimeInterval, subInts);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/ec41370c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsSnapshot.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsSnapshot.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsSnapshot.java
new file mode 100644
index 0000000..4841387
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/DataStorageMetricsSnapshot.java
@@ -0,0 +1,144 @@
+/*
+ * 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 org.apache.ignite.DataStorageMetrics;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ *
+ */
+public class DataStorageMetricsSnapshot implements DataStorageMetrics {
+    /** */
+    private float walLoggingRate;
+
+    /** */
+    private float walWritingRate;
+
+    /** */
+    private int walArchiveSegments;
+
+    /** */
+    private float walFsyncTimeAvg;
+
+    /** */
+    private long lastCpDuration;
+
+    /** */
+    private long lastCpLockWaitDuration;
+
+    /** */
+    private long lastCpMmarkDuration;
+
+    /** */
+    private long lastCpPagesWriteDuration;
+
+    /** */
+    private long lastCpFsyncDuration;
+
+    /** */
+    private long lastCpTotalPages;
+
+    /** */
+    private long lastCpDataPages;
+
+    /** */
+    private long lastCpCowPages;
+
+    /**
+     * @param metrics Metrics.
+     */
+    public DataStorageMetricsSnapshot(DataStorageMetrics metrics) {
+        walLoggingRate = metrics.getWalLoggingRate();
+        walWritingRate = metrics.getWalWritingRate();
+        walArchiveSegments = metrics.getWalArchiveSegments();
+        walFsyncTimeAvg = metrics.getWalFsyncTimeAverage();
+        lastCpDuration = metrics.getLastCheckpointingDuration();
+        lastCpLockWaitDuration = metrics.getLastCheckpointLockWaitDuration();
+        lastCpMmarkDuration = metrics.getLastCheckpointMarkDuration();
+        lastCpPagesWriteDuration = metrics.getLastCheckpointPagesWriteDuration();
+        lastCpFsyncDuration = metrics.getLastCheckpointFsyncDuration();
+        lastCpTotalPages = metrics.getLastCheckpointTotalPagesNumber();
+        lastCpDataPages = metrics.getLastCheckpointDataPagesNumber();
+        lastCpCowPages = metrics.getLastCheckpointCopiedOnWritePagesNumber();
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalLoggingRate() {
+        return walLoggingRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalWritingRate() {
+        return walWritingRate;
+    }
+
+    /** {@inheritDoc} */
+    @Override public int getWalArchiveSegments() {
+        return walArchiveSegments;
+    }
+
+    /** {@inheritDoc} */
+    @Override public float getWalFsyncTimeAverage() {
+        return walFsyncTimeAvg;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointingDuration() {
+        return lastCpDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointLockWaitDuration() {
+        return lastCpLockWaitDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointMarkDuration() {
+        return lastCpMmarkDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointPagesWriteDuration() {
+        return lastCpPagesWriteDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointFsyncDuration() {
+        return lastCpFsyncDuration;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointTotalPagesNumber() {
+        return lastCpTotalPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointDataPagesNumber() {
+        return lastCpDataPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public long getLastCheckpointCopiedOnWritePagesNumber() {
+        return lastCpCowPages;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String toString() {
+        return S.toString(DataStorageMetricsSnapshot.class, this);
+    }
+}