hbase-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From apurt...@apache.org
Subject hbase git commit: HBASE-12980 Delete of a table may not clean all rows from hbase:meta
Date Sat, 07 Feb 2015 00:51:04 GMT
Repository: hbase
Updated Branches:
  refs/heads/0.98 d776789fc -> be82ea78f


HBASE-12980 Delete of a table may not clean all rows from hbase:meta

Conflicts:
	hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
	hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestDeleteTableHandler.java

Amending-Author: Andrew Purtell <apurtell@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/be82ea78
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/be82ea78
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/be82ea78

Branch: refs/heads/0.98
Commit: be82ea78f3cee109ce30b8c72b6ed4ac09df7ed6
Parents: d776789
Author: stack <stack@apache.org>
Authored: Fri Feb 6 16:50:45 2015 -0800
Committer: Andrew Purtell <apurtell@apache.org>
Committed: Fri Feb 6 16:50:45 2015 -0800

----------------------------------------------------------------------
 .../master/handler/DeleteTableHandler.java      |  41 +++++++
 .../hadoop/hbase/HBaseTestingUtility.java       |  43 ++++++++
 .../master/handler/TestDeleteTableHandler.java  | 109 +++++++++++++++++++
 3 files changed, 193 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/be82ea78/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
index 7b182b8..474da0a 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/handler/DeleteTableHandler.java
@@ -19,11 +19,17 @@
 package org.apache.hadoop.hbase.master.handler;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.TableName;
@@ -31,6 +37,7 @@ import org.apache.hadoop.hbase.HRegionInfo;
 import org.apache.hadoop.hbase.Server;
 import org.apache.hadoop.hbase.backup.HFileArchiver;
 import org.apache.hadoop.hbase.catalog.MetaEditor;
+import org.apache.hadoop.hbase.catalog.MetaReader;
 import org.apache.hadoop.hbase.executor.EventType;
 import org.apache.hadoop.hbase.master.AssignmentManager;
 import org.apache.hadoop.hbase.master.HMaster;
@@ -124,6 +131,9 @@ public class DeleteTableHandler extends TableEventHandler {
       // 8. If entry for this table in zk, and up in AssignmentManager, remove it.
       LOG.debug("Marking '" + tableName + "' as deleted.");
       am.getZKTable().setDeletedTable(tableName);
+
+      // 9. Clean up any remaining rows for this table
+      cleanAnyRemainingRows();
     }
 
     if (cpHost != null) {
@@ -131,6 +141,37 @@ public class DeleteTableHandler extends TableEventHandler {
     }
   }
 
