From commits-return-67066-archive-asf-public=cust-asf.ponee.io@hbase.apache.org Sun Feb 4 16:14:19 2018 Return-Path: X-Original-To: archive-asf-public@eu.ponee.io Delivered-To: archive-asf-public@eu.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by mx-eu-01.ponee.io (Postfix) with ESMTP id 8FED3180677 for ; Sun, 4 Feb 2018 16:14:19 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 7FB28160C64; Sun, 4 Feb 2018 15:14:19 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 2B389160C5E for ; Sun, 4 Feb 2018 16:14:17 +0100 (CET) Received: (qmail 19895 invoked by uid 500); 4 Feb 2018 15:14:15 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 19600 invoked by uid 99); 4 Feb 2018 15:14:15 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 04 Feb 2018 15:14:15 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id D0CB8F4DE2; Sun, 4 Feb 2018 15:14:13 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: git-site-role@apache.org To: commits@hbase.apache.org Date: Sun, 04 Feb 2018 15:14:39 -0000 Message-Id: <6447c2ed31dd40359fdbf2b1fad1acbc@git.apache.org> In-Reply-To: <2249bb5ddff74eb1ac2ed001d482235c@git.apache.org> References: <2249bb5ddff74eb1ac2ed001d482235c@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [28/51] [partial] hbase-site git commit: Published site at . http://git-wip-us.apache.org/repos/asf/hbase-site/blob/6674e3ab/devapidocs/src-html/org/apache/hadoop/hbase/MetaTableAccessor.CollectingVisitor.html ---------------------------------------------------------------------- diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/MetaTableAccessor.CollectingVisitor.html b/devapidocs/src-html/org/apache/hadoop/hbase/MetaTableAccessor.CollectingVisitor.html index ad601c4..53e455f 100644 --- a/devapidocs/src-html/org/apache/hadoop/hbase/MetaTableAccessor.CollectingVisitor.html +++ b/devapidocs/src-html/org/apache/hadoop/hbase/MetaTableAccessor.CollectingVisitor.html @@ -1117,1183 +1117,1186 @@ 1109 @Nullable 1110 public static TableState getTableState(Connection conn, TableName tableName) 1111 throws IOException { -1112 Table metaHTable = getMetaHTable(conn); -1113 Get get = new Get(tableName.getName()).addColumn(getTableFamily(), getTableStateColumn()); -1114 long time = EnvironmentEdgeManager.currentTime(); -1115 get.setTimeRange(0, time); -1116 Result result = -1117 metaHTable.get(get); -1118 return getTableState(result); -1119 } -1120 -1121 /** -1122 * Fetch table states from META table -1123 * @param conn connection to use -1124 * @return map {tableName -&gt; state} -1125 * @throws IOException -1126 */ -1127 public static Map<TableName, TableState> getTableStates(Connection conn) -1128 throws IOException { -1129 final Map<TableName, TableState> states = new LinkedHashMap<>(); -1130 Visitor collector = new Visitor() { -1131 @Override -1132 public boolean visit(Result r) throws IOException { -1133 TableState state = getTableState(r); -1134 if (state != null) -1135 states.put(state.getTableName(), state); -1136 return true; -1137 } -1138 }; -1139 fullScanTables(conn, collector); -1140 return states; -1141 } -1142 -1143 /** -1144 * Updates state in META -1145 * @param conn connection to use -1146 * @param tableName table to look for -1147 * @throws IOException -1148 */ -1149 public static void updateTableState(Connection conn, TableName tableName, -1150 TableState.State actual) throws IOException { -1151 updateTableState(conn, new TableState(tableName, actual)); -1152 } -1153 -1154 /** -1155 * Decode table state from META Result. -1156 * Should contain cell from HConstants.TABLE_FAMILY -1157 * @param r result -1158 * @return null if not found -1159 * @throws IOException -1160 */ -1161 @Nullable -1162 public static TableState getTableState(Result r) -1163 throws IOException { -1164 Cell cell = r.getColumnLatestCell(getTableFamily(), getTableStateColumn()); -1165 if (cell == null) return null; -1166 try { -1167 return TableState.parseFrom(TableName.valueOf(r.getRow()), -1168 Arrays.copyOfRange(cell.getValueArray(), -1169 cell.getValueOffset(), cell.getValueOffset() + cell.getValueLength())); -1170 } catch (DeserializationException e) { -1171 throw new IOException(e); -1172 } -1173 -1174 } -1175 -1176 /** -1177 * Implementations 'visit' a catalog table row. -1178 */ -1179 public interface Visitor { -1180 /** -1181 * Visit the catalog table row. -1182 * @param r A row from catalog table -1183 * @return True if we are to proceed scanning the table, else false if -1184 * we are to stop now. -1185 */ -1186 boolean visit(final Result r) throws IOException; -1187 } -1188 -1189 /** -1190 * Implementations 'visit' a catalog table row but with close() at the end. -1191 */ -1192 public interface CloseableVisitor extends Visitor, Closeable { -1193 } -1194 -1195 /** -1196 * A {@link Visitor} that collects content out of passed {@link Result}. -1197 */ -1198 static abstract class CollectingVisitor<T> implements Visitor { -1199 final List<T> results = new ArrayList<>(); -1200 @Override -1201 public boolean visit(Result r) throws IOException { -1202 if (r == null || r.isEmpty()) return true; -1203 add(r); -1204 return true; -1205 } -1206 -1207 abstract void add(Result r); -1208 -1209 /** -1210 * @return Collected results; wait till visits complete to collect all -1211 * possible results -1212 */ -1213 List<T> getResults() { -1214 return this.results; -1215 } -1216 } -1217 -1218 /** -1219 * Collects all returned. -1220 */ -1221 static class CollectAllVisitor extends CollectingVisitor<Result> { -1222 @Override -1223 void add(Result r) { -1224 this.results.add(r); -1225 } -1226 } -1227 -1228 /** -1229 * A Visitor that skips offline regions and split parents -1230 */ -1231 public static abstract class DefaultVisitorBase implements Visitor { -1232 -1233 public DefaultVisitorBase() { -1234 super(); -1235 } -1236 -1237 public abstract boolean visitInternal(Result rowResult) throws IOException; -1238 -1239 @Override -1240 public boolean visit(Result rowResult) throws IOException { -1241 RegionInfo info = getRegionInfo(rowResult); -1242 if (info == null) { -1243 return true; -1244 } -1245 -1246 //skip over offline and split regions -1247 if (!(info.isOffline() || info.isSplit())) { -1248 return visitInternal(rowResult); -1249 } -1250 return true; -1251 } -1252 } -1253 -1254 /** -1255 * A Visitor for a table. Provides a consistent view of the table's -1256 * hbase:meta entries during concurrent splits (see HBASE-5986 for details). This class -1257 * does not guarantee ordered traversal of meta entries, and can block until the -1258 * hbase:meta entries for daughters are available during splits. -1259 */ -1260 public static abstract class TableVisitorBase extends DefaultVisitorBase { -1261 private TableName tableName; -1262 -1263 public TableVisitorBase(TableName tableName) { -1264 super(); -1265 this.tableName = tableName; -1266 } -1267 -1268 @Override -1269 public final boolean visit(Result rowResult) throws IOException { -1270 RegionInfo info = getRegionInfo(rowResult); -1271 if (info == null) { -1272 return true; -1273 } -1274 if (!(info.getTable().equals(tableName))) { -1275 return false; +1112 if (tableName.equals(TableName.META_TABLE_NAME)) { +1113 return new TableState(tableName, TableState.State.ENABLED); +1114 } +1115 Table metaHTable = getMetaHTable(conn); +1116 Get get = new Get(tableName.getName()).addColumn(getTableFamily(), getTableStateColumn()); +1117 long time = EnvironmentEdgeManager.currentTime(); +1118 get.setTimeRange(0, time); +1119 Result result = +1120 metaHTable.get(get); +1121 return getTableState(result); +1122 } +1123 +1124 /** +1125 * Fetch table states from META table +1126 * @param conn connection to use +1127 * @return map {tableName -&gt; state} +1128 * @throws IOException +1129 */ +1130 public static Map<TableName, TableState> getTableStates(Connection conn) +1131 throws IOException { +1132 final Map<TableName, TableState> states = new LinkedHashMap<>(); +1133 Visitor collector = new Visitor() { +1134 @Override +1135 public boolean visit(Result r) throws IOException { +1136 TableState state = getTableState(r); +1137 if (state != null) +1138 states.put(state.getTableName(), state); +1139 return true; +1140 } +1141 }; +1142 fullScanTables(conn, collector); +1143 return states; +1144 } +1145 +1146 /** +1147 * Updates state in META +1148 * @param conn connection to use +1149 * @param tableName table to look for +1150 * @throws IOException +1151 */ +1152 public static void updateTableState(Connection conn, TableName tableName, +1153 TableState.State actual) throws IOException { +1154 updateTableState(conn, new TableState(tableName, actual)); +1155 } +1156 +1157 /** +1158 * Decode table state from META Result. +1159 * Should contain cell from HConstants.TABLE_FAMILY +1160 * @param r result +1161 * @return null if not found +1162 * @throws IOException +1163 */ +1164 @Nullable +1165 public static TableState getTableState(Result r) +1166 throws IOException { +1167 Cell cell = r.getColumnLatestCell(getTableFamily(), getTableStateColumn()); +1168 if (cell == null) return null; +1169 try { +1170 return TableState.parseFrom(TableName.valueOf(r.getRow()), +1171 Arrays.copyOfRange(cell.getValueArray(), +1172 cell.getValueOffset(), cell.getValueOffset() + cell.getValueLength())); +1173 } catch (DeserializationException e) { +1174 throw new IOException(e); +1175 } +1176 +1177 } +1178 +1179 /** +1180 * Implementations 'visit' a catalog table row. +1181 */ +1182 public interface Visitor { +1183 /** +1184 * Visit the catalog table row. +1185 * @param r A row from catalog table +1186 * @return True if we are to proceed scanning the table, else false if +1187 * we are to stop now. +1188 */ +1189 boolean visit(final Result r) throws IOException; +1190 } +1191 +1192 /** +1193 * Implementations 'visit' a catalog table row but with close() at the end. +1194 */ +1195 public interface CloseableVisitor extends Visitor, Closeable { +1196 } +1197 +1198 /** +1199 * A {@link Visitor} that collects content out of passed {@link Result}. +1200 */ +1201 static abstract class CollectingVisitor<T> implements Visitor { +1202 final List<T> results = new ArrayList<>(); +1203 @Override +1204 public boolean visit(Result r) throws IOException { +1205 if (r == null || r.isEmpty()) return true; +1206 add(r); +1207 return true; +1208 } +1209 +1210 abstract void add(Result r); +1211 +1212 /** +1213 * @return Collected results; wait till visits complete to collect all +1214 * possible results +1215 */ +1216 List<T> getResults() { +1217 return this.results; +1218 } +1219 } +1220 +1221 /** +1222 * Collects all returned. +1223 */ +1224 static class CollectAllVisitor extends CollectingVisitor<Result> { +1225 @Override +1226 void add(Result r) { +1227 this.results.add(r); +1228 } +1229 } +1230 +1231 /** +1232 * A Visitor that skips offline regions and split parents +1233 */ +1234 public static abstract class DefaultVisitorBase implements Visitor { +1235 +1236 public DefaultVisitorBase() { +1237 super(); +1238 } +1239 +1240 public abstract boolean visitInternal(Result rowResult) throws IOException; +1241 +1242 @Override +1243 public boolean visit(Result rowResult) throws IOException { +1244 RegionInfo info = getRegionInfo(rowResult); +1245 if (info == null) { +1246 return true; +1247 } +1248 +1249 //skip over offline and split regions +1250 if (!(info.isOffline() || info.isSplit())) { +1251 return visitInternal(rowResult); +1252 } +1253 return true; +1254 } +1255 } +1256 +1257 /** +1258 * A Visitor for a table. Provides a consistent view of the table's +1259 * hbase:meta entries during concurrent splits (see HBASE-5986 for details). This class +1260 * does not guarantee ordered traversal of meta entries, and can block until the +1261 * hbase:meta entries for daughters are available during splits. +1262 */ +1263 public static abstract class TableVisitorBase extends DefaultVisitorBase { +1264 private TableName tableName; +1265 +1266 public TableVisitorBase(TableName tableName) { +1267 super(); +1268 this.tableName = tableName; +1269 } +1270 +1271 @Override +1272 public final boolean visit(Result rowResult) throws IOException { +1273 RegionInfo info = getRegionInfo(rowResult); +1274 if (info == null) { +1275 return true; 1276 } -1277 return super.visit(rowResult); -1278 } -1279 } -1280 -1281 /** -1282 * Count regions in <code>hbase:meta</code> for passed table. -1283 * @param c Configuration object -1284 * @param tableName table name to count regions for -1285 * @return Count or regions in table <code>tableName</code> -1286 * @throws IOException -1287 */ -1288 public static int getRegionCount(final Configuration c, final TableName tableName) -1289 throws IOException { -1290 try (Connection connection = ConnectionFactory.createConnection(c)) { -1291 return getRegionCount(connection, tableName); -1292 } -1293 } -1294 -1295 /** -1296 * Count regions in <code>hbase:meta</code> for passed table. -1297 * @param connection Connection object -1298 * @param tableName table name to count regions for -1299 * @return Count or regions in table <code>tableName</code> -1300 * @throws IOException -1301 */ -1302 public static int getRegionCount(final Connection connection, final TableName tableName) -1303 throws IOException { -1304 try (RegionLocator locator = connection.getRegionLocator(tableName)) { -1305 List<HRegionLocation> locations = locator.getAllRegionLocations(); -1306 return locations == null? 0: locations.size(); -1307 } -1308 } -1309 -1310 //////////////////////// -1311 // Editing operations // -1312 //////////////////////// -1313 -1314 /** -1315 * Generates and returns a Put containing the region into for the catalog table -1316 */ -1317 public static Put makePutFromRegionInfo(RegionInfo regionInfo) throws IOException { -1318 return makePutFromRegionInfo(regionInfo, EnvironmentEdgeManager.currentTime()); -1319 } -1320 -1321 /** -1322 * Generates and returns a Put containing the region into for the catalog table -1323 */ -1324 public static Put makePutFromRegionInfo(RegionInfo regionInfo, long ts) throws IOException { -1325 Put put = new Put(regionInfo.getRegionName(), ts); -1326 addRegionInfo(put, regionInfo); -1327 return put; -1328 } -1329 -1330 /** -1331 * Generates and returns a Delete containing the region info for the catalog -1332 * table -1333 */ -1334 public static Delete makeDeleteFromRegionInfo(RegionInfo regionInfo) { -1335 long now = EnvironmentEdgeManager.currentTime(); -1336 return makeDeleteFromRegionInfo(regionInfo, now); -1337 } -1338 -1339 /** -1340 * Generates and returns a Delete containing the region info for the catalog -1341 * table -1342 */ -1343 public static Delete makeDeleteFromRegionInfo(RegionInfo regionInfo, long ts) { -1344 if (regionInfo == null) { -1345 throw new IllegalArgumentException("Can't make a delete for null region"); -1346 } -1347 Delete delete = new Delete(regionInfo.getRegionName()); -1348 delete.addFamily(getCatalogFamily(), ts); -1349 return delete; -1350 } -1351 -1352 public static Put makeBarrierPut(byte[] encodedRegionName, long seq, byte[] tableName) -1353 throws IOException { -1354 byte[] seqBytes = Bytes.toBytes(seq); -1355 Put put = new Put(encodedRegionName); -1356 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1357 .setRow(put.getRow()) -1358 .setFamily(HConstants.REPLICATION_BARRIER_FAMILY) -1359 .setQualifier(seqBytes) -1360 .setTimestamp(put.getTimeStamp()) -1361 .setType(Type.Put) -1362 .setValue(seqBytes) -1363 .build()) -1364 .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1365 .setRow(put.getRow()) -1366 .setFamily(HConstants.REPLICATION_META_FAMILY) -1367 .setQualifier(tableNameCq) -1368 .setTimestamp(put.getTimeStamp()) -1369 .setType(Cell.Type.Put) -1370 .setValue(tableName) -1371 .build()); -1372 return put; -1373 } -1374 -1375 -1376 public static Put makeDaughterPut(byte[] encodedRegionName, byte[] value) throws IOException { -1377 Put put = new Put(encodedRegionName); -1378 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1379 .setRow(put.getRow()) -1380 .setFamily(HConstants.REPLICATION_META_FAMILY) -1381 .setQualifier(daughterNameCq) -1382 .setTimestamp(put.getTimeStamp()) -1383 .setType(Type.Put) -1384 .setValue(value) -1385 .build()); -1386 return put; -1387 } -1388 -1389 public static Put makeParentPut(byte[] encodedRegionName, byte[] value) throws IOException { -1390 Put put = new Put(encodedRegionName); -1391 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1392 .setRow(put.getRow()) -1393 .setFamily(HConstants.REPLICATION_META_FAMILY) -1394 .setQualifier(parentNameCq) -1395 .setTimestamp(put.getTimeStamp()) -1396 .setType(Type.Put) -1397 .setValue(value) -1398 .build()); -1399 return put; -1400 } -1401 -1402 /** -1403 * Adds split daughters to the Put -1404 */ -1405 public static Put addDaughtersToPut(Put put, RegionInfo splitA, RegionInfo splitB) -1406 throws IOException { -1407 if (splitA != null) { -1408 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1409 .setRow(put.getRow()) -1410 .setFamily(HConstants.CATALOG_FAMILY) -1411 .setQualifier(HConstants.SPLITA_QUALIFIER) -1412 .setTimestamp(put.getTimeStamp()) -1413 .setType(Type.Put) -1414 .setValue(RegionInfo.toByteArray(splitA)) -1415 .build()); -1416 } -1417 if (splitB != null) { -1418 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1419 .setRow(put.getRow()) -1420 .setFamily(HConstants.CATALOG_FAMILY) -1421 .setQualifier(HConstants.SPLITB_QUALIFIER) -1422 .setTimestamp(put.getTimeStamp()) -1423 .setType(Type.Put) -1424 .setValue(RegionInfo.toByteArray(splitB)) -1425 .build()); -1426 } -1427 return put; -1428 } -1429 -1430 /** -1431 * Put the passed <code>puts</code> to the <code>hbase:meta</code> table. -1432 * Non-atomic for multi puts. -1433 * @param connection connection we're using -1434 * @param puts Put to add to hbase:meta -1435 * @throws IOException -1436 */ -1437 public static void putToMetaTable(final Connection connection, final Put... puts) -1438 throws IOException { -1439 put(getMetaHTable(connection), Arrays.asList(puts)); -1440 } -1441 -1442 /** -1443 * @param t Table to use (will be closed when done). -1444 * @param puts puts to make -1445 * @throws IOException -1446 */ -1447 private static void put(final Table t, final List<Put> puts) throws IOException { -1448 try { -1449 debugLogMutations(puts); -1450 t.put(puts); -1451 } finally { -1452 t.close(); -1453 } -1454 } -1455 -1456 /** -1457 * Put the passed <code>ps</code> to the <code>hbase:meta</code> table. -1458 * @param connection connection we're using -1459 * @param ps Put to add to hbase:meta -1460 * @throws IOException -1461 */ -1462 public static void putsToMetaTable(final Connection connection, final List<Put> ps) -1463 throws IOException { -1464 Table t = getMetaHTable(connection); -1465 try { -1466 debugLogMutations(ps); -1467 t.put(ps); -1468 } finally { -1469 t.close(); -1470 } -1471 } -1472 -1473 /** -1474 * Delete the passed <code>d</code> from the <code>hbase:meta</code> table. -1475 * @param connection connection we're using -1476 * @param d Delete to add to hbase:meta -1477 * @throws IOException -1478 */ -1479 static void deleteFromMetaTable(final Connection connection, final Delete d) -1480 throws IOException { -1481 List<Delete> dels = new ArrayList<>(1); -1482 dels.add(d); -1483 deleteFromMetaTable(connection, dels); -1484 } -1485 -1486 /** -1487 * Delete the passed <code>deletes</code> from the <code>hbase:meta</code> table. -1488 * @param connection connection we're using -1489 * @param deletes Deletes to add to hbase:meta This list should support #remove. -1490 * @throws IOException -1491 */ -1492 public static void deleteFromMetaTable(final Connection connection, final List<Delete> deletes) -1493 throws IOException { -1494 Table t = getMetaHTable(connection); -1495 try { -1496 debugLogMutations(deletes); -1497 t.delete(deletes); -1498 } finally { -1499 t.close(); -1500 } -1501 } -1502 -1503 /** -1504 * Deletes some replica columns corresponding to replicas for the passed rows -1505 * @param metaRows rows in hbase:meta -1506 * @param replicaIndexToDeleteFrom the replica ID we would start deleting from -1507 * @param numReplicasToRemove how many replicas to remove -1508 * @param connection connection we're using to access meta table -1509 * @throws IOException -1510 */ -1511 public static void removeRegionReplicasFromMeta(Set<byte[]> metaRows, -1512 int replicaIndexToDeleteFrom, int numReplicasToRemove, Connection connection) -1513 throws IOException { -1514 int absoluteIndex = replicaIndexToDeleteFrom + numReplicasToRemove; -1515 for (byte[] row : metaRows) { -1516 long now = EnvironmentEdgeManager.currentTime(); -1517 Delete deleteReplicaLocations = new Delete(row); -1518 for (int i = replicaIndexToDeleteFrom; i < absoluteIndex; i++) { -1519 deleteReplicaLocations.addColumns(getCatalogFamily(), -1520 getServerColumn(i), now); -1521 deleteReplicaLocations.addColumns(getCatalogFamily(), -1522 getSeqNumColumn(i), now); -1523 deleteReplicaLocations.addColumns(getCatalogFamily(), -1524 getStartCodeColumn(i), now); -1525 } -1526 deleteFromMetaTable(connection, deleteReplicaLocations); -1527 } -1528 } -1529 -1530 /** -1531 * Execute the passed <code>mutations</code> against <code>hbase:meta</code> table. -1532 * @param connection connection we're using -1533 * @param mutations Puts and Deletes to execute on hbase:meta -1534 * @throws IOException -1535 */ -1536 public static void mutateMetaTable(final Connection connection, -1537 final List<Mutation> mutations) -1538 throws IOException { -1539 Table t = getMetaHTable(connection); -1540 try { -1541 debugLogMutations(mutations); -1542 t.batch(mutations, null); -1543 } catch (InterruptedException e) { -1544 InterruptedIOException ie = new InterruptedIOException(e.getMessage()); -1545 ie.initCause(e); -1546 throw ie; -1547 } finally { -1548 t.close(); -1549 } -1550 } -1551 -1552 static void addRegionStateToPut(Put put, RegionState.State state) throws IOException { -1553 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1554 .setRow(put.getRow()) -1555 .setFamily(HConstants.CATALOG_FAMILY) -1556 .setQualifier(getRegionStateColumn()) -1557 .setTimestamp(put.getTimeStamp()) -1558 .setType(Cell.Type.Put) -1559 .setValue(Bytes.toBytes(state.name())) -1560 .build()); -1561 } -1562 -1563 /** -1564 * Adds daughter region infos to hbase:meta row for the specified region. Note that this does not -1565 * add its daughter's as different rows, but adds information about the daughters in the same row -1566 * as the parent. Use -1567 * {@link #splitRegion(Connection, RegionInfo, RegionInfo, RegionInfo, ServerName,int,boolean)} -1568 * if you want to do that. -1569 * @param connection connection we're using -1570 * @param regionInfo RegionInfo of parent region -1571 * @param splitA first split daughter of the parent regionInfo -1572 * @param splitB second split daughter of the parent regionInfo -1573 * @throws IOException if problem connecting or updating meta -1574 */ -1575 public static void addSpiltsToParent(Connection connection, RegionInfo regionInfo, -1576 RegionInfo splitA, RegionInfo splitB) throws IOException { -1577 Table meta = getMetaHTable(connection); -1578 try { -1579 Put put = makePutFromRegionInfo(regionInfo); -1580 addDaughtersToPut(put, splitA, splitB); -1581 meta.put(put); -1582 debugLogMutation(put); -1583 LOG.debug("Added region {}", regionInfo.getRegionNameAsString()); -1584 } finally { -1585 meta.close(); -1586 } -1587 } -1588 -1589 /** -1590 * Adds a hbase:meta row for the specified new region. Initial state of new region is CLOSED. -1591 * @param connection connection we're using -1592 * @param regionInfo region information -1593 * @throws IOException if problem connecting or updating meta -1594 */ -1595 @VisibleForTesting -1596 public static void addRegionToMeta(Connection connection, RegionInfo regionInfo) -1597 throws IOException { -1598 addRegionsToMeta(connection, Collections.singletonList(regionInfo), 1); -1599 } -1600 -1601 /** -1602 * Adds a hbase:meta row for each of the specified new regions. Initial state for new regions -1603 * is CLOSED. -1604 * @param connection connection we're using -1605 * @param regionInfos region information list -1606 * @throws IOException if problem connecting or updating meta -1607 */ -1608 public static void addRegionsToMeta(Connection connection, List<RegionInfo> regionInfos, -1609 int regionReplication) throws IOException { -1610 addRegionsToMeta(connection, regionInfos, regionReplication, HConstants.LATEST_TIMESTAMP); -1611 } -1612 /** -1613 * Adds a hbase:meta row for each of the specified new regions. Initial state for new regions -1614 * is CLOSED. -1615 * @param connection connection we're using -1616 * @param regionInfos region information list -1617 * @param regionReplication -1618 * @param ts desired timestamp -1619 * @throws IOException if problem connecting or updating meta -1620 */ -1621 public static void addRegionsToMeta(Connection connection, List<RegionInfo> regionInfos, -1622 int regionReplication, long ts) throws IOException { -1623 List<Put> puts = new ArrayList<>(); -1624 for (RegionInfo regionInfo : regionInfos) { -1625 if (RegionReplicaUtil.isDefaultReplica(regionInfo)) { -1626 Put put = makePutFromRegionInfo(regionInfo, ts); -1627 // New regions are added with initial state of CLOSED. -1628 addRegionStateToPut(put, RegionState.State.CLOSED); -1629 // Add empty locations for region replicas so that number of replicas can be cached -1630 // whenever the primary region is looked up from meta -1631 for (int i = 1; i < regionReplication; i++) { -1632 addEmptyLocation(put, i); -1633 } -1634 puts.add(put); -1635 } -1636 } -1637 putsToMetaTable(connection, puts); -1638 LOG.info("Added {} regions to meta.", puts.size()); -1639 } -1640 -1641 /** -1642 * Merge the two regions into one in an atomic operation. Deletes the two -1643 * merging regions in hbase:meta and adds the merged region with the information of -1644 * two merging regions. -1645 * @param connection connection we're using -1646 * @param mergedRegion the merged region -1647 * @param regionA -1648 * @param regionB -1649 * @param sn the location of the region -1650 * @param masterSystemTime -1651 * @param saveBarrier true if need save replication barrier in meta, used for serial replication -1652 * @throws IOException -1653 */ -1654 public static void mergeRegions(final Connection connection, RegionInfo mergedRegion, -1655 RegionInfo regionA, RegionInfo regionB, ServerName sn, int regionReplication, -1656 long masterSystemTime, boolean saveBarrier) -1657 throws IOException { -1658 Table meta = getMetaHTable(connection); -1659 try { -1660 // use the maximum of what master passed us vs local time. -1661 long time = Math.max(EnvironmentEdgeManager.currentTime(), masterSystemTime); -1662 -1663 // Put for parent -1664 Put putOfMerged = makePutFromRegionInfo(mergedRegion, time); -1665 putOfMerged.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1666 .setRow(putOfMerged.getRow()) -1667 .setFamily(HConstants.CATALOG_FAMILY) -1668 .setQualifier(HConstants.MERGEA_QUALIFIER) -1669 .setTimestamp(putOfMerged.getTimeStamp()) -1670 .setType(Type.Put) -1671 .setValue(RegionInfo.toByteArray(regionA)) -1672 .build()) -1673 .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) -1674 .setRow(putOfMerged.getRow()) -1675 .setFamily(HConstants.CATALOG_FAMILY) -1676 .setQualifier(HConstants.MERGEB_QUALIFIER) -1677 .setTimestamp(putOfMerged.getTimeStamp()) -1678 .setType(Type.Put) -1679 .setValue(RegionInfo.toByteArray(regionB)) -1680 .build()); -1681 -1682 // Set initial state to CLOSED -1683 // NOTE: If initial state is not set to CLOSED then merged region gets added with the -1684 // default OFFLINE state. If Master gets restarted after this step, start up sequence of -1685 // master tries to assign this offline region. This is followed by re-assignments of the -1686 // merged region from resumed {@link MergeTableRegionsProcedure} -1687 addRegionStateToPut(putOfMerged, RegionState.State.CLOSED); -1688 -1689 // Deletes for merging regions -1690 Delete deleteA = makeDeleteFromRegionInfo(regionA, time); -1691 Delete deleteB = makeDeleteFromRegionInfo(regionB, time); -1692 -1693 // The merged is a new region, openSeqNum = 1 is fine. ServerName may be null -1694 // if crash after merge happened but before we got to here.. means in-memory -1695 // locations of offlined merged, now-closed, regions is lost. Should be ok. We -1696 // assign the merged region later. -1697 if (sn != null) addLocation(putOfMerged, sn, 1, -1, mergedRegion.getReplicaId()); -1698 -1699 // Add empty locations for region replicas of the merged region so that number of replicas can -1700 // be cached whenever the primary region is looked up from meta -1701 for (int i = 1; i < regionReplication; i++) { -1702 addEmptyLocation(putOfMerged, i); -1703 } -1704 -1705 byte[] tableRow = Bytes.toBytes(mergedRegion.getRegionNameAsString() -1706 + HConstants.DELIMITER); -1707 Mutation[] mutations; -1708 if (saveBarrier) { -1709 Put putBarrierA = makeDaughterPut(regionA.getEncodedNameAsBytes(), -1710 mergedRegion.getEncodedNameAsBytes()); -1711 Put putBarrierB = makeDaughterPut(regionB.getEncodedNameAsBytes(), -1712 mergedRegion.getEncodedNameAsBytes()); -1713 Put putDaughter = makeParentPut(mergedRegion.getEncodedNameAsBytes(), Bytes.toBytes( -1714 regionA.getEncodedName() + "," + regionB.getEncodedName())); -1715 mutations = new Mutation[] { putOfMerged, deleteA, deleteB, -1716 putBarrierA, putBarrierB, putDaughter}; -1717 } else { -1718 mutations = new Mutation[] { putOfMerged, deleteA, deleteB }; -1719 } -1720 multiMutate(connection, meta, tableRow, mutations); -1721 } finally { -1722 meta.close(); -1723 } -1724 } -1725 -1726 /** -1727 * Splits the region into two in an atomic operation. Offlines the parent -1728 * region with the information that it is split into two, and also adds -1729 * the daughter regions. Does not add the location information to the daughter -1730 * regions since they are not open yet. -1731 * @param connection connection we're using -1732 * @param parent the parent region which is split -1733 * @param splitA Split daughter region A -1734 * @param splitB Split daughter region A -1735 * @param sn the location of the region -1736 * @param saveBarrier true if need save replication barrier in meta, used for serial replication -1737 */ -1738 public static void splitRegion(final Connection connection, RegionInfo parent, -1739 RegionInfo splitA, RegionInfo splitB, ServerName sn, int regionReplication, -1740 boolean saveBarrier) throws IOException { -1741 Table meta = getMetaHTable(connection); -1742 try { -1743 //Put for parent -1744 Put putParent = makePutFromRegionInfo(RegionInfoBuilder.newBuilder(parent) -1745 .setOffline(true) -1746 .setSplit(true).build()); -1747 addDaughtersToPut(putParent, splitA, splitB); -1748 -1749 //Puts for daughters -1750 Put putA = makePutFromRegionInfo(splitA); -1751 Put putB = makePutFromRegionInfo(splitB); -1752 -1753 // Set initial state to CLOSED -1754 // NOTE: If initial state is not set to CLOSED then daughter regions get added with the -1755 // default OFFLINE state. If Master gets restarted after this step, start up sequence of -1756 // master tries to assign these offline regions. This is followed by re-assignments of the -1757 // daughter regions from resumed {@link SplitTableRegionProcedure} -1758 addRegionStateToPut(putA, RegionState.State.CLOSED); -1759 addRegionStateToPut(putA, RegionState.State.CLOSED); -1760 -1761 addSequenceNum(putA, 1, -1, splitA.getReplicaId()); //new regions, openSeqNum = 1 is fine. -1762 addSequenceNum(putB, 1, -1, splitB.getReplicaId()); +1277 if (!(info.getTable().equals(tableName))) { +1278 return false; +1279 } +1280 return super.visit(rowResult); +1281 } +1282 } +1283 +1284 /** +1285 * Count regions in <code>hbase:meta</code> for passed table. +1286 * @param c Configuration object +1287 * @param tableName table name to count regions for +1288 * @return Count or regions in table <code>tableName</code> +1289 * @throws IOException +1290 */ +1291 public static int getRegionCount(final Configuration c, final TableName tableName) +1292 throws IOException { +1293 try (Connection connection = ConnectionFactory.createConnection(c)) { +1294 return getRegionCount(connection, tableName); +1295 } +1296 } +1297 +1298 /** +1299 * Count regions in <code>hbase:meta</code> for passed table. +1300 * @param connection Connection object +1301 * @param tableName table name to count regions for +1302 * @return Count or regions in table <code>tableName</code> +1303 * @throws IOException +1304 */ +1305 public static int getRegionCount(final Connection connection, final TableName tableName) +1306 throws IOException { +1307 try (RegionLocator locator = connection.getRegionLocator(tableName)) { +1308 List<HRegionLocation> locations = locator.getAllRegionLocations(); +1309 return locations == null? 0: locations.size(); +1310 } +1311 } +1312 +1313 //////////////////////// +1314 // Editing operations // +1315 //////////////////////// +1316 +1317 /** +1318 * Generates and returns a Put containing the region into for the catalog table +1319 */ +1320 public static Put makePutFromRegionInfo(RegionInfo regionInfo) throws IOException { +1321 return makePutFromRegionInfo(regionInfo, EnvironmentEdgeManager.currentTime()); +1322 } +1323 +1324 /** +1325 * Generates and returns a Put containing the region into for the catalog table +1326 */ +1327 public static Put makePutFromRegionInfo(RegionInfo regionInfo, long ts) throws IOException { +1328 Put put = new Put(regionInfo.getRegionName(), ts); +1329 addRegionInfo(put, regionInfo); +1330 return put; +1331 } +1332 +1333 /** +1334 * Generates and returns a Delete containing the region info for the catalog +1335 * table +1336 */ +1337 public static Delete makeDeleteFromRegionInfo(RegionInfo regionInfo) { +1338 long now = EnvironmentEdgeManager.currentTime(); +1339 return makeDeleteFromRegionInfo(regionInfo, now); +1340 } +1341 +1342 /** +1343 * Generates and returns a Delete containing the region info for the catalog +1344 * table +1345 */ +1346 public static Delete makeDeleteFromRegionInfo(RegionInfo regionInfo, long ts) { +1347 if (regionInfo == null) { +1348 throw new IllegalArgumentException("Can't make a delete for null region"); +1349 } +1350 Delete delete = new Delete(regionInfo.getRegionName()); +1351 delete.addFamily(getCatalogFamily(), ts); +1352 return delete; +1353 } +1354 +1355 public static Put makeBarrierPut(byte[] encodedRegionName, long seq, byte[] tableName) +1356 throws IOException { +1357 byte[] seqBytes = Bytes.toBytes(seq); +1358 Put put = new Put(encodedRegionName); +1359 put.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) +1360 .setRow(put.getRow()) +