You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2021/02/11 13:25:17 UTC

[ignite] branch master updated: IGNITE-14140 Checkpointer thread holds write lock too long (#8772)

This is an automated email from the ASF dual-hosted git repository.

ibessonov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 652f69d  IGNITE-14140 Checkpointer thread holds write lock too long (#8772)
652f69d is described below

commit 652f69d9b4c61658eaaa43dc6f3df5ec85104b88
Author: Vladislav Pyatkov <vl...@gmail.com>
AuthorDate: Thu Feb 11 16:25:02 2021 +0300

    IGNITE-14140 Checkpointer thread holds write lock too long (#8772)
---
 .../cache/persistence/GridCacheOffheapManager.java |  3 ++
 .../cache/persistence/freelist/PagesList.java      | 38 ++++++++++++++++++++--
 2 files changed, 39 insertions(+), 2 deletions(-)

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 e9a956d..7f4af90 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
@@ -261,6 +261,9 @@ public class GridCacheOffheapManager extends IgniteCacheOffheapManagerImpl imple
         assert grp.dataRegion().pageMemory() instanceof PageMemoryEx;
 
         syncMetadata(ctx);
+
+        // Double flushing memory buckets for decrease a time on write lock.
+        syncMetadata(ctx, ctx.executor(), false);
     }
 
     /** {@inheritDoc} */
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
index bf66500..a7166a6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/persistence/freelist/PagesList.java
@@ -112,6 +112,9 @@ public abstract class PagesList extends DataStructure {
     /** */
     protected volatile boolean changed;
 
+    /** Page cache changed. */
+    protected volatile boolean pageCacheChanged;
+
     /** Page ID to store list metadata. */
     private final long metaPageId;
 
@@ -376,13 +379,20 @@ public abstract class PagesList extends DataStructure {
 
     /**
      * Flush onheap cached pages lists to page memory.
+     *
+     * @param statHolder Statistic holder.
+     * @throws IgniteCheckedException If failed to write a page.
      */
     private void flushBucketsCache(IoStatisticsHolder statHolder) throws IgniteCheckedException {
-        if (!isCachingApplicable())
+        if (!isCachingApplicable() || !pageCacheChanged)
             return;
 
+        pageCacheChanged = false;
+
         onheapListCachingEnabled = false;
 
+        int lockedPages = 0;
+
         try {
             for (int bucket = 0; bucket < buckets; bucket++) {
                 PagesCache pagesCache = getBucketCache(bucket, false);
@@ -406,6 +416,8 @@ public abstract class PagesList extends DataStructure {
                         if (res == null) {
                             // Return page to onheap pages list if can't lock it.
                             pagesCache.add(pageId);
+
+                            lockedPages++;
                         }
                     }
                 }
@@ -414,6 +426,14 @@ public abstract class PagesList extends DataStructure {
         finally {
             onheapListCachingEnabled = true;
         }
+
+        if (lockedPages != 0) {
+            if (log.isInfoEnabled())
+                log.info("Several pages were locked and weren't flushed on disk [grp=" + grpName
+                    + ", lockedPages=" + lockedPages + ']');
+
+            pageCacheChanged = true;
+        }
     }
 
     /**
@@ -988,6 +1008,8 @@ public abstract class PagesList extends DataStructure {
                     wal.log(new DataPageSetFreeListPageRecord(grpId, dataId, 0L));
             }
 
+            pageCacheChanged();
+
             return true;
         }
         else
@@ -1927,6 +1949,15 @@ public abstract class PagesList extends DataStructure {
     }
 
     /**
+     * Mark free list page cache was changed.
+     */
+    private void pageCacheChanged() {
+        // Ok to have a race here, see the field javadoc.
+        if (!pageCacheChanged)
+            pageCacheChanged = true;
+    }
+
+    /**
      * Pages list name.
      */
     public String name() {
@@ -2148,7 +2179,7 @@ public abstract class PagesList extends DataStructure {
             if (size == 0) {
                 boolean stripesChanged = false;
 
-                if (++emptyFlushCnt >= EMPTY_FLUSH_GC_THRESHOLD) {
+                if (emptyFlushCnt >= 0 && ++emptyFlushCnt >= EMPTY_FLUSH_GC_THRESHOLD) {
                     for (int i = 0; i < STRIPES_COUNT; i++) {
                         synchronized (stripeLocks[i]) {
                             GridLongList stripe = stripes[i];
@@ -2165,6 +2196,9 @@ public abstract class PagesList extends DataStructure {
                             }
                         }
                     }
+
+                    if (!stripesChanged)
+                        emptyFlushCnt = -1;
                 }
 
                 if (!stripesChanged)