+  /**
+   * There may be items for this table still up in hbase:meta in the case where the
+   * info:regioninfo column was empty because of some write error. Remove ALL rows from hbase:meta
+   * that have to do with this table. See HBASE-12980.
+   * @throws IOException
+   */
+  private void cleanAnyRemainingRows() throws IOException {
+    Scan tableScan = MetaReader.getScanForTableName(tableName);
+    HTable metaTable = new HTable(TableName.META_TABLE_NAME, 
+      this.masterServices.getCatalogTracker().getConnection());
+    try {
+      List<Delete> deletes = new ArrayList<Delete>();
+      ResultScanner resScanner = metaTable.getScanner(tableScan);
+      try {
+        for (Result result : resScanner) {
+          deletes.add(new Delete(result.getRow()));
+        }
+      } finally {
+        resScanner.close();
+      }
+      if (!deletes.isEmpty()) {
+        LOG.warn("Deleting some vestigal " + deletes.size() + " rows of " + this.tableName
+
+          " from " + TableName.META_TABLE_NAME);
+        metaTable.delete(deletes);
+      }
+    } finally {
+      metaTable.close();
+    }
+  }
+
+  
   @Override
   protected void releaseTableLock() {
     super.releaseTableLock();

http://git-wip-us.apache.org/repos/asf/hbase/blob/be82ea78/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
index 2673e5a..6b02205 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java
@@ -2770,6 +2770,48 @@ public class HBaseTestingUtility extends HBaseCommonTestingUtility
{
   }
 
   /**
+   * Waits for a table to be 'disabled'.  Disabled means that table is set as 'disabled'
+   * Will timeout after default period (30 seconds)
+   * @param table Table to wait on.
+   * @throws InterruptedException
+   * @throws IOException
+   */
+  public void waitTableDisabled(byte[] table)
+      throws InterruptedException, IOException {
+    waitTableDisabled(getHBaseAdmin(), table, 30000);
+  }
+
+  public void waitTableDisabled(HBaseAdmin admin, byte[] table)
+      throws InterruptedException, IOException {
+    waitTableDisabled(admin, table, 30000);
+  }
+
+  /**
+   * Waits for a table to be 'disabled'.  Disabled means that table is set as 'disabled'
+   * @param table Table to wait on.
+   * @param timeoutMillis Time to wait on it being marked disabled.
+   * @throws InterruptedException
+   * @throws IOException
+   */
+  public void waitTableDisabled(byte[] table, long timeoutMillis)
+      throws InterruptedException, IOException {
+    waitTableDisabled(getHBaseAdmin(), table, timeoutMillis);
+  }
+
+  public void waitTableDisabled(HBaseAdmin admin, byte[] table, long timeoutMillis)
+      throws InterruptedException, IOException {
+    TableName tableName = TableName.valueOf(table);
+    long startWait = System.currentTimeMillis();
+    while (!admin.isTableDisabled(tableName)) {
+      assertTrue("Timed out waiting for table to become disabled " +
+              Bytes.toStringBinary(table),
+          System.currentTimeMillis() - startWait < timeoutMillis);
+      Thread.sleep(200);
+    }
+  }
+
+  /**
+   * 
    * Make sure that at least the specified number of region servers
    * are running
    * @param num minimum number of region servers that should be running
@@ -3515,4 +3557,5 @@ public class HBaseTestingUtility extends HBaseCommonTestingUtility {
     }
     return supportedAlgos.toArray(new Algorithm[supportedAlgos.size()]);
   }
+
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/be82ea78/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestDeleteTableHandler.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestDeleteTableHandler.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestDeleteTableHandler.java
new file mode 100644
index 0000000..3962c2f
--- /dev/null
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestDeleteTableHandler.java
@@ -0,0 +1,109 @@
+/**
+ *
+ * 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.master.handler;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.testclassification.MediumTests;
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.catalog.MetaReader;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(MediumTests.class)
+public class TestDeleteTableHandler {
+  private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
+  private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
+
+  @Before
+  public void setUp() throws Exception {
+    TEST_UTIL.startMiniCluster(1);
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    TEST_UTIL.shutdownMiniCluster();
+  }
+
+  /**
+   * We were only clearing rows that had a hregioninfo column in hbase:meta.  Mangled rows
that
+   * were missing the hregioninfo because of error were being left behind messing up any
+   * subsequent table made with the same name. HBASE-12980
+   * @throws IOException
+   * @throws InterruptedException
+   */
+  @Test(timeout=60000)
+  public void testDeleteForSureClearsAllTableRowsFromMeta()
+  throws IOException, InterruptedException {
+    final TableName tableName = TableName.valueOf("testDeleteForSureClearsAllTableRowsFromMeta");
+    final HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
+    final HTableDescriptor desc = new HTableDescriptor(tableName);
+    desc.addFamily(new HColumnDescriptor(FAMILYNAME));
+    admin.createTable(desc, HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE);
+    // Now I have a nice table, mangle it by removing the HConstants.REGIONINFO_QUALIFIER_STR
+    // content from a few of the rows.
+    Scan metaScannerForMyTable = MetaReader.getScanForTableName(tableName);
+    HTable metaTable = new HTable(TEST_UTIL.getConfiguration(), TableName.META_TABLE_NAME);
+    try {
+      ResultScanner scanner = metaTable.getScanner(metaScannerForMyTable);
+      try {
+        for (Result result : scanner) {
+          // Just delete one row.
+          Delete d = new Delete(result.getRow());
+          d.deleteColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+          metaTable.delete(d);
+          break;
+        }
+      } finally {
+        scanner.close();
+      }
+      admin.disableTable(tableName);
+      TEST_UTIL.waitTableDisabled(tableName.getName());
+      admin.deleteTable(tableName);
+      int rowCount = 0;
+      scanner = metaTable.getScanner(metaScannerForMyTable);
+      try {
+        for (Result result : scanner) {
+          rowCount++;
+        }
+      } finally {
+        scanner.close();
+      }
+      assertEquals(0, rowCount);
+    } finally {
+      metaTable.close();
+    }
+  }
+}
+


Mime
View raw message