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 java.io.IOException;
23 import java.util.Map;
24 import java.util.concurrent.locks.Lock;
25 import java.util.concurrent.locks.ReentrantLock;
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.fs.FileStatus;
31 import org.apache.hadoop.fs.FileSystem;
32 import org.apache.hadoop.fs.Path;
33 import org.apache.hadoop.hbase.HColumnDescriptor;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.HServerInfo;
37 import org.apache.hadoop.hbase.RemoteExceptionHandler;
38 import org.apache.hadoop.hbase.Server;
39 import org.apache.hadoop.hbase.master.metrics.MasterMetrics;
40 import org.apache.hadoop.hbase.regionserver.HRegion;
41 import org.apache.hadoop.hbase.regionserver.Store;
42 import org.apache.hadoop.hbase.regionserver.wal.HLog;
43 import org.apache.hadoop.hbase.regionserver.wal.HLogSplitter;
44 import org.apache.hadoop.hbase.regionserver.wal.OrphanHLogAfterSplitException;
45 import org.apache.hadoop.hbase.util.Bytes;
46 import org.apache.hadoop.hbase.util.FSUtils;
47
48
49
50
51
52
53 public class MasterFileSystem {
54 private static final Log LOG = LogFactory.getLog(MasterFileSystem.class.getName());
55
56 Configuration conf;
57
58 Server master;
59
60 MasterMetrics metrics;
61
62 private final FileSystem fs;
63
64 private volatile boolean fsOk = true;
65
66 private final Path oldLogDir;
67
68 private final Path rootdir;
69
70 final Lock splitLogLock = new ReentrantLock();
71
72 public MasterFileSystem(Server master, MasterMetrics metrics)
73 throws IOException {
74 this.conf = master.getConfiguration();
75 this.master = master;
76 this.metrics = metrics;
77
78
79
80
81 this.rootdir = FSUtils.getRootDir(conf);
82
83
84 conf.set("fs.default.name", this.rootdir.toString());
85 conf.set("fs.defaultFS", this.rootdir.toString());
86
87 this.fs = FileSystem.get(conf);
88
89 this.oldLogDir = new Path(this.rootdir, HConstants.HREGION_OLDLOGDIR_NAME);
90 createInitialFileSystemLayout();
91 }
92
93
94
95
96
97
98
99
100
101
102
103 private void createInitialFileSystemLayout() throws IOException {
104
105 checkRootDir(this.rootdir, conf, this.fs);
106
107
108 if(!this.fs.exists(this.oldLogDir)) {
109 this.fs.mkdirs(this.oldLogDir);
110 }
111 }
112
113 public FileSystem getFileSystem() {
114 return this.fs;
115 }
116
117
118
119
120
121 public Path getOldLogDir() {
122 return this.oldLogDir;
123 }
124
125
126
127
128
129
130 public boolean checkFileSystem() {
131 if (this.fsOk) {
132 try {
133 FSUtils.checkFileSystemAvailable(this.fs);
134 } catch (IOException e) {
135 master.abort("Shutting down HBase cluster: file system not available", e);
136 this.fsOk = false;
137 }
138 }
139 return this.fsOk;
140 }
141
142
143
144
145
146 public Path getRootDir() {
147 return this.rootdir;
148 }
149
150
151
152
153
154
155
156 void splitLogAfterStartup(final Map<String, HServerInfo> onlineServers) {
157 Path logsDirPath = new Path(this.rootdir, HConstants.HREGION_LOGDIR_NAME);
158 try {
159 if (!this.fs.exists(logsDirPath)) {
160 return;
161 }
162 } catch (IOException e) {
163 throw new RuntimeException("Failed exists test on " + logsDirPath, e);
164 }
165 FileStatus[] logFolders;
166 try {
167 logFolders = this.fs.listStatus(logsDirPath);
168 } catch (IOException e) {
169 throw new RuntimeException("Failed listing " + logsDirPath.toString(), e);
170 }
171 if (logFolders == null || logFolders.length == 0) {
172 LOG.debug("No log files to split, proceeding...");
173 return;
174 }
175 for (FileStatus status : logFolders) {
176 String serverName = status.getPath().getName();
177 if (onlineServers.get(serverName) == null) {
178 LOG.info("Log folder " + status.getPath() + " doesn't belong " +
179 "to a known region server, splitting");
180 splitLog(serverName);
181 } else {
182 LOG.info("Log folder " + status.getPath() +
183 " belongs to an existing region server");
184 }
185 }
186 }
187
188 public void splitLog(final String serverName) {
189 this.splitLogLock.lock();
190 long splitTime = 0, splitLogSize = 0;
191 Path logDir = new Path(this.rootdir, HLog.getHLogDirectoryName(serverName));
192 try {
193 HLogSplitter splitter = HLogSplitter.createLogSplitter(
194 conf, rootdir, logDir, oldLogDir, this.fs);
195 try {
196 splitter.splitLog();
197 } catch (OrphanHLogAfterSplitException e) {
198 LOG.warn("Retrying splitting because of:", e);
199
200 splitter = HLogSplitter.createLogSplitter(conf, rootdir, logDir,
201 oldLogDir, this.fs);
202 splitter.splitLog();
203 }
204 splitTime = splitter.getTime();
205 splitLogSize = splitter.getSize();
206 } catch (IOException e) {
207 LOG.error("Failed splitting " + logDir.toString(), e);
208 } finally {
209 this.splitLogLock.unlock();
210 }
211 if (this.metrics != null) {
212 this.metrics.addSplit(splitTime, splitLogSize);
213 }
214 }
215
216
217
218
219
220
221
222
223
224
225 private static Path checkRootDir(final Path rd, final Configuration c,
226 final FileSystem fs)
227 throws IOException {
228
229 FSUtils.waitOnSafeMode(c, c.getInt(HConstants.THREAD_WAKE_FREQUENCY,
230 10 * 1000));
231
232 if (!fs.exists(rd)) {
233 fs.mkdirs(rd);
234 FSUtils.setVersion(fs, rd);
235 } else {
236 FSUtils.checkVersion(fs, rd, true);
237 }
238
239 if (!FSUtils.rootRegionExists(fs, rd)) {
240 bootstrap(rd, c);
241 }
242 return rd;
243 }
244
245 private static void bootstrap(final Path rd, final Configuration c)
246 throws IOException {
247 LOG.info("BOOTSTRAP: creating ROOT and first META regions");
248 try {
249
250
251
252
253 HRegionInfo rootHRI = new HRegionInfo(HRegionInfo.ROOT_REGIONINFO);
254 setInfoFamilyCaching(rootHRI, false);
255 HRegionInfo metaHRI = new HRegionInfo(HRegionInfo.FIRST_META_REGIONINFO);
256 setInfoFamilyCaching(metaHRI, false);
257 HRegion root = HRegion.createHRegion(rootHRI, rd, c);
258 HRegion meta = HRegion.createHRegion(metaHRI, rd, c);
259 setInfoFamilyCaching(rootHRI, true);
260 setInfoFamilyCaching(metaHRI, true);
261
262 HRegion.addRegionToMETA(root, meta);
263 root.close();
264 root.getLog().closeAndDelete();
265 meta.close();
266 meta.getLog().closeAndDelete();
267 } catch (IOException e) {
268 e = RemoteExceptionHandler.checkIOException(e);
269 LOG.error("bootstrap", e);
270 throw e;
271 }
272 }
273
274
275
276
277
278 private static void setInfoFamilyCaching(final HRegionInfo hri, final boolean b) {
279 for (HColumnDescriptor hcd: hri.getTableDesc().families.values()) {
280 if (Bytes.equals(hcd.getName(), HConstants.CATALOG_FAMILY)) {
281 hcd.setBlockCacheEnabled(b);
282 hcd.setInMemory(b);
283 }
284 }
285 }
286
287 public void deleteRegion(HRegionInfo region) throws IOException {
288 fs.delete(HRegion.getRegionDir(rootdir, region), true);
289 }
290
291 public void deleteTable(byte[] tableName) throws IOException {
292 fs.delete(new Path(rootdir, Bytes.toString(tableName)), true);
293 }
294
295 public void updateRegionInfo(HRegionInfo region) {
296
297
298
299 }
300
301 public void deleteFamily(HRegionInfo region, byte[] familyName)
302 throws IOException {
303 fs.delete(Store.getStoreHomedir(
304 new Path(rootdir, region.getTableDesc().getNameAsString()),
305 region.getEncodedName(), familyName), true);
306 }
307 }