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