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 public static final String MASTER_SNAPSHOT_TIMEOUT_MILLIS = "hbase.snapshot.master.timeout.millis";
112
113
114 public static final long DEFAULT_MAX_WAIT_TIME = 60000;
115
116 private SnapshotDescriptionUtils() {
117
118 }
119
120 public static int getDefaultSnapshotLayoutFormat(final Configuration conf) {
121 int layoutFormat = conf.getInt(SNAPSHOT_LAYOUT_CONF_KEY, SNAPSHOT_LAYOUT_LATEST_FORMAT);
122 if (layoutFormat >= SnapshotManifestV2.DESCRIPTOR_VERSION) {
123 return SnapshotManifestV2.DESCRIPTOR_VERSION;
124 }
125 return SnapshotManifestV1.DESCRIPTOR_VERSION;
126 }
127
128
129
130
131
132
133
134
135 public static long getMaxMasterTimeout(Configuration conf, SnapshotDescription.Type type,
136 long defaultMaxWaitTime) {
137 String confKey;
138 switch (type) {
139 case DISABLED:
140 default:
141 confKey = MASTER_SNAPSHOT_TIMEOUT_MILLIS;
142 }
143 return conf.getLong(confKey, defaultMaxWaitTime);
144 }
145
146
147
148
149
150
151
152 public static Path getSnapshotRootDir(final Path rootDir) {
153 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
154 }
155
156
157
158
159
160
161
162
163 public static Path getCompletedSnapshotDir(final SnapshotDescription snapshot, final Path rootDir) {
164 return getCompletedSnapshotDir(snapshot.getName(), rootDir);
165 }
166
167
168
169
170
171
172
173
174 public static Path getCompletedSnapshotDir(final String snapshotName, final Path rootDir) {
175 return getCompletedSnapshotDir(getSnapshotsDir(rootDir), snapshotName);
176 }
177
178
179
180
181
182
183
184 public static Path getWorkingSnapshotDir(final Path rootDir) {
185 return new Path(getSnapshotsDir(rootDir), SNAPSHOT_TMP_DIR_NAME);
186 }
187
188
189
190
191
192
193
194 public static Path getWorkingSnapshotDir(SnapshotDescription snapshot, final Path rootDir) {
195 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshot.getName());
196 }
197
198
199
200
201
202
203
204 public static Path getWorkingSnapshotDir(String snapshotName, final Path rootDir) {
205 return getCompletedSnapshotDir(getWorkingSnapshotDir(rootDir), snapshotName);
206 }
207
208
209
210
211
212
213
214 private static final Path getCompletedSnapshotDir(final Path snapshotsDir, String snapshotName) {
215 return new Path(snapshotsDir, snapshotName);
216 }
217
218
219
220
221
222 public static final Path getSnapshotsDir(Path rootDir) {
223 return new Path(rootDir, HConstants.SNAPSHOT_DIR_NAME);
224 }
225
226
227
228
229
230
231
232
233
234
235
236 public static SnapshotDescription validate(SnapshotDescription snapshot, Configuration conf)
237 throws IllegalArgumentException {
238 if (!snapshot.hasTable()) {
239 throw new IllegalArgumentException(
240 "Descriptor doesn't apply to a table, so we can't build it.");
241 }
242
243
244 long time = snapshot.getCreationTime();
245 if (time == SnapshotDescriptionUtils.NO_SNAPSHOT_START_TIME_SPECIFIED) {
246 time = EnvironmentEdgeManager.currentTimeMillis();
247 LOG.debug("Creation time not specified, setting to:" + time + " (current time:"
248 + EnvironmentEdgeManager.currentTimeMillis() + ").");
249 SnapshotDescription.Builder builder = snapshot.toBuilder();
250 builder.setCreationTime(time);
251 snapshot = builder.build();
252 }
253 return snapshot;
254 }
255
256
257
258
259
260
261
262
263
264 public static void writeSnapshotInfo(SnapshotDescription snapshot, Path workingDir, FileSystem fs)
265 throws IOException {
266 FsPermission perms = FSUtils.getFilePermissions(fs, fs.getConf(),
267 HConstants.DATA_FILE_UMASK_KEY);
268 Path snapshotInfo = new Path(workingDir, SnapshotDescriptionUtils.SNAPSHOTINFO_FILE);
269 try {
270 FSDataOutputStream out = FSUtils.create(fs, snapshotInfo, perms, true);
271 try {
272 snapshot.writeTo(out);
273 } finally {
274 out.close();
275 }
276 } catch (IOException e) {
277
278 if (!fs.delete(snapshotInfo, false)) {
279 String msg = "Couldn't delete snapshot info file: " + snapshotInfo;
280 LOG.error(msg);
281 throw new IOException(msg);
282 }
283 }
284 }
285
286
287
288
289
290
291
292
293
294 public static SnapshotDescription readSnapshotInfo(FileSystem fs, Path snapshotDir)
295 throws CorruptedSnapshotException {
296 Path snapshotInfo = new Path(snapshotDir, SNAPSHOTINFO_FILE);
297 try {
298 FSDataInputStream in = null;
299 try {
300 in = fs.open(snapshotInfo);
301 SnapshotDescription desc = SnapshotDescription.parseFrom(in);
302 return desc;
303 } finally {
304 if (in != null) in.close();
305 }
306 } catch (IOException e) {
307 throw new CorruptedSnapshotException("Couldn't read snapshot info from:" + snapshotInfo, e);
308 }
309 }
310
311
312
313
314
315
316
317
318
319
320
321
322 public static void completeSnapshot(SnapshotDescription snapshot, Path rootdir, Path workingDir,
323 FileSystem fs) throws SnapshotCreationException, IOException {
324 Path finishedDir = getCompletedSnapshotDir(snapshot, rootdir);
325 LOG.debug("Snapshot is done, just moving the snapshot from " + workingDir + " to "
326 + finishedDir);
327 if (!fs.rename(workingDir, finishedDir)) {
328 throw new SnapshotCreationException("Failed to move working directory(" + workingDir
329 + ") to completed directory(" + finishedDir + ").", snapshot);
330 }
331 }
332
333 }