1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22 import java.io.Closeable;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.NavigableMap;
27 import java.util.TreeMap;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.hbase.classification.InterfaceAudience;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.ServerName;
37 import org.apache.hadoop.hbase.TableNotFoundException;
38 import org.apache.hadoop.hbase.util.Bytes;
39
40
41
42
43
44
45
46
47
48
49
50
51 @InterfaceAudience.Private
52 public class MetaScanner {
53 private static final Log LOG = LogFactory.getLog(MetaScanner.class);
54
55
56
57
58
59
60
61
62 public static void metaScan(Configuration configuration,
63 MetaScannerVisitor visitor)
64 throws IOException {
65 metaScan(configuration, visitor, null, null, Integer.MAX_VALUE);
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79 public static void metaScan(Configuration configuration, HConnection connection,
80 MetaScannerVisitor visitor, TableName userTableName)
81 throws IOException {
82 metaScan(configuration, connection, visitor, userTableName, null, Integer.MAX_VALUE,
83 TableName.META_TABLE_NAME);
84 }
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 public static void metaScan(Configuration configuration,
102 MetaScannerVisitor visitor, TableName userTableName, byte[] row,
103 int rowLimit)
104 throws IOException {
105 metaScan(configuration, null, visitor, userTableName, row, rowLimit,
106 TableName.META_TABLE_NAME);
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 public static void metaScan(Configuration configuration, HConnection connection,
127 final MetaScannerVisitor visitor, final TableName tableName,
128 final byte[] row, final int rowLimit, final TableName metaTableName)
129 throws IOException {
130 int rowUpperLimit = rowLimit > 0 ? rowLimit: Integer.MAX_VALUE;
131 HTable metaTable;
132 if (connection == null) {
133 metaTable = new HTable(configuration, TableName.META_TABLE_NAME, null);
134 } else {
135 metaTable = new HTable(TableName.META_TABLE_NAME, connection, null);
136 }
137
138 byte[] startRow;
139 ResultScanner scanner = null;
140 try {
141 if (row != null) {
142
143 byte[] searchRow = HRegionInfo.createRegionName(tableName, row, HConstants.NINES, false);
144 Result startRowResult = metaTable.getRowOrBefore(searchRow, HConstants.CATALOG_FAMILY);
145 if (startRowResult == null) {
146 throw new TableNotFoundException("Cannot find row in "+ TableName
147 .META_TABLE_NAME.getNameAsString()+" for table: "
148 + tableName + ", row=" + Bytes.toStringBinary(searchRow));
149 }
150 HRegionInfo regionInfo = getHRegionInfo(startRowResult);
151 if (regionInfo == null) {
152 throw new IOException("HRegionInfo was null or empty in Meta for " +
153 tableName + ", row=" + Bytes.toStringBinary(searchRow));
154 }
155 byte[] rowBefore = regionInfo.getStartKey();
156 startRow = HRegionInfo.createRegionName(tableName, rowBefore, HConstants.ZEROES, false);
157 } else if (tableName == null || tableName.getName().length == 0) {
158
159 startRow = HConstants.EMPTY_START_ROW;
160 } else {
161
162 startRow = HRegionInfo.createRegionName(tableName, HConstants.EMPTY_START_ROW,
163 HConstants.ZEROES, false);
164 }
165 final Scan scan = new Scan(startRow).addFamily(HConstants.CATALOG_FAMILY);
166 int scannerCaching = configuration.getInt(HConstants.HBASE_META_SCANNER_CACHING,
167 HConstants.DEFAULT_HBASE_META_SCANNER_CACHING);
168 if (rowUpperLimit <= scannerCaching) {
169 scan.setSmall(true);
170 }
171 int rows = Math.min(rowLimit, scannerCaching);
172 scan.setCaching(rows);
173 if (LOG.isTraceEnabled()) {
174 LOG.trace("Scanning " + metaTableName.getNameAsString() + " starting at row=" +
175 Bytes.toStringBinary(startRow) + " for max=" + rowUpperLimit + " with caching=" + rows);
176 }
177
178 scanner = metaTable.getScanner(scan);
179 Result result = null;
180 int processedRows = 0;
181 while ((result = scanner.next()) != null) {
182 if (visitor != null) {
183 if (!visitor.processRow(result)) break;
184 }
185 processedRows++;
186 if (processedRows >= rowUpperLimit) break;
187 }
188 } finally {
189 if (scanner != null) {
190 try {
191 scanner.close();
192 } catch (Throwable t) {
193 LOG.debug("Got exception in closing the result scanner", t);
194 }
195 }
196 if (visitor != null) {
197 try {
198 visitor.close();
199 } catch (Throwable t) {
200 LOG.debug("Got exception in closing the meta scanner visitor", t);
201 }
202 }
203 if (metaTable != null) {
204 try {
205 metaTable.close();
206 } catch (Throwable t) {
207 LOG.debug("Got exception in closing the meta table", t);
208 }
209 }
210 }
211 }
212
213
214
215
216
217
218
219
220 public static HRegionInfo getHRegionInfo(Result data) {
221 return HRegionInfo.getHRegionInfo(data);
222 }
223
224
225
226
227
228
229
230
231
232
233
234 public static List<HRegionInfo> listAllRegions(Configuration conf, final boolean offlined)
235 throws IOException {
236 final List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
237 MetaScannerVisitor visitor = new DefaultMetaScannerVisitor() {
238 @Override
239 public boolean processRowInternal(Result result) throws IOException {
240 if (result == null || result.isEmpty()) {
241 return true;
242 }
243
244 HRegionInfo regionInfo = getHRegionInfo(result);
245 if (regionInfo == null) {
246 LOG.warn("Null REGIONINFO_QUALIFIER: " + result);
247 return true;
248 }
249
250
251 if (regionInfo.isOffline() && !offlined) return true;
252 regions.add(regionInfo);
253 return true;
254 }
255 };
256 metaScan(conf, visitor);
257 return regions;
258 }
259
260
261
262
263
264
265
266
267
268 public static NavigableMap<HRegionInfo, ServerName> allTableRegions(Configuration conf,
269 HConnection connection, final TableName tableName,
270 final boolean offlined) throws IOException {
271 final NavigableMap<HRegionInfo, ServerName> regions =
272 new TreeMap<HRegionInfo, ServerName>();
273 MetaScannerVisitor visitor = new TableMetaScannerVisitor(tableName) {
274 @Override
275 public boolean processRowInternal(Result rowResult) throws IOException {
276 HRegionInfo info = getHRegionInfo(rowResult);
277 ServerName serverName = HRegionInfo.getServerName(rowResult);
278 regions.put(new UnmodifyableHRegionInfo(info), serverName);
279 return true;
280 }
281 };
282 metaScan(conf, connection, visitor, tableName);
283 return regions;
284 }
285
286
287
288
289 public interface MetaScannerVisitor extends Closeable {
290
291
292
293
294
295
296
297
298
299 boolean processRow(Result rowResult) throws IOException;
300 }
301
302 public static abstract class MetaScannerVisitorBase implements MetaScannerVisitor {
303 @Override
304 public void close() throws IOException {
305 }
306 }
307
308
309
310
311 public static abstract class DefaultMetaScannerVisitor
312 extends MetaScannerVisitorBase {
313
314 public DefaultMetaScannerVisitor() {
315 super();
316 }
317
318 public abstract boolean processRowInternal(Result rowResult) throws IOException;
319
320 @Override
321 public boolean processRow(Result rowResult) throws IOException {
322 HRegionInfo info = getHRegionInfo(rowResult);
323 if (info == null) {
324 return true;
325 }
326
327
328 if (!(info.isOffline() || info.isSplit())) {
329 return processRowInternal(rowResult);
330 }
331 return true;
332 }
333 }
334
335
336
337
338
339
340
341 public static abstract class TableMetaScannerVisitor extends DefaultMetaScannerVisitor {
342 private TableName tableName;
343
344 public TableMetaScannerVisitor(TableName tableName) {
345 super();
346 this.tableName = tableName;
347 }
348
349 @Override
350 public final boolean processRow(Result rowResult) throws IOException {
351 HRegionInfo info = getHRegionInfo(rowResult);
352 if (info == null) {
353 return true;
354 }
355 if (!(info.getTable().equals(tableName))) {
356 return false;
357 }
358 return super.processRow(rowResult);
359 }
360 }
361 }