1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.client;
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.HConstants;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.TableNotFoundException;
33 import org.apache.hadoop.hbase.util.Bytes;
34 import org.apache.hadoop.hbase.util.Writables;
35
36
37
38
39
40
41
42
43
44 public class MetaScanner {
45 private static final Log LOG = LogFactory.getLog(MetaScanner.class);
46
47
48
49
50
51
52
53
54 public static void metaScan(Configuration configuration,
55 MetaScannerVisitor visitor)
56 throws IOException {
57 metaScan(configuration, visitor, null);
58 }
59
60
61
62
63
64
65
66
67
68
69
70 public static void metaScan(Configuration configuration,
71 MetaScannerVisitor visitor, byte [] userTableName)
72 throws IOException {
73 metaScan(configuration, visitor, userTableName, null, Integer.MAX_VALUE);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91 public static void metaScan(Configuration configuration,
92 MetaScannerVisitor visitor, byte [] userTableName, byte[] row,
93 int rowLimit)
94 throws IOException {
95 metaScan(configuration, visitor, userTableName, row, rowLimit,
96 HConstants.META_TABLE_NAME);
97 }
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public static void metaScan(Configuration configuration,
116 MetaScannerVisitor visitor, byte [] tableName, byte[] row,
117 int rowLimit, final byte [] metaTableName)
118 throws IOException {
119 int rowUpperLimit = rowLimit > 0 ? rowLimit: Integer.MAX_VALUE;
120
121 HConnection connection = HConnectionManager.getConnection(configuration);
122
123
124 byte[] startRow;
125 if (row != null) {
126
127 assert tableName != null;
128 byte[] searchRow =
129 HRegionInfo.createRegionName(tableName, row, HConstants.NINES,
130 false);
131
132 HTable metaTable = new HTable(configuration, HConstants.META_TABLE_NAME);
133 Result startRowResult = metaTable.getRowOrBefore(searchRow,
134 HConstants.CATALOG_FAMILY);
135 if (startRowResult == null) {
136 throw new TableNotFoundException("Cannot find row in .META. for table: "
137 + Bytes.toString(tableName) + ", row=" + Bytes.toStringBinary(searchRow));
138 }
139 byte[] value = startRowResult.getValue(HConstants.CATALOG_FAMILY,
140 HConstants.REGIONINFO_QUALIFIER);
141 if (value == null || value.length == 0) {
142 throw new IOException("HRegionInfo was null or empty in Meta for " +
143 Bytes.toString(tableName) + ", row=" + Bytes.toStringBinary(searchRow));
144 }
145 HRegionInfo regionInfo = Writables.getHRegionInfo(value);
146
147 byte[] rowBefore = regionInfo.getStartKey();
148 startRow = HRegionInfo.createRegionName(tableName, rowBefore,
149 HConstants.ZEROES, false);
150 } else if (tableName == null || tableName.length == 0) {
151
152 startRow = HConstants.EMPTY_START_ROW;
153 } else {
154
155 startRow = HRegionInfo.createRegionName(
156 tableName, HConstants.EMPTY_START_ROW, HConstants.ZEROES, false);
157 }
158
159
160 ScannerCallable callable;
161 int rows = Math.min(rowLimit,
162 configuration.getInt("hbase.meta.scanner.caching", 100));
163 do {
164 final Scan scan = new Scan(startRow).addFamily(HConstants.CATALOG_FAMILY);
165 if (LOG.isDebugEnabled()) {
166 LOG.debug("Scanning " + Bytes.toString(metaTableName) +
167 " starting at row=" + Bytes.toStringBinary(startRow) + " for max=" +
168 rowUpperLimit + " rows");
169 }
170 callable = new ScannerCallable(connection, metaTableName, scan);
171
172 connection.getRegionServerWithRetries(callable);
173
174 int processedRows = 0;
175 try {
176 callable.setCaching(rows);
177 done: do {
178 if (processedRows >= rowUpperLimit) {
179 break;
180 }
181
182 Result [] rrs = connection.getRegionServerWithRetries(callable);
183 if (rrs == null || rrs.length == 0 || rrs[0].size() == 0) {
184 break;
185 }
186 for (Result rr : rrs) {
187 if (processedRows >= rowUpperLimit) {
188 break done;
189 }
190 if (!visitor.processRow(rr))
191 break done;
192 processedRows++;
193 }
194
195 } while(true);
196
197 startRow = callable.getHRegionInfo().getEndKey();
198 } finally {
199
200 callable.setClose();
201 connection.getRegionServerWithRetries(callable);
202 }
203 } while (Bytes.compareTo(startRow, HConstants.LAST_ROW) != 0);
204 }
205
206
207
208
209
210
211
212 public static List<HRegionInfo> listAllRegions(Configuration conf)
213 throws IOException {
214 return listAllRegions(conf, true);
215 }
216
217
218
219
220
221
222
223
224
225 public static List<HRegionInfo> listAllRegions(Configuration conf, final boolean offlined)
226 throws IOException {
227 final List<HRegionInfo> regions = new ArrayList<HRegionInfo>();
228 MetaScannerVisitor visitor =
229 new MetaScannerVisitor() {
230 @Override
231 public boolean processRow(Result result) throws IOException {
232 if (result == null || result.isEmpty()) {
233 return true;
234 }
235 byte [] bytes = result.getValue(HConstants.CATALOG_FAMILY,
236 HConstants.REGIONINFO_QUALIFIER);
237 if (bytes == null) {
238 LOG.warn("Null REGIONINFO_QUALIFIER: " + result);
239 return true;
240 }
241 HRegionInfo regionInfo = Writables.getHRegionInfo(bytes);
242
243 if (regionInfo.isOffline() && !offlined) return true;
244 regions.add(regionInfo);
245 return true;
246 }
247 };
248 metaScan(conf, visitor);
249 return regions;
250 }
251
252
253
254
255 public interface MetaScannerVisitor {
256
257
258
259
260
261
262
263
264
265 public boolean processRow(Result rowResult) throws IOException;
266 }
267 }