Index: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java =================================================================== --- oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java (revision 1767067) +++ oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java (working copy) @@ -183,7 +183,16 @@ @Override public boolean childNodeChanged(String name, NodeState before, NodeState after) { - return process(name, "childNodeChanged", before, after); + try { + return process(name, "childNodeChanged", before, after); + } catch (RuntimeException e) { + log.trace("Check binaries for node {} and retry to process childNodeChanged", name); + // Attempt to load the binaries and retry, see OAK-4969 + for (PropertyState propertyState : after.getProperties()) { + binaryCheck(propertyState); + } + return process(name, "childNodeChanged", before, after); + } } private boolean process(String name, String op, NodeState before, NodeState after) { Index: oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/DataStoreTestBase.java =================================================================== --- oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/DataStoreTestBase.java (revision 1767067) +++ oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/DataStoreTestBase.java (working copy) @@ -101,7 +101,38 @@ assertArrayEquals(data, testData); } + /** + * See OAK-4969 + */ @Test + public void testSyncUpdatedBinaryProperty() throws Exception { + + final int mb = 1 * 1024 * 1024; + final int blobSize = 5 * mb; + + FileStore primary = getPrimary(); + FileStore secondary = getSecondary(); + + NodeStore store = SegmentNodeStoreBuilders.builder(primary).build(); + try ( + StandbyServerSync serverSync = new StandbyServerSync(getServerPort(), primary); + StandbyClientSync clientSync = newStandbyClientSync(secondary) + ) { + serverSync.start(); + + addTestContent(store, "server", blobSize); + primary.flush(); + clientSync.run(); + assertEquals(primary.getHead(), secondary.getHead()); + + addTestContent(store, "server", blobSize); + primary.flush(); + clientSync.run(); + assertEquals(primary.getHead(), secondary.getHead()); + } + } + + @Test public void testProxySkippedBytes() throws Exception { useProxy(100, 1, -1, false); }