You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-dev@jackrabbit.apache.org by TALHAOUI Mohamed <m....@rsd.com> on 2014/10/06 18:17:46 UTC

OakMerge0001: Failed to merge changes to the underlying store

HI,

Sorry if this is not the right place to post but I have an issue with a simple POC using Oak 1.1.0 and MongoDB as a node store.
I would appreciate any help / hints on resolving this issue.

Thanks

I am getting the following exception:
java.lang.RuntimeException: org.apache.jackrabbit.oak.api.CommitFailedException: OakMerge0001: OakMerge0001: Failed to merge changes to the underlying store (retries 5, 4848 ms)
       at org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakInitializer.java:64)
       at org.apache.jackrabbit.oak.Oak.createContentRepository(Oak.java:551)
       at org.apache.jackrabbit.oak.jcr.Jcr.createRepository(Jcr.java:196)
       at com.rsd.glass.oak.Poc.main(Poc.java:44)
Caused by: org.apache.jackrabbit.oak.api.CommitFailedException: OakMerge0001: OakMerge0001: Failed to merge changes to the underlying store (retries 5, 4848 ms)
       at org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch.merge(AbstractNodeStoreBranch.java:341)
       at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch.merge(DocumentNodeStoreBranch.java:161)
       at org.apache.jackrabbit.oak.plugins.document.DocumentRootBuilder.merge(DocumentRootBuilder.java:159)
       at org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.merge(DocumentNodeStore.java:1290)
       at org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakInitializer.java:62)

Here is my code:

public class Poc {

       public static void main(String args[]) {

             Session session = null;
             try {
                    MongoConnection connection = new MongoConnection("127.0.0.1", 27017, "oak");
                    DB db = connection.getDB();

                    DocumentMK.Builder builder = new DocumentMK.Builder();
                    builder.setMongoDB(db);

                    NodeStore nodeStore = new DocumentNodeStore(builder);
                    Repository repository = new Jcr(nodeStore).createRepository();
                    session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));

                    Poc poc = new Poc();

                    NodeTypeManager ntm = session.getWorkspace().getNodeTypeManager();
                    CndImporter.registerNodeTypes(new FileReader("src/main/resources/myMetadata.cnd"), session, true);

                    poc.buildContent(session, poc, ntm);

                    session.save();

                    // Retrieve content
                    Node rootNode = session.getRootNode();
                    Node node = rootNode.getNode("Policies/HR/Contracts");
                    System.out.println(node.getPath());

                    System.exit(0);
             } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.exit(-1);
             } finally {
                    if (session != null) {
                           session.logout();
                    }
             }

       }

       private void buildContent(Session session, Poc poc, NodeTypeManager ntm) throws Exception {

             if (session.itemExists("/Policies")) {
                    session.removeItem("/Policies");
             }

             // Create Policies tree
             Node rootNode = session.getRootNode();
             Node policiesNode = rootNode.addNode("Policies", "my:policy");
             Node hrNode = policiesNode.addNode("HR", "my:policy");
             hrNode.setProperty("my:metadata", "hr");
             Node contractsNode = hrNode.addNode("Contracts", "my:policy");
             contractsNode.setProperty("my:metadata", "contract");

       }

}


RE: OakMerge0001: Failed to merge changes to the underlying store

Posted by TALHAOUI Mohamed <m....@rsd.com>.
Thanks a lot, it is working much better now.

-----Original Message-----
From: Marcel Reutegger [mailto:mreutegg@adobe.com] 
Sent: mardi 7 octobre 2014 10:59
To: oak-dev@jackrabbit.apache.org
Subject: Re: OakMerge0001: Failed to merge changes to the underlying store 

Hi,

you forgot to shut down the DocumentNodeStore. You need to add this do your finally clause:

if (nodeStore != null) {
    nodeStore.dispose();
}


It isn't intuitive why this leads to this exception, but let me try to explain.

The DocumentNodeStore allows deployments with multiple instances working in a cluster. Each instance has a unique clusterId, which is maintained in MongoDB with a lease time. Now, if you just exit without shutting down the store, the lease is not removed and a subsequent start will use a different clusterId. This means, the store will look at the data in MongoDB from a different cluster node point of view.

Changes from other cluster nodes are not visible immediately. Each cluster node periodically makes its changes visible to others by updating the _lastRev on the root document in MongoDB. Similarly they pick up other changes periodically. Per default this happens every second. If you don't shut down the store you will leave some changes in a state not visible to other cluster nodes (or as in your case a subsequent startup with a different clusterId). It will then try to create the initial content again and fail with a conflict because it is already there, but just not yet visible.

