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