1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master.snapshot;
19
20 import java.io.IOException;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.classification.InterfaceStability;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.hbase.TableName;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.ServerName;
35 import org.apache.hadoop.hbase.catalog.MetaReader;
36 import org.apache.hadoop.hbase.master.MasterServices;
37 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
38 import org.apache.hadoop.hbase.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;
39 import org.apache.hadoop.hbase.snapshot.ClientSnapshotDescriptionUtils;
40 import org.apache.hadoop.hbase.snapshot.CorruptedSnapshotException;
41 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
42 import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
43 import org.apache.hadoop.hbase.snapshot.SnapshotReferenceUtil;
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 @InterfaceAudience.Private
74 @InterfaceStability.Unstable
75 public final class MasterSnapshotVerifier {
76 private static final Log LOG = LogFactory.getLog(MasterSnapshotVerifier.class);
77
78 private SnapshotDescription snapshot;
79 private FileSystem fs;
80 private Path rootDir;
81 private TableName tableName;
82 private MasterServices services;
83
84
85
86
87
88
89 public MasterSnapshotVerifier(MasterServices services, SnapshotDescription snapshot, Path rootDir) {
90 this.fs = services.getMasterFileSystem().getFileSystem();
91 this.services = services;
92 this.snapshot = snapshot;
93 this.rootDir = rootDir;
94 this.tableName = TableName.valueOf(snapshot.getTable());
95 }
96
97
98
99
100
101
102
103
104 public void verifySnapshot(Path snapshotDir, Set<String> snapshotServers)
105 throws CorruptedSnapshotException, IOException {
106 SnapshotManifest manifest = SnapshotManifest.open(services.getConfiguration(), fs,
107 snapshotDir, snapshot);
108
109 verifySnapshotDescription(snapshotDir);
110
111
112 verifyTableInfo(manifest);
113
114
115 verifyRegions(manifest);
116 }
117
118
119
120
121
122 private void verifySnapshotDescription(Path snapshotDir) throws CorruptedSnapshotException {
123 SnapshotDescription found = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
124 if (!this.snapshot.equals(found)) {
125 throw new CorruptedSnapshotException("Snapshot read (" + found
126 + ") doesn't equal snapshot we ran (" + snapshot + ").", snapshot);
127 }
128 }
129
130
131
132
133
134 private void verifyTableInfo(final SnapshotManifest manifest) throws IOException {
135 HTableDescriptor htd = manifest.getTableDescriptor();
136 if (htd == null) {
137 throw new CorruptedSnapshotException("Missing Table Descriptor", snapshot);
138 }
139
140 if (!htd.getNameAsString().equals(snapshot.getTable())) {
141 throw new CorruptedSnapshotException("Invalid Table Descriptor. Expected "
142 + snapshot.getTable() + " name, got " + htd.getNameAsString(), snapshot);
143 }
144 }
145
146
147
148
149
150
151 private void verifyRegions(final SnapshotManifest manifest) throws IOException {
152 List<HRegionInfo> regions = MetaReader.getTableRegions(this.services.getCatalogTracker(),
153 tableName);
154
155 Map<String, SnapshotRegionManifest> regionManifests = manifest.getRegionManifestsMap();
156 if (regionManifests == null) {
157 String msg = "Snapshot " + ClientSnapshotDescriptionUtils.toString(snapshot) + " looks empty";
158 LOG.error(msg);
159 throw new CorruptedSnapshotException(msg);
160 }
161
162 String errorMsg = "";
163 if (regionManifests.size() != regions.size()) {
164 errorMsg = "Regions moved during the snapshot '" +
165 ClientSnapshotDescriptionUtils.toString(snapshot) + "'. expected=" +
166 regions.size() + " snapshotted=" + regionManifests.size() + ".";
167 LOG.error(errorMsg);
168 }
169
170
171 for (HRegionInfo region : regions) {
172 SnapshotRegionManifest regionManifest = regionManifests.get(region.getEncodedName());
173 if (regionManifest == null) {
174
175 String mesg = " No snapshot region directory found for region:" + region;
176 if (errorMsg.isEmpty()) errorMsg = mesg;
177 LOG.error(mesg);
178 continue;
179 }
180
181 verifyRegionInfo(region, regionManifest);
182 }
183
184 if (!errorMsg.isEmpty()) {
185 throw new CorruptedSnapshotException(errorMsg);
186 }
187
188
189 SnapshotReferenceUtil.verifySnapshot(services.getConfiguration(), fs, manifest);
190 }
191
192
193
194
195
196
197 private void verifyRegionInfo(final HRegionInfo region,
198 final SnapshotRegionManifest manifest) throws IOException {
199 HRegionInfo manifestRegionInfo = HRegionInfo.convert(manifest.getRegionInfo());
200 if (!region.equals(manifestRegionInfo)) {
201 String msg = "Manifest region info " + manifestRegionInfo +
202 "doesn't match expected region:" + region;
203 throw new CorruptedSnapshotException(msg, snapshot);
204 }
205 }
206 }