There is a recovery mechanism built into the DocumentNodeStore to make these kind of changes visible if an instance crashes or is not shut down properly. However, this process is only triggered when you deploy Oak in an OSGi container.
See DocumentNodeStoreService.registerLastRevRecoveryJob()

Regards
 Marcel

On 06/10/14 18:17, "TALHAOUI Mohamed" <m....@rsd.com> wrote:

>HI,
>
>Sorry if this is not the right place to post but I have an issue with a 
>simple POC using Oak 1.1.0 and MongoDB as a node store.
>I would appreciate any help / hints on resolving this issue.
>
>Thanks
>
>I am getting the following exception:
>java.lang.RuntimeException:
>org.apache.jackrabbit.oak.api.CommitFailedException: OakMerge0001:
>OakMerge0001: Failed to merge changes to the underlying store (retries 
>5,
>4848 ms)
>       at
>org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakIn
>iti
>alizer.java:64)
>       at
>org.apache.jackrabbit.oak.Oak.createContentRepository(Oak.java:551)
>       at org.apache.jackrabbit.oak.jcr.Jcr.createRepository(Jcr.java:196)
>       at com.rsd.glass.oak.Poc.main(Poc.java:44)
>Caused by: org.apache.jackrabbit.oak.api.CommitFailedException:
>OakMerge0001: OakMerge0001: Failed to merge changes to the underlying 
>store (retries 5, 4848 ms)
>       at
>org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch.merge(Abstr
>act
>NodeStoreBranch.java:341)
>       at
>org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch.merg
>e(D
>ocumentNodeStoreBranch.java:161)
>       at
>org.apache.jackrabbit.oak.plugins.document.DocumentRootBuilder.merge(Do
>cum
>entRootBuilder.java:159)
>       at
>org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.merge(Docu
>men
>tNodeStore.java:1290)
>       at
>org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakIn
>iti
>alizer.java:62)
>
>Here is my code:
>
>public class Poc {
>
>       public static void main(String args[]) {
>
>             Session session = null;
>             try {
>                    MongoConnection connection = new 
>MongoConnection("127.0.0.1", 27017, "oak");
>                    DB db = connection.getDB();
>
>                    DocumentMK.Builder builder = new DocumentMK.Builder();
>                    builder.setMongoDB(db);
>
>                    NodeStore nodeStore = new DocumentNodeStore(builder);
>                    Repository repository = new 
>Jcr(nodeStore).createRepository();
>                    session = repository.login(new 
>SimpleCredentials("admin", "admin".toCharArray()));
>
>                    Poc poc = new Poc();
>
>                    NodeTypeManager ntm = 
>session.getWorkspace().getNodeTypeManager();
>                    CndImporter.registerNodeTypes(new 
>FileReader("src/main/resources/myMetadata.cnd"), session, true);
>
>                    poc.buildContent(session, poc, ntm);
>
>                    session.save();
>
>                    // Retrieve content
>                    Node rootNode = session.getRootNode();
>                    Node node = rootNode.getNode("Policies/HR/Contracts");
>                    System.out.println(node.getPath());
>
>                    System.exit(0);
>             } catch (Exception e) {
>                    // TODO Auto-generated catch block
>                    e.printStackTrace();
>                    System.exit(-1);
>             } finally {
>                    if (session != null) {
>                           session.logout();
>                    }
>             }
>
>       }
>
>       private void buildContent(Session session, Poc poc, 
>NodeTypeManager ntm) throws Exception {
>
>             if (session.itemExists("/Policies")) {
>                    session.removeItem("/Policies");
>             }
>
>             // Create Policies tree
>             Node rootNode = session.getRootNode();
>             Node policiesNode = rootNode.addNode("Policies", 
>"my:policy");
>             Node hrNode = policiesNode.addNode("HR", "my:policy");
>             hrNode.setProperty("my:metadata", "hr");
>             Node contractsNode = hrNode.addNode("Contracts", 
>"my:policy");
>             contractsNode.setProperty("my:metadata", "contract");
>
>       }
>
>}
>


Re: OakMerge0001: Failed to merge changes to the underlying store

Posted by Marcel Reutegger <mr...@adobe.com>.
Hi,

you forgot to shut down the DocumentNodeStore. You need to add
this do your finally clause:

if (nodeStore != null) {
    nodeStore.dispose();
}


It isn't intuitive why this leads to this exception, but let me
try to explain.

The DocumentNodeStore allows deployments with multiple instances
working in a cluster. Each instance has a unique clusterId, which
is maintained in MongoDB with a lease time. Now, if you just exit
without shutting down the store, the lease is not removed and a
subsequent start will use a different clusterId. This means, the
store will look at the data in MongoDB from a different cluster
node point of view.

