1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.snapshot;
19
20 import java.io.IOException;
21 import java.util.Collections;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.fs.FSDataInputStream;
27 import org.apache.hadoop.fs.FSDataOutputStream;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.fs.permission.FsPermission;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
33 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
34 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV1;
35 import org.apache.hadoop.hbase.snapshot.SnapshotManifestV2;
36 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
37 import org.apache.hadoop.hbase.util.FSUtils;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 public class SnapshotDescriptionUtils {
76
77
78
79
80 public static class CompletedSnaphotDirectoriesFilter extends FSUtils.BlackListDirFilter {
81
82
83
84
85 public CompletedSnaphotDirectoriesFilter(FileSystem fs) {
86 super(fs, Collections.singletonList(SNAPSHOT_TMP_DIR_NAME));
87 }
88 }
89
90 private static final Log LOG = LogFactory.getLog(SnapshotDescriptionUtils.class);
91
92
93
94
95
96 public static final String SNAPSHOT_LAYOUT_CONF_KEY = "hbase.snapshot.format.version";
97 public static final int SNAPSHOT_LAYOUT_LATEST_FORMAT = SnapshotManifestV2.DESCRIPTOR_VERSION;
98
99
100
101
102
103 public static final String SNAPSHOTINFO_FILE = ".snapshotinfo";
104
105
106 public static final String SNAPSHOT_TMP_DIR_NAME = ".tmp";
107
108
109 public static final long NO_SNAPSHOT_START_TIME_SPECIFIED = 0;
110
111
112 public static final String MASTER_SNAPSHOT_TIMEOUT_MILLIS = "hbase.snapshot.master.timeout.millis";
113
114
115 public static final long DEFAULT_MAX_WAIT_TIME = 60000 * 5 ;
116
117
118
119
120
121
122 @Deprecated
123 public static final int SNAPSHOT_TIMEOUT_MILLIS_DEFAULT = 60000 * 5;
124
125
126
127
128
129
130 @Deprecated
131 public static final String SNAPSHOT_TIMEOUT_MILLIS_KEY = "hbase.snapshot.master.timeoutMillis";
132
133 private SnapshotDescriptionUtils() {
134
135 }
136
137 public static int getDefaultSnapshotLayoutFormat(final Configuration conf) {
138 int layoutFormat = conf.getInt(SNAPSHOT_LAYOUT_CONF_KEY, SNAPSHOT_LAYOUT_LATEST_FORMAT);
139 if (layoutFormat >= SnapshotManifestV2.DESCRIPTOR_VERSION) {
140 return SnapshotManifestV2.DESCRIPTOR_VERSION;
141 }
142 return SnapshotManifestV1.DESCRIPTOR_VERSION;
143 }
144
145
146
147
148
149
150
151
152 public static long getMaxMasterTimeout(Configuration conf, SnapshotDescription.Type type,
153 long defaultMaxWaitTime) {
154 String confKey;
155 switch (type) {
156 case DISABLED:
157 default:
158 confKey = MASTER_SNAPSHOT_TIMEOUT_MILLIS;
159 }
160 return Math.max(conf.getLong(confKey, defaultMaxWaitTime),
161 conf.getLong(SNAPSHOT_TIMEOUT_MILLIS_KEY, defaultMaxWaitTime));
162 }
163
164
165
166
167
168
169
170 public static Path getSnapshotRootDir(final Path rootDir) {
171 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
172 }
173
174
175
176
177
178
179
180
181 public static Path getCompletedSnapshotDir(final SnapshotDescription snapshot, final Path rootDir) {
182 return getCompletedSnapshotDir(snapshot.getName(), rootDir);
183 }
184
185
186
187
188
189
190
191
192 public static Path getCompletedSnapshotDir(final String snapshotName, final Path rootDir) {
193 return getCompletedSnapshotDir(getSnapshotsDir(rootDir), snapshotName);
194 }
195
196
197
198
199
200
201
202 public static Path getWorkingSnapshotDir(final Path rootDir) {
203 return new Path(getSnapshotsDir(rootDir), SNAPSHOT_TMP_DIR_NAME);
204 }
205
206
207
208
209
210
211
212 public static Path getWorkingSnapshotDir(SnapshotDescription snapshot, final Path rootDir) {
213 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshot.getName());
214 }
215
216
217
218
219
220
221
222 public static Path getWorkingSnapshotDir(String snapshotName, final Path rootDir) {
223 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshotName);
224 }
225
226
227
228
229
230
231
232 private static final Path getCompletedSnapshotDir(final Path snapshotsDir, String snapshotName) {
233 return new Path(snapshotsDir, snapshotName);
234 }
235
236
237
238
239
240 public static final Path getSnapshotsDir(Path rootDir) {
241 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
242 }
243
244
245
246
247
248
249
250
251
252
253
254 public static SnapshotDescription validate(SnapshotDescription snapshot, Configuration conf)
255 throws IllegalArgumentException {
256 if (!snapshot.hasTable()) {
257 throw new IllegalArgumentException(
258 "Descriptor doesn't apply to a table, so we can't build it.");
259 }
260
261
262 long time = snapshot.getCreationTime();
263 if (time == SnapshotDescriptionUtils.NO_SNAPSHOT_START_TIME_SPECIFIED) {
264 time = EnvironmentEdgeManager.currentTimeMillis();
265 LOG.debug("Creation time not specified, setting to:" + time + " (current time:"
266 + EnvironmentEdgeManager.currentTimeMillis() + ").");
267 SnapshotDescription.Builder builder = snapshot.toBuilder();
268 builder.setCreationTime(time);
269 snapshot = builder.build();
270 }
271 return snapshot;
272 }
273
274
275
276
277
278
279
280
281
282 public static void writeSnapshotInfo(SnapshotDescription snapshot, Path workingDir, FileSystem fs)
283 throws IOException {
284 FsPermission perms = FSUtils.getFilePermissions(fs, fs.getConf(),
285 HConstants.DATA_FILE_UMASK_KEY);
286 Path snapshotInfo = new Path(workingDir, SnapshotDescriptionUtils.SNAPSHOTINFO_FILE);
287 try {
288 FSDataOutputStream out = FSUtils.create(fs, snapshotInfo, perms, true);
289 try {
290 snapshot.writeTo(out);
291 } finally {
292 out.close();
293 }
294 } catch (IOException e) {
295
296 if (!fs.delete(snapshotInfo, false)) {
297 String msg = "Couldn't delete snapshot info file: " + snapshotInfo;
298 LOG.error(msg);
299 throw new IOException(msg);
300 }
301 }
302 }
303
304
305
306
307
308
309
310
311
312 public static SnapshotDescription readSnapshotInfo(FileSystem fs, Path snapshotDir)
313 throws CorruptedSnapshotException {
314 Path snapshotInfo = new Path(snapshotDir, SNAPSHOTINFO_FILE);
315 try {
316 FSDataInputStream in = null;
317 try {
318 in = fs.open(snapshotInfo);
319 SnapshotDescription desc = SnapshotDescription.parseFrom(in);
320 return desc;
321 } finally {
322 if (in != null) in.close();
323 }
324 } catch (IOException e) {
325 throw new CorruptedSnapshotException("Couldn't read snapshot info from:" + snapshotInfo, e);
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340 public static void completeSnapshot(SnapshotDescription snapshot, Path rootdir, Path workingDir,
341 FileSystem fs) throws SnapshotCreationException, IOException {
342 Path finishedDir = getCompletedSnapshotDir(snapshot, rootdir);
343 LOG.debug("Snapshot is done, just moving the snapshot from " + workingDir + " to "
344 + finishedDir);
345 if (!fs.rename(workingDir, finishedDir)) {
346 throw new SnapshotCreationException("Failed to move working directory(" + workingDir
347 + ") to completed directory(" + finishedDir + ").", snapshot);
348 }
349 }
350
351 }