Repository: bookkeeper Updated Branches: refs/heads/branch-4.3 dada850b6 -> f1bccab98
BOOKKEEPER-811: Recovery tool doesn't remove cookie after recovering one bookie (Charles Xie via sijie) Project: http://git-wip-us.apache.org/repos/asf/bookkeeper/repo Commit: http://git-wip-us.apache.org/repos/asf/bookkeeper/commit/f1bccab9 Tree: http://git-wip-us.apache.org/repos/asf/bookkeeper/tree/f1bccab9 Diff: http://git-wip-us.apache.org/repos/asf/bookkeeper/diff/f1bccab9 Branch: refs/heads/branch-4.3 Commit: f1bccab98f22d46fd33c5bd78e666725a81aa401 Parents: dada850 Author: Sijie Guo <[email protected]> Authored: Fri Dec 5 23:05:36 2014 -0800 Committer: Sijie Guo <[email protected]> Committed: Fri Dec 5 23:05:36 2014 -0800 ---------------------------------------------------------------------- CHANGES.txt | 2 + .../apache/bookkeeper/bookie/BookieShell.java | 39 ++++++++++--- .../org/apache/bookkeeper/bookie/Cookie.java | 58 ++++++++++++++++++-- .../bookkeeper/client/BookKeeperAdmin.java | 9 +++ 4 files changed, 96 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/bookkeeper/blob/f1bccab9/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index eabeb41..edde7ce 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -22,6 +22,8 @@ Release 4.3.1 - unreleased BOOKKEEPER-813: BookieShell doesn't find index directory (Charles Xie via sijie) + BOOKKEEPER-811: Recovery tool doesn't remove cookie after recovering one bookie (Charles Xie via sijie) + bookkeeper-client: BOOKKEEPER-810: Allow to configure TCP connect timeout (Charles Xie via sijie) http://git-wip-us.apache.org/repos/asf/bookkeeper/blob/f1bccab9/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java ---------------------------------------------------------------------- diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java index 621c823..a1e4639 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/BookieShell.java @@ -54,6 +54,7 @@ import org.apache.bookkeeper.util.Tool; import org.apache.bookkeeper.util.ZkUtils; import org.apache.bookkeeper.versioning.Version; import org.apache.bookkeeper.versioning.Versioned; +import org.apache.bookkeeper.zookeeper.ZooKeeperClient; import org.apache.bookkeeper.zookeeper.ZooKeeperWatcherBase; import org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.GenericCallback; @@ -207,6 +208,7 @@ public class BookieShell implements Tool { opts.addOption("f", "force", false, "If [nonInteractive] is specified, then whether" + " to force delete the old data without prompt..?"); + opts.addOption("d", "deleteCookie", false, "Delete its cookie on zookeeper"); } @Override @@ -221,7 +223,7 @@ public class BookieShell implements Tool { @Override String getUsage() { - return "bookieformat [-nonInteractive] [-force]"; + return "bookieformat [-nonInteractive] [-force] [-deleteCookie]"; } @Override @@ -231,6 +233,19 @@ public class BookieShell implements Tool { ServerConfiguration conf = new ServerConfiguration(bkConf); boolean result = Bookie.format(conf, interactive, force); + // delete cookie + if (cmdLine.hasOption("d")) { + ZooKeeperClient zkc = + ZooKeeperClient.createConnectedZooKeeperClient(conf.getZkServers(), conf.getZkTimeout()); + try { + Versioned<Cookie> cookie = Cookie.readFromZooKeeper(zkc, conf); + cookie.getValue().deleteFromZooKeeper(zkc, conf, cookie.getVersion()); + } catch (KeeperException.NoNodeException nne) { + LOG.warn("No cookie to remove : ", nne); + } finally { + zkc.close(); + } + } return (result) ? 0 : 1; } } @@ -243,6 +258,7 @@ public class BookieShell implements Tool { public RecoverCmd() { super(CMD_RECOVER); + opts.addOption("d", "deleteCookie", false, "Delete cookie node for the bookie."); } @Override @@ -257,7 +273,7 @@ public class BookieShell implements Tool { @Override String getUsage() { - return "recover <bookieSrc> [bookieDest]"; + return "recover [-deleteCookie] <bookieSrc> [bookieDest]"; } @Override @@ -271,16 +287,15 @@ public class BookieShell implements Tool { ClientConfiguration adminConf = new ClientConfiguration(bkConf); BookKeeperAdmin admin = new BookKeeperAdmin(adminConf); try { - return bkRecovery(admin, args); + return bkRecovery(adminConf, admin, args, cmdLine.hasOption("d")); } finally { - if (null != admin) { - admin.close(); - } + admin.close(); } } - private int bkRecovery(BookKeeperAdmin bkAdmin, String[] args) - throws InterruptedException, BKException { + private int bkRecovery(ClientConfiguration conf, BookKeeperAdmin bkAdmin, + String[] args, boolean deleteCookie) + throws InterruptedException, BKException, KeeperException, IOException { final String bookieSrcString[] = args[0].split(":"); if (bookieSrcString.length != 2) { System.err.println("BookieSrc inputted has invalid format" @@ -302,6 +317,14 @@ public class BookieShell implements Tool { } bkAdmin.recoverBookieData(bookieSrc, bookieDest); + if (deleteCookie) { + try { + Versioned<Cookie> cookie = Cookie.readFromZooKeeper(bkAdmin.getZooKeeper(), conf, bookieSrc); + cookie.getValue().deleteFromZooKeeper(bkAdmin.getZooKeeper(), conf, bookieSrc, cookie.getVersion()); + } catch (KeeperException.NoNodeException nne) { + LOG.warn("No cookie to remove for {} : ", bookieSrc, nne); + } + } return 0; } } http://git-wip-us.apache.org/repos/asf/bookkeeper/blob/f1bccab9/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Cookie.java ---------------------------------------------------------------------- diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Cookie.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Cookie.java index 9e77029..349eee5 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Cookie.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/bookie/Cookie.java @@ -35,8 +35,10 @@ import java.io.StringReader; import java.net.InetSocketAddress; import java.net.UnknownHostException; +import org.apache.bookkeeper.conf.AbstractConfiguration; import org.apache.bookkeeper.conf.ServerConfiguration; import org.apache.bookkeeper.meta.ZkVersion; +import org.apache.bookkeeper.net.BookieSocketAddress; import org.apache.bookkeeper.proto.DataFormats.CookieFormat; import org.apache.bookkeeper.util.BookKeeperConstants; import org.apache.bookkeeper.versioning.Version; @@ -232,13 +234,33 @@ class Cookie { * @throws InterruptedException * @throws UnknownHostException */ - void deleteFromZooKeeper(ZooKeeper zk, ServerConfiguration conf, Version version) throws KeeperException, + public void deleteFromZooKeeper(ZooKeeper zk, ServerConfiguration conf, Version version) throws KeeperException, InterruptedException, UnknownHostException { + BookieSocketAddress address = Bookie.getBookieAddress(conf); + deleteFromZooKeeper(zk, conf, address, version); + } + + /** + * Delete cookie from zookeeper + * + * @param zk zookeeper client + * @param conf configuration instance + * @param address bookie address + * @param version cookie version + * @throws KeeperException + * @throws InterruptedException + * @throws UnknownHostException + */ + public void deleteFromZooKeeper(ZooKeeper zk, AbstractConfiguration conf, + BookieSocketAddress address, Version version) + throws KeeperException, InterruptedException, UnknownHostException { if (!(version instanceof ZkVersion)) { throw new IllegalArgumentException("Invalid version type, expected ZkVersion type"); } - String zkPath = getZkPath(conf); + + String zkPath = getZkPath(conf, address); zk.delete(zkPath, ((ZkVersion)version).getZnodeVersion()); + LOG.info("Removed cookie from {} for bookie {}.", conf.getZkLedgersRootPath(), address); } /** @@ -284,7 +306,24 @@ class Cookie { */ static Versioned<Cookie> readFromZooKeeper(ZooKeeper zk, ServerConfiguration conf) throws KeeperException, InterruptedException, IOException, UnknownHostException { - String zkPath = getZkPath(conf); + return readFromZooKeeper(zk, conf, Bookie.getBookieAddress(conf)); + } + + /** + * Read cookie from zookeeper for a given bookie <i>address</i> + * + * @param zk zookeeper client + * @param conf configuration instance + * @param address bookie address + * @return versioned cookie object + * @throws KeeperException + * @throws InterruptedException + * @throws IOException + * @throws UnknownHostException + */ + static Versioned<Cookie> readFromZooKeeper(ZooKeeper zk, AbstractConfiguration conf, BookieSocketAddress address) + throws KeeperException, InterruptedException, IOException, UnknownHostException { + String zkPath = getZkPath(conf, address); Stat stat = zk.exists(zkPath, false); byte[] data = zk.getData(zkPath, false, stat); @@ -334,9 +373,20 @@ class Cookie { */ static String getZkPath(ServerConfiguration conf) throws UnknownHostException { + return getZkPath(conf, Bookie.getBookieAddress(conf)); + } + + /** + * Return cookie path for a given bookie <i>address</i> + * + * @param conf configuration + * @param address bookie address + * @return cookie path for bookie + */ + static String getZkPath(AbstractConfiguration conf, BookieSocketAddress address) { String bookieCookiePath = conf.getZkLedgersRootPath() + "/" + BookKeeperConstants.COOKIE_NODE; - return bookieCookiePath + "/" + Bookie.getBookieAddress(conf); + return bookieCookiePath + "/" + address; } /** http://git-wip-us.apache.org/repos/asf/bookkeeper/blob/f1bccab9/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java ---------------------------------------------------------------------- diff --git a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java index 18a801c..fbca7d2 100644 --- a/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java +++ b/bookkeeper-server/src/main/java/org/apache/bookkeeper/client/BookKeeperAdmin.java @@ -172,6 +172,15 @@ public class BookKeeperAdmin { } /** + * Get {@link org.apache.zookeeper.ZooKeeper} used by bookkeeper admin client. + * + * @return zookeeper client used by bookkeeper admin client + */ + public ZooKeeper getZooKeeper() { + return zk; + } + + /** * Get a list of the available bookies. * * @return a collection of bookie addresses
