onlineRegionsForTable = null;
+ try {
+ onlineRegionsForTable = getOnlineRegionsForTable(tableName);
+ if (onlineRegionsForTable != null && onlineRegionsForTable.size() > 0) {
+ LOG.info("refreshSchema found " + onlineRegionsForTable
+ + " online regions for table = " + Bytes.toString(tableName)
+ + " Refreshing them now..");
+ reopenRegions(onlineRegionsForTable);
+ } else {
+ LOG.info("refreshSchema found no onlineRegions for table = "
+ + Bytes.toString(tableName) + ". Skipping refreshSchema...");
+ }
+ } catch (IOException ioe) {
+ LOG.info("refreshSchema failed with exception "
+ + " for table = " + Bytes.toString(tableName)
+ + " Number of regions online = "
+ + onlineRegionsForTable == null ? 0 : onlineRegionsForTable.size());
+ throw ioe;
+ }
+ }
+
+}
Index: hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/MasterSchemaChangeTracker.java
===================================================================
--- hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/MasterSchemaChangeTracker.java (revision )
+++ hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/MasterSchemaChangeTracker.java (revision )
@@ -0,0 +1,143 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.zookeeper;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.Abortable;
+import org.apache.hadoop.hbase.regionserver.RegionServerServices;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.zookeeper.KeeperException;
+
+import java.io.IOException;
+import java.util.List;
+
+public class MasterSchemaChangeTracker extends ZooKeeperNodeTracker {
+ public static final Log LOG = LogFactory.getLog(MasterSchemaChangeTracker.class);
+
+ /**
+ * Constructs a new ZK node tracker.
+ *
+ * After construction, use {@link #start} to kick off tracking.
+ *
+ * @param watcher
+ * @param node
+ * @param abortable
+ */
+ public MasterSchemaChangeTracker(ZooKeeperWatcher watcher,
+ Abortable abortable) {
+ super(watcher, watcher.schemaZNode, abortable);
+ }
+
+
+ @Override
+ public void start() {
+ try {
+ ZKUtil.listChildrenAndWatchThem(watcher, watcher.schemaZNode);
+ watcher.registerListener(this);
+ } catch (KeeperException e) {
+ LOG.error("MasterSchemaChangeTracker startup failed.", e);
+ }
+ }
+
+ /**
+ * Create a new schema change ZK node.
+ * @param tableName
+ * @throws KeeperException
+ */
+ public void createSchemaChangeNode(String tableName) throws KeeperException {
+ LOG.info("Creating schema change node for table = "
+ + tableName + " Path = "
+ + getSchemaChangeNodePathForTable(tableName));
+ if (isSchemaChangeNodeExists(tableName)) {
+ LOG.info("Schema change node already exists for table = " + tableName
+ + " Deleting the schema change node.");
+ deleteSchemaChangeNode(tableName);
+ }
+ ZKUtil.createAndFailSilent(this.watcher,
+ getSchemaChangeNodePathForTable(tableName));
+ int rsCount = ZKUtil.getNumberOfChildren(this.watcher, watcher.rsZNode);
+ ZKUtil.setData(this.watcher, getSchemaChangeNodePathForTable(tableName),
+ Bytes.toBytes(rsCount));
+ ZKUtil.listChildrenAndWatchThem(this.watcher,
+ getSchemaChangeNodePathForTable(tableName));
+ }
+
+ private void deleteSchemaChangeNode(String tableName) throws KeeperException {
+ ZKUtil.deleteNodeRecursively(watcher,
+ getSchemaChangeNodePathForTable(tableName));
+ }
+
+ /**
+ * Create a new schema change ZK node.
+ * @param tableName
+ * @throws KeeperException
+ */
+ public boolean isSchemaChangeNodeExists(String tableName)
+ throws KeeperException {
+ return ZKUtil.checkExists(watcher,
+ getSchemaChangeNodePathForTable(tableName)) != -1;
+ }
+
+
+ @Override
+ public void nodeChildrenChanged(String path) {
+ if (path.startsWith(watcher.schemaZNode)
+ && !path.equals(watcher.schemaZNode)) {
+ try {
+ List servers =
+ ZKUtil.listChildrenAndWatchThem(watcher, path);
+ String tableName = path.substring(path.lastIndexOf("/")+1, path.length());
+ LOG.debug("Master.SchemaChangeTracker.nodeChildrenChanged. "
+ + " Current table == " + tableName
+ + " List of servers which processed schema change = " + servers);
+ byte[] rsCountBytes = ZKUtil.getData(watcher,
+ getSchemaChangeNodePathForTable(tableName));
+ int rsCount = 0;
+ if (rsCountBytes != null) {
+ rsCount = Bytes.toInt(rsCountBytes);
+ }
+ //int rsCount = Bytes.toInt(rsCountBytes);
+ if (rsCount != 0 && (servers != null && servers.size() >= rsCount)) {
+ LOG.debug("All region servers have successfully processed the " +
+ "schema changes for table = " + tableName
+ + " . Deleting the schema change node = "
+ + path);
+ ZKUtil.deleteNodeRecursively(this.watcher, path);
+ } else {
+ LOG.debug("Not all region servers have processed the schema changes"
+ + "for table = " + tableName + " rs count = "
+ + rsCount + " processed count = " + servers);
+ }
+ } catch (KeeperException e) {
+ LOG.error("MasterSchemaChangeTracker: Unexpected zk exception getting"
+ + " schema change nodes", e);
+ }
+ } else {
+ LOG.debug("Not processing Master.nodeChildrenChanged for path = "
+ + path);
+ }
+ }
+
+ public String getSchemaChangeNodePathForTable(String tableName) {
+ return ZKUtil.joinZNode(watcher.schemaZNode, tableName);
+ }
+}
Index: hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/SchemaChangeTracker.java
===================================================================
--- hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/SchemaChangeTracker.java (revision )
+++ hbase/src/main/java/org/apache/hadoop/hbase/zookeeper/SchemaChangeTracker.java (revision )
@@ -0,0 +1,157 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.zookeeper;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.Abortable;
+import org.apache.hadoop.hbase.regionserver.RegionServerServices;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.zookeeper.KeeperException;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Random;
+import java.util.logging.Logger;
+
+public class SchemaChangeTracker extends ZooKeeperNodeTracker {
+ public static final Log LOG = LogFactory.getLog(SchemaChangeTracker.class);
+ private RegionServerServices regionServer = null;
+
+
+ /**
+ * Constructs a new ZK node tracker.
+ *
+ * After construction, use {@link #start} to kick off tracking.
+ *
+ * @param watcher
+ * @param node
+ * @param abortable
+ */
+ public SchemaChangeTracker(ZooKeeperWatcher watcher,
+ Abortable abortable,
+ RegionServerServices regionServer) {
+ super(watcher, watcher.schemaZNode, abortable);
+ this.regionServer = regionServer;
+ }
+
+ @Override
+ public void start() {
+ try {
+ ZKUtil.listChildrenAndWatchThem(watcher, node);
+ watcher.registerListener(this);
+ } catch (KeeperException e) {
+ LOG.error("RegionServer SchemaChangeTracker startup failed with " +
+ "KeeperException.", e);
+ }
+ }
+
+ // whenever new schema change occur this event will get triggered
+ @Override
+ public void nodeChildrenChanged(String path) {
+ if (path.equals(watcher.schemaZNode)) {
+ try {
+ List tables =
+ ZKUtil.listChildrenAndWatchThem(watcher, watcher.schemaZNode);
+ LOG.debug("RS.SchemaChangeTracker: " +
+ "Current list of tables with schema change = " + tables);
+ if (tables != null) {
+ handleSchemaChange(tables);
+ } else {
+ LOG.error("No tables found for schema change event." +
+ " Skipping instant schema refresh");
+ }
+ } catch (KeeperException ke) {
+ LOG.error("KeeperException handling schema change event.", ke);
+
+ }
+ }
+ }
+
+ private void handleSchemaChange(String tableName) throws IOException {
+ if (tableName != null) {
+ regionServer.refreshSchema(Bytes.toBytes(tableName));
+ updateZKNode(tableName);
+ LOG.info("Refresh schema completed for table name = " + tableName
+ + " server = " + regionServer.getServerName().getServerName());
+ }
+ }
+
+ private boolean hasHandledSchemaChange(List servers) {
+ return (servers != null &&
+ servers.contains(regionServer.getServerName().getServerName()));
+ }
+
+ private void handleSchemaChange(List tables) {
+ for (String tableName : tables) {
+ try {
+ List servers = ZKUtil.listChildrenNoWatch(watcher,
+ getSchemaChangeNodePathForTable(tableName));
+ if (!hasHandledSchemaChange(servers)) {
+ handleSchemaChange(tableName);
+ } else {
+ LOG.info("Schema change for table " + tableName
+ + " already addressed by server = "
+ + regionServer.getServerName().getServerName()
+ + " skipping refresh schema");
+ }
+ } catch (KeeperException ke) {
+ LOG.error("KeeperException handling schema change event for " +
+ " table = " + tableName, ke);
+ } catch (IOException ioe) {
+ LOG.error("IOException handling schema change event for table = "
+ + tableName, ioe);
+ }
+ }
+ }
+
+ private void updateZKNode(String tableName) {
+ try {
+ ZKUtil.createAndFailSilent(this.watcher,
+ getSchemaChangeNodePathForTableAndServer(tableName,
+ regionServer.getServerName().getServerName()));
+ LOG.info("updateZKNode() Created child ZKNode with server name = "
+ + regionServer.getServerName().getServerName() + " for table = "
+ + tableName);
+ } catch (KeeperException.NoNodeException e) {
+ LOG.error("KeeperException.NoNodeException while updating the schema "
+ + "change node with server name for table = "
+ + tableName + " server = "
+ + regionServer.getServerName().getServerName(), e);
+ } catch (KeeperException e) {
+ LOG.error("KeeperException while updating the schema change node with "
+ + "server name for table = "
+ + tableName + " server = "
+ + regionServer.getServerName().getServerName(), e);
+ }
+ }
+
+ private String getSchemaChangeNodePathForTable(String tableName) {
+ return ZKUtil.joinZNode(watcher.schemaZNode, tableName);
+ }
+
+ private String getSchemaChangeNodePathForTableAndServer(
+ String tableName, String regionServerName) {
+ return ZKUtil.joinZNode(getSchemaChangeNodePathForTable(tableName),
+ regionServerName);
+ }
+
+}
Index: hbase/src/test/java/org/apache/hadoop/hbase/client/TestInstantSchemaChange.java
===================================================================
--- hbase/src/test/java/org/apache/hadoop/hbase/client/TestInstantSchemaChange.java (revision )
+++ hbase/src/test/java/org/apache/hadoop/hbase/client/TestInstantSchemaChange.java (revision )
@@ -0,0 +1,323 @@
+/**
+ * Copyright 2011 The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.hbase.client;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.MiniHBaseCluster;
+import org.apache.hadoop.hbase.regionserver.HRegion;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.zookeeper.MasterSchemaChangeTracker;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestInstantSchemaChange {
+
+ final Log LOG = LogFactory.getLog(getClass());
+ private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+ private HBaseAdmin admin;
+ private static MiniHBaseCluster miniHBaseCluster = null;
+ private Configuration conf;
+ private ZooKeeperWatcher zkw;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
+ TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
+ TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
+ miniHBaseCluster = TEST_UTIL.startMiniCluster(3);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ TEST_UTIL.shutdownMiniCluster();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ this.admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
+ }
+
+ @Test
+ public void testInstantSchemaChangeForModifyTable() throws IOException, KeeperException {
+
+ String tableName = "testSchemachange";
+ conf = TEST_UTIL.getConfiguration();
+ LOG.info("Start testInstantSchemaChangeForModifyTable()");
+
+ HTableDescriptor[] tables = admin.listTables();
+ int numTables = 0;
+ if (tables != null) {
+ numTables = tables.length;
+ }
+ HTable ht = TEST_UTIL.createTable(Bytes.toBytes(tableName),
+ HConstants.CATALOG_FAMILY);
+ tables = this.admin.listTables();
+ assertEquals(numTables + 1, tables.length);
+ LOG.info("Table testSchemachange created");
+
+ final byte [] row = Bytes.toBytes("row");
+ final byte [] qualifier = Bytes.toBytes("qualifier");
+ final byte [] value = Bytes.toBytes("value");
+
+ Put put = new Put(row);
+ put.add(HConstants.CATALOG_FAMILY, qualifier, value);
+ ht.put(put);
+ Get get = new Get(row);
+ get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
+ Result r1 = ht.get(get);
+ byte[] tvalue1 = r1.getValue(HConstants.CATALOG_FAMILY, qualifier);
+ int result1 = Bytes.compareTo(value, tvalue1);
+ assertEquals(result1, 0);
+
+ String newFamily = "newFamily";
+ HTableDescriptor htd = new HTableDescriptor(tableName);
+ htd.addFamily(new HColumnDescriptor(newFamily));
+
+ admin.modifyTable(Bytes.toBytes(tableName), htd, true);
+ waitForSchemaChangeProcess(tableName);
+
+ Put put1 = new Put(row);
+ put1.add(Bytes.toBytes(newFamily), qualifier, value);
+ ht.put(put1);
+
+ Get get1 = new Get(row);
+ get1.addColumn(Bytes.toBytes(newFamily), qualifier);
+ Result r = ht.get(get1);
+ byte[] tvalue = r.getValue(Bytes.toBytes(newFamily), qualifier);
+ int result = Bytes.compareTo(value, tvalue);
+ assertEquals(result, 0);
+ LOG.info("END testInstantSchemaChangeForModifyTable()");
+
+ }
+
+ private void waitForSchemaChangeProcess(String tableName)
+ throws KeeperException {
+ LOG.info("Waiting for ZK node creation for table = " + tableName);
+ MasterSchemaChangeTracker msct =
+ TEST_UTIL.getHBaseCluster().getMaster().getSchemaChangeTracker();
+
+ while(true) {
+ if (msct.isSchemaChangeNodeExists(tableName)) {
+ break;
+ }
+ }
+
+ LOG.info("Waiting for ZK node deletion for table = " + tableName);
+
+ while(true) {
+ if (!msct.isSchemaChangeNodeExists(tableName)) {
+ break;
+ }
+ }
+ }
+
+ @Test
+ public void testInstantSchemaChangeForAddColumn() throws IOException, KeeperException {
+ LOG.info("Start testInstantSchemaChangeForAddColumn() ");
+ String tableName = "testSchemachangeForAddColumn";
+ HTableDescriptor[] tables = admin.listTables();
+ int numTables = 0;
+ if (tables != null) {
+ numTables = tables.length;
+ }
+ HTable ht = TEST_UTIL.createTable(Bytes.toBytes(tableName),
+ HConstants.CATALOG_FAMILY);
+ tables = this.admin.listTables();
+ assertEquals(numTables + 1, tables.length);
+ LOG.info("Table testSchemachangeForAddColumn created");
+
+ final byte [] row = Bytes.toBytes("row");
+ final byte [] qualifier = Bytes.toBytes("qualifier");
+ final byte [] value = Bytes.toBytes("value");
+
+ Put put = new Put(row);
+ put.add(HConstants.CATALOG_FAMILY, qualifier, value);
+ ht.put(put);
+ Get get = new Get(row);
+ get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
+ Result r1 = ht.get(get);
+ byte[] tvalue1 = r1.getValue(HConstants.CATALOG_FAMILY, qualifier);
+ int result1 = Bytes.compareTo(value, tvalue1);
+ assertEquals(result1, 0);
+
+ String newFamily = "newFamily";
+ HColumnDescriptor hcd = new HColumnDescriptor("newFamily");
+
+ admin.addColumn(Bytes.toBytes(tableName), hcd, true);
+ //waitForSchemaChangeProcess(tableName);
+
+ // Take a mini nap for changes to take effect.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+
+ Put put1 = new Put(row);
+ put1.add(Bytes.toBytes(newFamily), qualifier, value);
+ LOG.info("******** Put into new column family ");
+ ht.put(put1);
+
+ Get get1 = new Get(row);
+ get1.addColumn(Bytes.toBytes(newFamily), qualifier);
+ Result r = ht.get(get1);
+ byte[] tvalue = r.getValue(Bytes.toBytes(newFamily), qualifier);
+ LOG.info(" Value put = " + value + " value from table = " + tvalue);
+ int result = Bytes.compareTo(value, tvalue);
+ assertEquals(result, 0);
+ LOG.info("End testInstantSchemaChangeForAddColumn() ");
+
+ }
+
+ @Test
+ public void testInstantSchemaChangeForModifyColumn() throws IOException,
+ KeeperException {
+ LOG.info("Start testInstantSchemaChangeForModifyColumn() ");
+ String tableName = "testSchemachangeForModifyColumn";
+ int numTables = 0;
+ HTableDescriptor[] tables = admin.listTables();
+ if (tables != null) {
+ numTables = tables.length;
+ }
+ HTable ht = TEST_UTIL.createTable(Bytes.toBytes(tableName),
+ HConstants.CATALOG_FAMILY);
+ tables = this.admin.listTables();
+ assertEquals(numTables + 1, tables.length);
+ LOG.info("Table testSchemachangeForModifyColumn created");
+
+ final byte [] row = Bytes.toBytes("row");
+ final byte [] qualifier = Bytes.toBytes("qualifier");
+ final byte [] value = Bytes.toBytes("value");
+
+ Put put = new Put(row);
+ put.add(HConstants.CATALOG_FAMILY, qualifier, value);
+ ht.put(put);
+ Get get = new Get(row);
+ get.addColumn(HConstants.CATALOG_FAMILY, qualifier);
+ Result r1 = ht.get(get);
+ byte[] tvalue1 = r1.getValue(HConstants.CATALOG_FAMILY, qualifier);
+ int result1 = Bytes.compareTo(value, tvalue1);
+ assertEquals(result1, 0);
+
+ HColumnDescriptor hcd = new HColumnDescriptor(HConstants.CATALOG_FAMILY);
+ hcd.setMaxVersions(99);
+ hcd.setBlockCacheEnabled(false);
+
+ admin.modifyColumn(Bytes.toBytes(tableName), hcd, true);
+ //waitForSchemaChangeProcess(tableName);
+
+ // Take a mini nap for changes to take effect.
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+
+ List onlineRegions
+ = miniHBaseCluster.getRegions(Bytes.toBytes("testSchemachangeForModifyColumn"));
+ for (HRegion onlineRegion : onlineRegions) {
+ HTableDescriptor htd = onlineRegion.getTableDesc();
+ HColumnDescriptor tableHcd = htd.getFamily(HConstants.CATALOG_FAMILY);
+ assertTrue(tableHcd.isBlockCacheEnabled() == false);
+ assertEquals(tableHcd.getMaxVersions(), 99);
+ }
+ LOG.info("End testInstantSchemaChangeForModifyColumn() ");
+
+ }
+
+ @Test
+ public void testInstantSchemaChangeForDeleteColumn() throws IOException,
+ KeeperException {
+ LOG.info("Start testInstantSchemaChangeForDeleteColumn() ");
+ String tableName = "testSchemachangeForDeleteColumn";
+ int numTables = 0;
+ HTableDescriptor[] tables = admin.listTables();
+ if (tables != null) {
+ numTables = tables.length;
+ }
+
+ byte[][] FAMILIES = new byte[][] {
+ Bytes.toBytes("A"), Bytes.toBytes("B"), Bytes.toBytes("C") };
+
+ HTable ht = TEST_UTIL.createTable(Bytes.toBytes(tableName),
+ FAMILIES);
+ tables = this.admin.listTables();
+ assertEquals(numTables + 1, tables.length);
+ LOG.info("Table testSchemachangeForDeleteColumn created");
+
+ admin.deleteColumn(tableName, "C", true);
+
+ //waitForSchemaChangeProcess(tableName);
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ }
+
+ HTableDescriptor modifiedHtd = this.admin.getTableDescriptor(Bytes.toBytes(tableName));
+ HColumnDescriptor hcd = modifiedHtd.getFamily(Bytes.toBytes("C"));
+ assertTrue(hcd == null);
+ LOG.info("End testInstantSchemaChangeForDeleteColumn() ");
+ }
+
+ @Test
+ public void testInstantSchemaOperationsInZK() throws IOException, KeeperException {
+ LOG.info("testInstantSchemaOperationsInZK() ");
+
+ conf = TEST_UTIL.getConfiguration();
+ zkw = new ZooKeeperWatcher(conf, "instant-schema-change-tests", null);
+ ZKUtil.createAndFailSilent(zkw, zkw.schemaZNode);
+ assertTrue(ZKUtil.checkExists(zkw, zkw.schemaZNode) != -1);
+ LOG.debug(zkw.schemaZNode + " created");
+
+ MasterSchemaChangeTracker msct =
+ TEST_UTIL.getHBaseCluster().getMaster().getSchemaChangeTracker();
+
+ msct.createSchemaChangeNode("testSchemachangeNode");
+ LOG.debug(msct.getSchemaChangeNodePathForTable("testSchemachangeNode")
+ + " created");
+
+ String nodePath = msct.getSchemaChangeNodePathForTable("testSchemachangeNode");
+ assertTrue(ZKUtil.checkExists(zkw, nodePath) != -1);
+ waitForSchemaChangeProcess("testSchemachangeNode");
+
+ assertTrue(ZKUtil.checkExists(zkw, nodePath) == -1);
+ LOG.debug(msct.getSchemaChangeNodePathForTable("testSchemachangeNode")
+ + " deleted");
+
+ }
+
+}
+