You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2015/07/15 14:26:31 UTC

svn commit: r1691195 - in /jackrabbit/oak/branches/1.2: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/ oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/

Author: reschke
Date: Wed Jul 15 12:26:31 2015
New Revision: 1691195

URL: http://svn.apache.org/r1691195
Log:
OAK-3108: RDBDocumentStore: improve diagnostics for failed inserts/updates caused by long data, enhance test coverage (ported to 1.2)

Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
    jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java
    jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Jul 15 12:26:31 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820,1684868,1685023,1685370,1685552
 ,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691151,1691167
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820,1684868,1685023,1685370,1685552
 ,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691151,1691167,1691183
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1691195&r1=1691194&r2=1691195&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java Wed Jul 15 12:26:31 2015
@@ -1423,6 +1423,7 @@ public class RDBDocumentStore implements
             @Nonnull UpdateOp update, Long oldmodcount) {
         Connection connection = null;
         String tableName = getTable(collection);
+        String data = null;
         try {
             connection = this.ch.getRWConnection();
             Operation modOperation = update.getChanges().get(MODIFIEDKEY);
@@ -1452,7 +1453,7 @@ public class RDBDocumentStore implements
                 }
             }
             if (!success) {
-                String data = SR.asString(document);
+                data = SR.asString(document);
                 success = dbUpdate(connection, tableName, document.getId(), modified, hasBinary, deletedOnce, modcount, cmodcount,
                         oldmodcount, data);
                 connection.commit();
@@ -1460,7 +1461,15 @@ public class RDBDocumentStore implements
             return success;
         } catch (SQLException ex) {
             this.ch.rollbackConnection(connection);
-            throw new DocumentStoreException(ex);
+            String addDiags = "";
+            if (RDBJDBCTools.matchesSQLState(ex, "22", "72")) {
+                byte[] bytes = asBytes(data);
+                addDiags = String.format(" (DATA size in Java characters: %d, in octets: %d, computed character limit: %d)",
+                        data.length(), bytes.length, this.dataLimitInOctets / CHAR2OCTETRATIO);
+            }
+            String message = String.format("Update for %s failed%s", document.getId(), addDiags);
+            LOG.debug(message, ex);
+            throw new DocumentStoreException(message, ex);
         } finally {
             this.ch.closeConnection(connection);
         }
@@ -1510,14 +1519,44 @@ public class RDBDocumentStore implements
             for (T doc : documents) {
                 ids.add(doc.getId());
             }
-            LOG.debug("insert of " + ids + " failed", ex);
+            String message = String.format("insert of %s failed", ids);
+            LOG.debug(message, ex);
 
             // collect additional exceptions
             String messages = LOG.isDebugEnabled() ? RDBJDBCTools.getAdditionalMessages(ex) : "";
+
+            // see whether a DATA error was involved
+            boolean dataRelated = false;
+            SQLException walk = ex;
+            while (walk != null && !dataRelated) {
+                dataRelated = RDBJDBCTools.matchesSQLState(walk, "22", "72");
+                walk = walk.getNextException();
+            }
+            if (dataRelated) {
+                String id = null;
+                int longest = 0, longestChars = 0;
+
+                for (Document d : documents) {
+                    String data = SR.asString(d);
+                    byte bytes[] = asBytes(data);
+                    if (bytes.length > longest) {
+                        longest = bytes.length;
+                        longestChars = data.length();
+                        id = d.getId();
+                    }
+                }
+
+                String m = String
+                        .format(" (potential cause: long data for ID %s - longest octet DATA size in Java characters: %d, in octets: %d, computed character limit: %d)",
+                                id, longest, longestChars, this.dataLimitInOctets / CHAR2OCTETRATIO);
+                messages += m;
+            }
+
             if (!messages.isEmpty()) {
                 LOG.debug("additional diagnostics: " + messages);
             }
-            throw new DocumentStoreException(ex);
+
+            throw new DocumentStoreException(message, ex);
         } finally {
             this.ch.closeConnection(connection);
         }

Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java?rev=1691195&r1=1691194&r2=1691195&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java Wed Jul 15 12:26:31 2015
@@ -140,4 +140,18 @@ public class RDBJDBCTools {
 
         return messages.isEmpty() ? "" : messages.toString();
     }
+
+    /**
+     * Check whether the exception matches one of the given states.
+     */
+    protected static boolean matchesSQLState(SQLException ex, String... statePrefix) {
+        String state = ex.getSQLState();
+        if (state != null) {
+            for (String sp : statePrefix) {
+                if (state.startsWith(sp))
+                    return true;
+            }
+        }
+        return false;
+    }
 }

Modified: jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java?rev=1691195&r1=1691194&r2=1691195&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java (original)
+++ jackrabbit/oak/branches/1.2/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/BasicDocumentStoreTest.java Wed Jul 15 12:26:31 2015
@@ -138,7 +138,7 @@ public class BasicDocumentStoreTest exte
     }
 
     @Test
-    public void testInterestingPropLengths() {
+    public void testInterestingPropLengths() throws UnsupportedEncodingException {
         int lengths[] = { 1, 10, 100, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000,
                 15000, 16000, 20000 };
 
@@ -162,12 +162,19 @@ public class BasicDocumentStoreTest exte
             up.set("foo", pval);
             super.ds.remove(Collection.NODES, id);
             boolean success = super.ds.create(Collection.NODES, Collections.singletonList(up));
-            try {
-                assertTrue("failed to insert a document with property of length " + test
-                        + "(potentially non-ASCII, actual octet length in UTF-8: " + pval.getBytes("UTF-8").length + ") in "
-                        + super.dsname, success);
-            } catch (UnsupportedEncodingException e) {
-                // outch
+            assertTrue("failed to insert a document with property of length " + test
+                    + " (potentially non-ASCII, actual octet length with UTF-8 encoding: " + pval.getBytes("UTF-8").length + ") in "
+                    + super.dsname, success);
+            // check that update works as well
+            if (success) {
+                try {
+                    super.ds.findAndUpdate(Collection.NODES, up);
+                } catch (Exception ex) {
+                    ex.printStackTrace(System.err);
+                    fail("failed to update a document with property of length " + test
+                            + " (potentially non-ASCII, actual octet length with UTF-8 encoding: " + pval.getBytes("UTF-8").length + ") in "
+                            + super.dsname);
+                }
             }
             super.ds.remove(Collection.NODES, id);
         }