HBASE-3650 HBA.delete can return too fast
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1082204 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8963351fc1
commit
a8beafc5cf
|
@ -167,6 +167,7 @@ Release 0.90.2 - Unreleased
|
|||
HBASE-3639 FSUtils.getRootDir should qualify path
|
||||
HBASE-3648 [replication] failover is sloppy with znodes
|
||||
HBASE-3613 NPE in MemStoreFlusher
|
||||
HBASE-3650 HBA.delete can return too fast
|
||||
|
||||
IMPROVEMENTS
|
||||
HBASE-3542 MultiGet methods in Thrift
|
||||
|
|
|
@ -431,22 +431,15 @@ public class MetaReader {
|
|||
}
|
||||
HRegionInterface metaServer =
|
||||
catalogTracker.waitForMetaServerConnectionDefault();
|
||||
byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
|
||||
Scan scan = new Scan(firstRowInTable);
|
||||
Scan scan = getScanForTableName(Bytes.toBytes(tableName));
|
||||
scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
|
||||
long scannerid = metaServer.openScanner(
|
||||
HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), scan);
|
||||
try {
|
||||
Result data = metaServer.next(scannerid);
|
||||
if (data != null && data.size() > 0) {
|
||||
HRegionInfo info = Writables.getHRegionInfo(
|
||||
data.getValue(HConstants.CATALOG_FAMILY,
|
||||
HConstants.REGIONINFO_QUALIFIER));
|
||||
if (info.getTableDesc().getNameAsString().equals(tableName)) {
|
||||
// A region for this table already exists. Ergo table exists.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
metaServer.close(scannerid);
|
||||
|
@ -494,9 +487,8 @@ public class MetaReader {
|
|||
HRegionInterface metaServer =
|
||||
getCatalogRegionInterface(catalogTracker, tableName);
|
||||
List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
|
||||
String tableString = Bytes.toString(tableName);
|
||||
byte[] firstRowInTable = Bytes.toBytes(tableString + ",,");
|
||||
Scan scan = new Scan(firstRowInTable);
|
||||
|
||||
Scan scan = getScanForTableName(tableName);
|
||||
scan.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
|
||||
long scannerid =
|
||||
metaServer.openScanner(getCatalogRegionNameForTable(tableName), scan);
|
||||
|
@ -507,13 +499,8 @@ public class MetaReader {
|
|||
HRegionInfo info = Writables.getHRegionInfo(
|
||||
data.getValue(HConstants.CATALOG_FAMILY,
|
||||
HConstants.REGIONINFO_QUALIFIER));
|
||||
if (info.getTableDesc().getNameAsString().equals(tableString)) {
|
||||
// Are we to include split parents in the list?
|
||||
if (excludeOfflinedSplitParents && info.isSplitParent()) continue;
|
||||
regions.add(info);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return regions;
|
||||
|
@ -522,6 +509,27 @@ public class MetaReader {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates a Scan object that will only scan catalog rows that
|
||||
* belong to the specified table. It doesn't specify any columns.
|
||||
* This is a better alternative to just using a start row and scan until
|
||||
* it hits a new table since that requires parsing the HRI to get the table
|
||||
* name.
|
||||
* @param tableName bytes of table's name
|
||||
* @return configured Scan object
|
||||
*/
|
||||
public static Scan getScanForTableName(byte[] tableName) {
|
||||
String strName = Bytes.toString(tableName);
|
||||
// Start key is just the table name with delimiters
|
||||
byte[] startKey = Bytes.toBytes(strName + ",,");
|
||||
// Stop key appends the smallest possible char to the table name
|
||||
byte[] stopKey = Bytes.toBytes(strName + " ,,");
|
||||
|
||||
Scan scan = new Scan(startKey);
|
||||
scan.setStopRow(stopKey);
|
||||
return scan;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param catalogTracker
|
||||
* @param tableName
|
||||
|
@ -545,8 +553,7 @@ public class MetaReader {
|
|||
getCatalogRegionInterface(catalogTracker, tableNameBytes);
|
||||
List<Pair<HRegionInfo, HServerAddress>> regions =
|
||||
new ArrayList<Pair<HRegionInfo, HServerAddress>>();
|
||||
byte[] firstRowInTable = Bytes.toBytes(tableName + ",,");
|
||||
Scan scan = new Scan(firstRowInTable);
|
||||
Scan scan = getScanForTableName(tableNameBytes);
|
||||
scan.addFamily(HConstants.CATALOG_FAMILY);
|
||||
long scannerid =
|
||||
metaServer.openScanner(getCatalogRegionNameForTable(tableNameBytes), scan);
|
||||
|
@ -556,12 +563,7 @@ public class MetaReader {
|
|||
if (data != null && data.size() > 0) {
|
||||
Pair<HRegionInfo, HServerAddress> region = metaRowToRegionPair(data);
|
||||
if (region == null) continue;
|
||||
if (region.getFirst().getTableDesc().getNameAsString().equals(
|
||||
tableName)) {
|
||||
regions.add(region);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return regions;
|
||||
|
|
|
@ -22,8 +22,6 @@ package org.apache.hadoop.hbase.client;
|
|||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NavigableMap;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
@ -49,7 +47,6 @@ import org.apache.hadoop.hbase.ipc.HMasterInterface;
|
|||
import org.apache.hadoop.hbase.ipc.HRegionInterface;
|
||||
import org.apache.hadoop.hbase.util.Bytes;
|
||||
import org.apache.hadoop.hbase.util.Pair;
|
||||
import org.apache.hadoop.hbase.util.Writables;
|
||||
import org.apache.hadoop.ipc.RemoteException;
|
||||
|
||||
/**
|
||||
|
@ -371,40 +368,21 @@ public class HBaseAdmin implements Abortable {
|
|||
} catch (RemoteException e) {
|
||||
throw RemoteExceptionHandler.decodeRemoteException(e);
|
||||
}
|
||||
final int batchCount = this.conf.getInt("hbase.admin.scanner.caching", 10);
|
||||
// Wait until all regions deleted
|
||||
HRegionInterface server =
|
||||
connection.getHRegionConnection(firstMetaServer.getServerAddress());
|
||||
HRegionInfo info = new HRegionInfo();
|
||||
for (int tries = 0; tries < (this.numRetries * this.retryLongerMultiplier); tries++) {
|
||||
long scannerId = -1L;
|
||||
try {
|
||||
Scan scan = new Scan().addColumn(HConstants.CATALOG_FAMILY,
|
||||
|
||||
Scan scan = MetaReader.getScanForTableName(tableName);
|
||||
scan.addColumn(HConstants.CATALOG_FAMILY,
|
||||
HConstants.REGIONINFO_QUALIFIER);
|
||||
scannerId = server.openScanner(
|
||||
firstMetaServer.getRegionInfo().getRegionName(), scan);
|
||||
// Get a batch at a time.
|
||||
Result [] values = server.next(scannerId, batchCount);
|
||||
if (values == null || values.length == 0) {
|
||||
break;
|
||||
}
|
||||
boolean found = false;
|
||||
for (Result r : values) {
|
||||
NavigableMap<byte[], byte[]> infoValues =
|
||||
r.getFamilyMap(HConstants.CATALOG_FAMILY);
|
||||
for (Map.Entry<byte[], byte[]> e : infoValues.entrySet()) {
|
||||
if (Bytes.equals(e.getKey(), HConstants.REGIONINFO_QUALIFIER)) {
|
||||
info = (HRegionInfo) Writables.getWritable(e.getValue(), info);
|
||||
if (Bytes.equals(info.getTableDesc().getName(), tableName)) {
|
||||
found = true;
|
||||
} else {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
Result values = server.next(scannerId);
|
||||
if (values == null) {
|
||||
break;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
|
|
|
@ -130,4 +130,34 @@ public class TestMetaReaderEditor {
|
|||
pair.getFirst().getEncodedName());
|
||||
LOG.info("Finished " + name);
|
||||
}
|
||||
|
||||
// Test for the optimization made in HBASE-3650
|
||||
@Test public void testScanMetaForTable() throws IOException {
|
||||
final String name = "testScanMetaForTable";
|
||||
LOG.info("Started " + name);
|
||||
|
||||
/** Create 5 tables
|
||||
- testScanMetaForTable
|
||||
- testScanMetaForTable0
|
||||
- testScanMetaForTable1
|
||||
- testScanMetaForTable2
|
||||
- testScanMetaForTablf
|
||||
**/
|
||||
|
||||
UTIL.createTable(Bytes.toBytes(name), HConstants.CATALOG_FAMILY);
|
||||
for (int i = 3; i < 3; i ++) {
|
||||
UTIL.createTable(Bytes.toBytes(name+i), HConstants.CATALOG_FAMILY);
|
||||
}
|
||||
// name that is +1 greater than the first one (e+1=f)
|
||||
byte[] greaterName = Bytes.toBytes("testScanMetaForTablf");
|
||||
UTIL.createTable(greaterName, HConstants.CATALOG_FAMILY);
|
||||
|
||||
// Now make sure we only get the regions from 1 of the tables at a time
|
||||
|
||||
assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name)).size());
|
||||
for (int i = 3; i < 3; i ++) {
|
||||
assertEquals(1, MetaReader.getTableRegions(ct, Bytes.toBytes(name+i)).size());
|
||||
}
|
||||
assertEquals(1, MetaReader.getTableRegions(ct, greaterName).size());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue