You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jm...@apache.org on 2015/02/22 21:55:43 UTC
[10/50] [abbrv] hbase git commit: HBASE-12980 Delete of a table may
not clean all rows from hbase:meta
HBASE-12980 Delete of a table may not clean all rows from hbase:meta
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/57319c53
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/57319c53
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/57319c53
Branch: refs/heads/hbase-11339
Commit: 57319c536a136d331b925614417a8deba159ad8c
Parents: 7514838
Author: stack <st...@apache.org>
Authored: Fri Feb 6 14:06:42 2015 -0800
Committer: stack <st...@apache.org>
Committed: Fri Feb 6 14:06:59 2015 -0800
----------------------------------------------------------------------
.../master/handler/DeleteTableHandler.java | 45 ++++++++++++++---
.../master/handler/TestEnableTableHandler.java | 52 ++++++++++++++++++++
2 files changed, 91 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/57319c53/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 004e2bb..092a17d 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
@@ -18,31 +18,37 @@
*/
package org.apache.hadoop.hbase.master.handler;
-import java.io.InterruptedIOException;
import java.io.IOException;
+import java.io.InterruptedIOException;
+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.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.CoordinatedStateException;
-import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.Server;
+import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.backup.HFileArchiver;
-import org.apache.hadoop.hbase.MetaTableAccessor;
+import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.client.Delete;
+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.client.Table;
import org.apache.hadoop.hbase.executor.EventType;
-import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.master.AssignmentManager;
import org.apache.hadoop.hbase.master.HMaster;
import org.apache.hadoop.hbase.master.MasterCoprocessorHost;
import org.apache.hadoop.hbase.master.MasterFileSystem;
import org.apache.hadoop.hbase.master.MasterServices;
-import org.apache.hadoop.hbase.master.RegionStates;
import org.apache.hadoop.hbase.master.RegionState.State;
+import org.apache.hadoop.hbase.master.RegionStates;
+import org.apache.hadoop.hbase.regionserver.HRegion;
@InterfaceAudience.Private
public class DeleteTableHandler extends TableEventHandler {
@@ -125,6 +131,33 @@ public class DeleteTableHandler extends TableEventHandler {
// 5. If entry for this table states, remove it.
LOG.debug("Marking '" + tableName + "' as deleted.");
am.getTableStateManager().setDeletedTable(tableName);
+
+ // 6.Clean any remaining rows for this table.
+ cleanAnyRemainingRows();
+ }
+
+ /**
+ * 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 = MetaTableAccessor.getScanForTableName(tableName);
+ try (Table metaTable =
+ this.masterServices.getConnection().getTable(TableName.META_TABLE_NAME)) {
+ List<Delete> deletes = new ArrayList<Delete>();
+ try (ResultScanner resScanner = metaTable.getScanner(tableScan)) {
+ for (Result result : resScanner) {
+ deletes.add(new Delete(result.getRow()));
+ }
+ }
+ if (!deletes.isEmpty()) {
+ LOG.warn("Deleting some vestigal " + deletes.size() + " rows of " + this.tableName +
+ " from " + TableName.META_TABLE_NAME);
+ metaTable.delete(deletes);
+ }
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/hbase/blob/57319c53/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestEnableTableHandler.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestEnableTableHandler.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestEnableTableHandler.java
index f5f2cd0..89fd9ba 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestEnableTableHandler.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/handler/TestEnableTableHandler.java
@@ -22,6 +22,8 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.MetaTableAccessor;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
@@ -42,6 +44,13 @@ import org.junit.experimental.categories.Category;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import java.io.IOException;
+import org.apache.hadoop.hbase.client.Delete;
+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.client.Table;
+
@Category({ MasterTests.class, MediumTests.class })
public class TestEnableTableHandler {
private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
@@ -98,4 +107,47 @@ public class TestEnableTableHandler {
assertEquals(tableName, onlineRegions.get(0).getTable());
}
+ /**
+ * 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 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
+ final HMaster m = cluster.getMaster();
+ 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 = MetaTableAccessor.getScanForTableName(tableName);
+ try (Table metaTable = TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME)) {
+ try (ResultScanner scanner = metaTable.getScanner(metaScannerForMyTable)) {
+ for (Result result : scanner) {
+ // Just delete one row.
+ Delete d = new Delete(result.getRow());
+ d.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
+ metaTable.delete(d);
+ break;
+ }
+ }
+ admin.disableTable(tableName);
+ TEST_UTIL.waitTableDisabled(tableName.getName());
+ // Presume this synchronous all is.
+ admin.deleteTable(tableName);
+ int rowCount = 0;
+ try (ResultScanner scanner = metaTable.getScanner(metaScannerForMyTable)) {
+ for (Result result : scanner) {
+ rowCount++;
+ }
+ }
+ assertEquals(0, rowCount);
+ }
+ }
}