1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.snapshot;
20
21 import com.google.protobuf.InvalidProtocolBufferException;
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.util.ArrayList;
25 import java.util.List;
26 import java.util.concurrent.Callable;
27 import java.util.concurrent.Executor;
28 import java.util.concurrent.ExecutionException;
29 import java.util.concurrent.ExecutorCompletionService;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.apache.hadoop.hbase.classification.InterfaceAudience;
34 import org.apache.hadoop.conf.Configuration;
35 import org.apache.hadoop.fs.FSDataInputStream;
36 import org.apache.hadoop.fs.FSDataOutputStream;
37 import org.apache.hadoop.fs.FileStatus;
38 import org.apache.hadoop.fs.FileSystem;
39 import org.apache.hadoop.fs.Path;
40 import org.apache.hadoop.fs.PathFilter;
41 import org.apache.hadoop.hbase.HRegionInfo;
42 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
43 import org.apache.hadoop.hbase.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;
44 import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
45 import org.apache.hadoop.hbase.util.ByteStringer;
46 import org.apache.hadoop.hbase.util.FSUtils;
47
48
49
50
51
52
53
54
55
56 @InterfaceAudience.Private
57 public final class SnapshotManifestV2 {
58 private static final Log LOG = LogFactory.getLog(SnapshotManifestV2.class);
59
60 public static final int DESCRIPTOR_VERSION = 2;
61
62 public static final String SNAPSHOT_MANIFEST_PREFIX = "region-manifest.";
63
64 private SnapshotManifestV2() {}
65
66 static class ManifestBuilder implements SnapshotManifest.RegionVisitor<
67 SnapshotRegionManifest.Builder, SnapshotRegionManifest.FamilyFiles.Builder> {
68 private final Configuration conf;
69 private final Path snapshotDir;
70 private final FileSystem fs;
71
72 public ManifestBuilder(final Configuration conf, final FileSystem fs, final Path snapshotDir) {
73 this.snapshotDir = snapshotDir;
74 this.conf = conf;
75 this.fs = fs;
76 }
77
78 public SnapshotRegionManifest.Builder regionOpen(final HRegionInfo regionInfo) {
79 SnapshotRegionManifest.Builder manifest = SnapshotRegionManifest.newBuilder();
80 manifest.setRegionInfo(HRegionInfo.convert(regionInfo));
81 return manifest;
82 }
83
84 public void regionClose(final SnapshotRegionManifest.Builder region) throws IOException {
85
86
87 if (fs.exists(snapshotDir)) {
88 SnapshotRegionManifest manifest = region.build();
89 FSDataOutputStream stream = fs.create(getRegionManifestPath(snapshotDir, manifest));
90 try {
91 manifest.writeTo(stream);
92 } finally {
93 stream.close();
94 }
95 } else {
96 LOG.warn("can't write manifest without parent dir, maybe it has been deleted by master?");
97 }
98 }
99
100 public SnapshotRegionManifest.FamilyFiles.Builder familyOpen(
101 final SnapshotRegionManifest.Builder region, final byte[] familyName) {
102 SnapshotRegionManifest.FamilyFiles.Builder family =
103 SnapshotRegionManifest.FamilyFiles.newBuilder();
104 family.setFamilyName(ByteStringer.wrap(familyName));
105 return family;
106 }
107
108 public void familyClose(final SnapshotRegionManifest.Builder region,
109 final SnapshotRegionManifest.FamilyFiles.Builder family) {
110 region.addFamilyFiles(family.build());
111 }
112
113 public void storeFile(final SnapshotRegionManifest.Builder region,
114 final SnapshotRegionManifest.FamilyFiles.Builder family, final StoreFileInfo storeFile)
115 throws IOException {
116 SnapshotRegionManifest.StoreFile.Builder sfManifest =
117 SnapshotRegionManifest.StoreFile.newBuilder();
118 sfManifest.setName(storeFile.getPath().getName());
119 if (storeFile.isReference()) {
120 sfManifest.setReference(storeFile.getReference().convert());
121 }
122 sfManifest.setFileSize(storeFile.getReferencedFileStatus(fs).getLen());
123 family.addStoreFiles(sfManifest.build());
124 }
125 }
126
127 static List<SnapshotRegionManifest> loadRegionManifests(final Configuration conf,
128 final Executor executor,final FileSystem fs, final Path snapshotDir,
129 final SnapshotDescription desc) throws IOException {
130 FileStatus[] manifestFiles = FSUtils.listStatus(fs, snapshotDir, new PathFilter() {
131 @Override
132 public boolean accept(Path path) {
133 return path.getName().startsWith(SNAPSHOT_MANIFEST_PREFIX);
134 }
135 });
136
137 if (manifestFiles == null || manifestFiles.length == 0) return null;
138
139 final ExecutorCompletionService<SnapshotRegionManifest> completionService =
140 new ExecutorCompletionService<SnapshotRegionManifest>(executor);
141 for (final FileStatus st: manifestFiles) {
142 completionService.submit(new Callable<SnapshotRegionManifest>() {
143 @Override
144 public SnapshotRegionManifest call() throws IOException {
145 FSDataInputStream stream = fs.open(st.getPath());
146 try {
147 return SnapshotRegionManifest.parseFrom(stream);
148 } finally {
149 stream.close();
150 }
151 }
152 });
153 }
154
155 ArrayList<SnapshotRegionManifest> regionsManifest =
156 new ArrayList<SnapshotRegionManifest>(manifestFiles.length);
157 try {
158 for (int i = 0; i < manifestFiles.length; ++i) {
159 regionsManifest.add(completionService.take().get());
160 }
161 } catch (InterruptedException e) {
162 throw new InterruptedIOException(e.getMessage());
163 } catch (ExecutionException e) {
164 Throwable t = e.getCause();
165
166 if(t instanceof InvalidProtocolBufferException) {
167 throw (InvalidProtocolBufferException)t;
168 } else {
169 IOException ex = new IOException("ExecutionException");
170 ex.initCause(e.getCause());
171 throw ex;
172 }
173 }
174 return regionsManifest;
175 }
176
177 static void deleteRegionManifest(final FileSystem fs, final Path snapshotDir,
178 final SnapshotRegionManifest manifest) throws IOException {
179 fs.delete(getRegionManifestPath(snapshotDir, manifest), true);
180 }
181
182 private static Path getRegionManifestPath(final Path snapshotDir,
183 final SnapshotRegionManifest manifest) {
184 String regionName = SnapshotManifest.getRegionNameFromManifest(manifest);
185 return new Path(snapshotDir, SNAPSHOT_MANIFEST_PREFIX + regionName);
186 }
187 }