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.master;
21
22 import org.apache.hadoop.hbase.HConstants;
23 import org.apache.hadoop.hbase.HRegionInfo;
24 import org.apache.hadoop.hbase.HServerInfo;
25 import org.apache.hadoop.hbase.MasterNotRunningException;
26 import org.apache.hadoop.hbase.RemoteExceptionHandler;
27 import org.apache.hadoop.hbase.TableNotFoundException;
28 import org.apache.hadoop.hbase.client.Result;
29 import org.apache.hadoop.hbase.client.Scan;
30 import org.apache.hadoop.hbase.ipc.HRegionInterface;
31 import org.apache.hadoop.hbase.util.Bytes;
32
33 import java.io.IOException;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Set;
37 import java.util.TreeSet;
38
39
40
41
42
43
44 abstract class TableOperation {
45 private final Set<MetaRegion> metaRegions;
46 protected final byte [] tableName;
47
48 protected final Set<HRegionInfo> unservedRegions = new TreeSet<HRegionInfo>();
49 protected HMaster master;
50
51 protected TableOperation(final HMaster master, final byte [] tableName)
52 throws IOException {
53 this.master = master;
54 if (!this.master.isMasterRunning()) {
55 throw new MasterNotRunningException();
56 }
57
58
59 this.tableName = tableName;
60
61
62 if (!Bytes.equals(HConstants.META_TABLE_NAME, this.tableName)) {
63
64
65 if (master.getRegionManager().metaScannerThread.waitForMetaRegionsOrClose()) {
66
67 throw new MasterNotRunningException();
68 }
69 }
70 this.metaRegions = master.getRegionManager().getMetaRegionsForTable(tableName);
71 }
72
73 private class ProcessTableOperation extends RetryableMetaOperation<Boolean> {
74 ProcessTableOperation(MetaRegion m, HMaster master) {
75 super(m, master);
76 }
77
78 public Boolean call() throws IOException {
79 boolean tableExists = false;
80
81
82 byte [] tableNameMetaStart =
83 Bytes.toBytes(Bytes.toString(tableName) + ",,");
84 final Scan scan = new Scan(tableNameMetaStart)
85 .addFamily(HConstants.CATALOG_FAMILY);
86 long scannerId = this.server.openScanner(m.getRegionName(), scan);
87 int rows = this.master.getConfiguration().
88 getInt("hbase.meta.scanner.caching", 100);
89 scan.setCaching(rows);
90 List<byte []> emptyRows = new ArrayList<byte []>();
91 try {
92 while (true) {
93 Result values = this.server.next(scannerId);
94 if (values == null || values.isEmpty()) {
95 break;
96 }
97 HRegionInfo info = this.master.getHRegionInfo(values.getRow(), values);
98 if (info == null) {
99 emptyRows.add(values.getRow());
100 LOG.error(Bytes.toString(HConstants.CATALOG_FAMILY) + ":"
101 + Bytes.toString(HConstants.REGIONINFO_QUALIFIER)
102 + " not found on "
103 + Bytes.toStringBinary(values.getRow()));
104 continue;
105 }
106 final String serverAddress = BaseScanner.getServerAddress(values);
107 String serverName = null;
108 if (serverAddress != null && serverAddress.length() > 0) {
109 long startCode = BaseScanner.getStartCode(values);
110 serverName = HServerInfo.getServerName(serverAddress, startCode);
111 }
112 if (Bytes.compareTo(info.getTableDesc().getName(), tableName) > 0) {
113 break;
114 }
115
116 tableExists = true;
117 if (!isBeingServed(serverName) || !isEnabled(info)) {
118 unservedRegions.add(info);
119 }
120 processScanItem(serverName, info);
121 }
122 } finally {
123 if (scannerId != -1L) {
124 try {
125 this.server.close(scannerId);
126 } catch (IOException e) {
127 e = RemoteExceptionHandler.checkIOException(e);
128 LOG.error("closing scanner", e);
129 }
130 }
131 scannerId = -1L;
132 }
133
134
135
136 if (emptyRows.size() > 0) {
137 LOG.warn("Found " + emptyRows.size() +
138 " rows with empty HRegionInfo while scanning meta region " +
139 Bytes.toString(m.getRegionName()));
140 master.deleteEmptyMetaRows(server, m.getRegionName(), emptyRows);
141 }
142
143 if (!tableExists) {
144 throw new TableNotFoundException(Bytes.toString(tableName));
145 }
146
147 postProcessMeta(m, server);
148 unservedRegions.clear();
149 return Boolean.TRUE;
150 }
151 }
152
153 void process() throws IOException {
154
155 synchronized(master.getRegionManager().metaScannerThread.scannerLock) {
156 for (MetaRegion m: metaRegions) {
157 new ProcessTableOperation(m, master).doWithRetries();
158 }
159 }
160 }
161
162 protected boolean isBeingServed(String serverName) {
163 boolean result = false;
164 if (serverName != null && serverName.length() > 0) {
165 HServerInfo s = master.getServerManager().getServerInfo(serverName);
166 result = s != null;
167 }
168 return result;
169 }
170
171 protected boolean isEnabled(HRegionInfo info) {
172 return !info.isOffline();
173 }
174
175 protected abstract void processScanItem(String serverName, HRegionInfo info)
176 throws IOException;
177
178 protected abstract void postProcessMeta(MetaRegion m,
179 HRegionInterface server) throws IOException;
180 }