[ 
https://issues.apache.org/jira/browse/OAK-3976?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15732050#comment-15732050
 ] 

Vikas Saurabh commented on OAK-3976:
------------------------------------

[~mreutegg], here's roughly what I am thinking of doing:
{code}
diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index 04ecfd7..c168ff0 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -185,6 +185,13 @@ public final class DocumentNodeStore
     private boolean disableJournalDiff =
diff --git 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
index 04ecfd7..c168ff0 100644
--- 
a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
+++ 
b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/DocumentNodeStore.java
@@ -185,6 +185,13 @@ public final class DocumentNodeStore
     private boolean disableJournalDiff =
             Boolean.getBoolean(SYS_PROP_DISABLE_JOURNAL);

+    public static final String SYS_PROP_JOURNAL_PUSH_THRESHOLD = 
"oak.journalPushThreshold";
+    /**
+     * Threshold for number of paths in journal entry to require a force push 
during commit
+     * (instead of at background write)
+     */
+    static int journalPushThreshold = 100000; //non-final to allow for tests.
+
     /**
      * The document store (might be used by multiple node stores).
      */
@@ -790,6 +797,7 @@ public final class DocumentNodeStore
                         changes.addChangeSet(getChangeSet(info));
                         // update head revision
                         newHead[0] = before.update(c.getRevision());
+                        pushJournalEntry(c.getRevision(), false);
                         setRoot(newHead[0]);
                         commitQueue.headRevisionChanged();
                         dispatcher.contentChanged(getRoot(), info);
@@ -2142,19 +2150,32 @@ public final class DocumentNodeStore
         return unsavedLastRevisions.persist(this, new 
UnsavedModifications.Snapshot() {
             @Override
             public void acquiring(Revision mostRecent) {
-                if (store.create(JOURNAL, 
singletonList(changes.asUpdateOp(mostRecent)))) {
-                    // success: start with a new document
-                    changes = newJournalEntry();
-                } else {
-                    // fail: log and keep the changes
-                    LOG.error("Failed to write to journal, accumulating 
changes for future write (~" + changes.getMemory()
-                            + " bytes).");
-                }
+                pushJournalEntry(mostRecent, true);
             }
         }, backgroundOperationLock.writeLock());
     }

     //-----------------------------< internal 
>---------------------------------
+    private ReadWriteLock journalPushLock = new ReentrantReadWriteLock();
+    void pushJournalEntry(Revision r, boolean force) {
+        if (!force && changes.getNumChangedPaths() < journalPushThreshold) {
+            return;
+        }
+        journalPushLock.writeLock().lock();
+        try {
+            if (store.create(JOURNAL, singletonList(changes.asUpdateOp(r)))) {
+                // success: start with a new document
+                changes = newJournalEntry();
+            } else {
+                // fail: log and keep the changes
+                LOG.error("Failed to write to journal, accumulating changes 
for future write (~" + changes.getMemory()
+                        + " bytes).");
+            }
+        } finally {
+            journalPushLock.writeLock().unlock();
+        }
+
+    }

     /**
      * Returns the binary size of a property value represented as a JSON or
{code}
A few things that I think were important to take care of:
* Commit (if required) should push journal entry before it sets new head
* minimize journal push critical section

This way things are currently, I'm not completely confident of:
# commit clears journal and pushes an entry with its own revision V/s bkWrite 
checked unsavedLastRevs to find the latest rev
#* I'm not sure if commit's rev could be bigger that highest-last-rev. Also, 
does it matter?
# BkWrite can now potentially create empty journal entries. Should we avoid 
that?

> journal should support large(r) entries
> ---------------------------------------
>
>                 Key: OAK-3976
>                 URL: https://issues.apache.org/jira/browse/OAK-3976
>             Project: Jackrabbit Oak
>          Issue Type: Improvement
>          Components: documentmk
>    Affects Versions: 1.3.14
>            Reporter: Stefan Egli
>            Assignee: Vikas Saurabh
>             Fix For: 1.6, 1.5.16
>
>
> Journal entries are created in the background write. Normally this happens 
> every second. If for some reason there is a large delay between two 
> background writes, the number of pending changes can also accumulate. Which 
> can result in (arbitrary) large single journal entries (ie with large {{_c}} 
> property).
> This can cause multiple problems down the road:
> * journal gc at this point loads 450 entries - and if some are large this can 
> result in a very large memory consumption during gc (which can cause severe 
> stability problems for the VM, if not OOM etc). This should be fixed with 
> OAK-3001 (where we only get the id, thus do not care how big {{_c}} is)
> * before OAK-3001 is done (which is currently scheduled after 1.4) what we 
> can do is reduce the delete batch size (OAK-3975)
> * background reads however also read the journal entries and even if 
> OAK-3001/OAK-3975 are implemented the background read can still cause large 
> memory consumption. So we need to improve this one way or another.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to