Return-Path: X-Original-To: apmail-zookeeper-commits-archive@www.apache.org Delivered-To: apmail-zookeeper-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 16F7F10227 for ; Mon, 10 Feb 2014 20:51:19 +0000 (UTC) Received: (qmail 2808 invoked by uid 500); 10 Feb 2014 20:51:17 -0000 Delivered-To: apmail-zookeeper-commits-archive@zookeeper.apache.org Received: (qmail 2770 invoked by uid 500); 10 Feb 2014 20:51:16 -0000 Mailing-List: contact commits-help@zookeeper.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ Delivered-To: mailing list commits@zookeeper.apache.org Received: (qmail 2758 invoked by uid 99); 10 Feb 2014 20:51:16 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 Feb 2014 20:51:16 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 Feb 2014 20:51:14 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id CCD2423888E4; Mon, 10 Feb 2014 20:50:54 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1566739 - in /zookeeper/trunk: CHANGES.txt src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java Date: Mon, 10 Feb 2014 20:50:54 -0000 To: commits@zookeeper.apache.org From: phunt@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140210205054.CCD2423888E4@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: phunt Date: Mon Feb 10 20:50:54 2014 New Revision: 1566739 URL: http://svn.apache.org/r1566739 Log: ZOOKEEPER-1573. Unable to load database due to missing parent node (Vinayakumar B via phunt, fpj) Modified: zookeeper/trunk/CHANGES.txt zookeeper/trunk/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java zookeeper/trunk/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java Modified: zookeeper/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1566739&r1=1566738&r2=1566739&view=diff ============================================================================== --- zookeeper/trunk/CHANGES.txt (original) +++ zookeeper/trunk/CHANGES.txt Mon Feb 10 20:50:54 2014 @@ -541,6 +541,9 @@ BUGFIXES: ZOOKEEPER-1867. Bug in ZkDatabaseCorruptionTest (fpj) + ZOOKEEPER-1573. Unable to load database due to missing parent node + (Vinayakumar B via phunt, fpj) + IMPROVEMENTS: ZOOKEEPER-1170. Fix compiler (eclipse) warnings: unused imports, Modified: zookeeper/trunk/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java?rev=1566739&r1=1566738&r2=1566739&view=diff ============================================================================== --- zookeeper/trunk/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java (original) +++ zookeeper/trunk/src/java/main/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java Mon Feb 10 20:50:54 2014 @@ -256,20 +256,15 @@ public class FileTxnSnapLog { } /** - * This should never happen. A NONODE can never show up in the - * transaction logs. This is more indicative of a corrupt transaction - * log. Refer ZOOKEEPER-1333 for more info. + * Snapshots are lazily created. So when a snapshot is in progress, + * there is a chance for later transactions to make into the + * snapshot. Then when the snapshot is restored, NONODE/NODEEXISTS + * errors could occur. It should be safe to ignore these. */ if (rc.err != Code.OK.intValue()) { - if (hdr.getType() == OpCode.create && rc.err == Code.NONODE.intValue()) { - int lastSlash = rc.path.lastIndexOf('/'); - String parentName = rc.path.substring(0, lastSlash); - LOG.error("Parent {} missing for {}", parentName, rc.path); - throw new KeeperException.NoNodeException(parentName); - } else { - LOG.debug("Ignoring processTxn failure hdr: " + hdr.getType() + - " : error: " + rc.err); - } + LOG.debug( + "Ignoring processTxn failure hdr: {}, error: {}, path: {}", + hdr.getType(), rc.err, rc.path); } } Modified: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java?rev=1566739&r1=1566738&r2=1566739&view=diff ============================================================================== --- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java (original) +++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/LoadFromLogTest.java Mon Feb 10 20:50:54 2014 @@ -38,6 +38,7 @@ import org.apache.zookeeper.ZKTestCase; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooDefs.OpCode; import org.apache.zookeeper.ZooKeeper; +import org.apache.zookeeper.data.Stat; import org.apache.zookeeper.server.DataNode; import org.apache.zookeeper.server.DataTree; import org.apache.zookeeper.server.ServerCnxnFactory; @@ -360,22 +361,8 @@ public class LoadFromLogTest extends ZKT f.startup(zks); Assert.assertTrue("waiting for server being up ", ClientBase .waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT)); - ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this); + ZooKeeper zk = getConnectedZkClient(); - long start = System.currentTimeMillis(); - while (!connected) { - long end = System.currentTimeMillis(); - if (end - start > 5000) { - Assert.assertTrue("Could not connect with server in 5 seconds", - false); - } - try { - Thread.sleep(200); - } catch (Exception e) { - LOG.warn("Intrrupted"); - } - - } // generate some transactions String lastPath = null; try { @@ -415,21 +402,8 @@ public class LoadFromLogTest extends ZKT // Verify lastProcessedZxid is set correctly Assert.assertTrue("Restore failed expected zxid=" + eZxid + " found=" + fZxid, fZxid == eZxid); - zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this); - start = System.currentTimeMillis(); - while (!connected) { - long end = System.currentTimeMillis(); - if (end - start > 5000) { - Assert.assertTrue("Could not connect with server in 5 seconds", - false); - } - try { - Thread.sleep(200); - } catch (Exception e) { - LOG.warn("Intrrupted"); - } + zk = getConnectedZkClient(); - } // Verify correctness of data and whether sequential znode creation // proceeds correctly after this point String[] children; @@ -468,22 +442,8 @@ public class LoadFromLogTest extends ZKT f.startup(zks); Assert.assertTrue("waiting for server being up ", ClientBase .waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT)); - ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this); - - long start = System.currentTimeMillis(); - while (!connected) { - long end = System.currentTimeMillis(); - if (end - start > 5000) { - Assert.assertTrue("Could not connect with server in 5 seconds", - false); - } - try { - Thread.sleep(200); - } catch (Exception e) { - LOG.warn("Intrrupted"); - } + ZooKeeper zk = getConnectedZkClient(); - } // generate some transactions try { for (int i = 0; i < NUM_MESSAGES; i++) { @@ -560,4 +520,67 @@ public class LoadFromLogTest extends ZKT } } + /** + * ZOOKEEPER-1573: test restoring a snapshot with deleted txns ahead of the + * snapshot file's zxid. + */ + @Test + public void testReloadSnapshotWithMissingParent() throws Exception { + // setup a single server cluster + File tmpDir = ClientBase.createTmpDir(); + ClientBase.setupTestEnv(); + ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000); + SyncRequestProcessor.setSnapCount(10000); + final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]); + ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1); + f.startup(zks); + Assert.assertTrue("waiting for server being up ", + ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT)); + ZooKeeper zk = getConnectedZkClient(); + + // create transactions to create the snapshot with create/delete pattern + zk.create("/a", "".getBytes(), Ids.OPEN_ACL_UNSAFE, + CreateMode.PERSISTENT); + Stat stat = zk.exists("/a", false); + long createZxId = stat.getMzxid(); + zk.create("/a/b", "".getBytes(), Ids.OPEN_ACL_UNSAFE, + CreateMode.PERSISTENT); + zk.delete("/a/b", -1); + zk.delete("/a", -1); + // force the zxid to be behind the content + zks.getZKDatabase().setlastProcessedZxid(createZxId); + LOG.info("Set lastProcessedZxid to {}", zks.getZKDatabase() + .getDataTreeLastProcessedZxid()); + // Force snapshot and restore + zks.takeSnapshot(); + zks.shutdown(); + f.shutdown(); + + zks = new ZooKeeperServer(tmpDir, tmpDir, 3000); + SyncRequestProcessor.setSnapCount(10000); + f = ServerCnxnFactory.createFactory(PORT, -1); + f.startup(zks); + Assert.assertTrue("waiting for server being up ", + ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT)); + f.shutdown(); + } + + private ZooKeeper getConnectedZkClient() throws IOException { + ZooKeeper zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this); + + long start = System.currentTimeMillis(); + while (!connected) { + long end = System.currentTimeMillis(); + if (end - start > 5000) { + Assert.assertTrue("Could not connect with server in 5 seconds", + false); + } + try { + Thread.sleep(200); + } catch (Exception e) { + LOG.warn("Interrupted"); + } + } + return zk; + } }