Changes from other cluster nodes are not visible immediately. Each
cluster node periodically makes its changes visible to others
by updating the _lastRev on the root document in MongoDB. Similarly
they pick up other changes periodically. Per default this happens
every second. If you don't shut down the store you will leave some
changes in a state not visible to other cluster nodes (or as in
your case a subsequent startup with a different clusterId). It
will then try to create the initial content again and fail with
a conflict because it is already there, but just not yet visible.

There is a recovery mechanism built into the DocumentNodeStore to
make these kind of changes visible if an instance crashes or is
not shut down properly. However, this process is only triggered
when you deploy Oak in an OSGi container.
See DocumentNodeStoreService.registerLastRevRecoveryJob()

Regards
 Marcel

On 06/10/14 18:17, "TALHAOUI Mohamed" <m....@rsd.com> wrote:

>HI,
>
>Sorry if this is not the right place to post but I have an issue with a
>simple POC using Oak 1.1.0 and MongoDB as a node store.
>I would appreciate any help / hints on resolving this issue.
>
>Thanks
>
>I am getting the following exception:
>java.lang.RuntimeException:
>org.apache.jackrabbit.oak.api.CommitFailedException: OakMerge0001:
>OakMerge0001: Failed to merge changes to the underlying store (retries 5,
>4848 ms)
>       at 
>org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakIniti
>alizer.java:64)
>       at 
>org.apache.jackrabbit.oak.Oak.createContentRepository(Oak.java:551)
>       at org.apache.jackrabbit.oak.jcr.Jcr.createRepository(Jcr.java:196)
>       at com.rsd.glass.oak.Poc.main(Poc.java:44)
>Caused by: org.apache.jackrabbit.oak.api.CommitFailedException:
>OakMerge0001: OakMerge0001: Failed to merge changes to the underlying
>store (retries 5, 4848 ms)
>       at 
>org.apache.jackrabbit.oak.spi.state.AbstractNodeStoreBranch.merge(Abstract
>NodeStoreBranch.java:341)
>       at 
>org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreBranch.merge(D
>ocumentNodeStoreBranch.java:161)
>       at 
>org.apache.jackrabbit.oak.plugins.document.DocumentRootBuilder.merge(Docum
>entRootBuilder.java:159)
>       at 
>org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore.merge(Documen
>tNodeStore.java:1290)
>       at 
>org.apache.jackrabbit.oak.spi.lifecycle.OakInitializer.initialize(OakIniti
>alizer.java:62)
>
>Here is my code:
>
>public class Poc {
>
>       public static void main(String args[]) {
>
>             Session session = null;
>             try {
>                    MongoConnection connection = new
>MongoConnection("127.0.0.1", 27017, "oak");
>                    DB db = connection.getDB();
>
>                    DocumentMK.Builder builder = new DocumentMK.Builder();
>                    builder.setMongoDB(db);
>
>                    NodeStore nodeStore = new DocumentNodeStore(builder);
>                    Repository repository = new
>Jcr(nodeStore).createRepository();
>                    session = repository.login(new
>SimpleCredentials("admin", "admin".toCharArray()));
>
>                    Poc poc = new Poc();
>
>                    NodeTypeManager ntm =
>session.getWorkspace().getNodeTypeManager();
>                    CndImporter.registerNodeTypes(new
>FileReader("src/main/resources/myMetadata.cnd"), session, true);
>
>                    poc.buildContent(session, poc, ntm);
>
>                    session.save();
>
>                    // Retrieve content
>                    Node rootNode = session.getRootNode();
>                    Node node = rootNode.getNode("Policies/HR/Contracts");
>                    System.out.println(node.getPath());
>
>                    System.exit(0);
>             } catch (Exception e) {
>                    // TODO Auto-generated catch block
>                    e.printStackTrace();
>                    System.exit(-1);
>             } finally {
>                    if (session != null) {
>                           session.logout();
>                    }
>             }
>
>       }
>
>       private void buildContent(Session session, Poc poc,
>NodeTypeManager ntm) throws Exception {
>
>             if (session.itemExists("/Policies")) {
>                    session.removeItem("/Policies");
>             }
>
>             // Create Policies tree
>             Node rootNode = session.getRootNode();
>             Node policiesNode = rootNode.addNode("Policies",
>"my:policy");
>             Node hrNode = policiesNode.addNode("HR", "my:policy");
>             hrNode.setProperty("my:metadata", "hr");
>             Node contractsNode = hrNode.addNode("Contracts",
>"my:policy");
>             contractsNode.setProperty("my:metadata", "contract");
>
>       }
>
>}
>