diff --git a/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java b/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java index c859390..093be45 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/lockmgr/zookeeper/ZooKeeperHiveLockManager.java @@ -442,6 +442,8 @@ private void unlockWithRetry(HiveConf conf, ZooKeeper zkpClient, break; } catch (Exception e) { if (tryNum >= numRetriesForUnLock) { + String name = ((ZooKeeperHiveLock)hiveLock).getPath(); + LOG.error("Node " + name + " can not be deleted after " + numRetriesForUnLock + " attempts."); throw new LockException(e); } } @@ -455,23 +457,28 @@ private void unlockWithRetry(HiveConf conf, ZooKeeper zkpClient, static void unlockPrimitive(HiveConf conf, ZooKeeper zkpClient, HiveLock hiveLock, String parent) throws LockException { ZooKeeperHiveLock zLock = (ZooKeeperHiveLock)hiveLock; + HiveLockObject obj = zLock.getHiveLockObject(); + String name = getLastObjectName(parent, obj); try { - // can throw KeeperException.NoNodeException, which might mean something is wrong zkpClient.delete(zLock.getPath(), -1); // Delete the parent node if all the children have been deleted - HiveLockObject obj = zLock.getHiveLockObject(); - String name = getLastObjectName(parent, obj); - - try { - List children = zkpClient.getChildren(name, false); - if (children == null || children.isEmpty()) { - zkpClient.delete(name, -1); - } - } catch (KeeperException.NoNodeException e) { - LOG.debug("Node " + name + " previously deleted when attempting to delete."); - } + List children = zkpClient.getChildren(name, false); + if (children == null || children.isEmpty()) { + zkpClient.delete(name, -1); + } + } catch (KeeperException.NoNodeException nne) { + //can happen in retrying deleting the zLock after exceptions like InterruptedException + //or in a race condition where parent has already been deleted by other process when it + //is to be deleted. Both cases should not raise error + LOG.debug("Node " + zLock.getPath() + " or its parent has already been deleted."); + } catch (KeeperException.NotEmptyException nee) { + //can happen in a race condition where another process adds a zLock under this parent + //just before it is about to be deleted. It should not be a problem since this parent + //can eventually be deleted by the process which hold its last child zLock + LOG.debug("Node " + name + " to be deleted is not empty."); } catch (Exception e) { + //exceptions including InterruptException and other KeeperException LOG.error("Failed to release ZooKeeper lock: ", e); throw new LockException(e); }