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.Set;
23
24 import org.apache.hadoop.classification.InterfaceAudience;
25 import org.apache.hadoop.classification.InterfaceStability;
26 import org.apache.hadoop.fs.FSDataInputStream;
27 import org.apache.hadoop.fs.FileStatus;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.fs.PathFilter;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.ServerName;
34 import org.apache.hadoop.hbase.catalog.MetaReader;
35 import org.apache.hadoop.hbase.master.MasterServices;
36 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
37 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription.Type;
38 import org.apache.hadoop.hbase.regionserver.HRegion;
39 import org.apache.hadoop.hbase.regionserver.StoreFile;
40 import org.apache.hadoop.hbase.snapshot.CorruptedSnapshotException;
41 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
42 import org.apache.hadoop.hbase.snapshot.TakeSnapshotUtils;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.apache.hadoop.hbase.util.FSTableDescriptors;
45 import org.apache.hadoop.hbase.util.FSUtils;
46 import org.apache.hadoop.hbase.util.HFileArchiveUtil;
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
76 @InterfaceAudience.Private
77 @InterfaceStability.Unstable
78 public final class MasterSnapshotVerifier {
79
80 private SnapshotDescription snapshot;
81 private FileSystem fs;
82 private Path rootDir;
83 private String tableName;
84 private MasterServices services;
85
86
87
88
89
90
91 public MasterSnapshotVerifier(MasterServices services, SnapshotDescription snapshot, Path rootDir) {
92 this.fs = services.getMasterFileSystem().getFileSystem();
93 this.services = services;
94 this.snapshot = snapshot;
95 this.rootDir = rootDir;
96 this.tableName = snapshot.getTable();
97 }
98
99
100
101
102
103
104
105
106 public void verifySnapshot(Path snapshotDir, Set<String> snapshotServers)
107 throws CorruptedSnapshotException, IOException {
108
109 verifySnapshotDescription(snapshotDir);
110
111
112 verifyTableInfo(snapshotDir);
113
114
115 verifyRegions(snapshotDir);
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(Path snapshotDir) throws IOException {
135 FSTableDescriptors.getTableDescriptor(fs, snapshotDir);
136 }
137
138
139
140
141
142
143 private void verifyRegions(Path snapshotDir) throws IOException {
144 List<HRegionInfo> regions = MetaReader.getTableRegions(this.services.getCatalogTracker(),
145 Bytes.toBytes(tableName));
146 for (HRegionInfo region : regions) {
147
148 if (region.isOffline() && (region.isSplit() || region.isSplitParent())) {
149 continue;
150 }
151
152 verifyRegion(fs, snapshotDir, region);
153 }
154 }
155
156
157
158
159
160
161
162 private void verifyRegion(FileSystem fs, Path snapshotDir, HRegionInfo region) throws IOException {
163
164 Path regionDir = new Path(snapshotDir, region.getEncodedName());
165 if (!fs.exists(regionDir)) {
166
167 throw new CorruptedSnapshotException("No region directory found for region:" + region,
168 snapshot);
169 }
170
171 Path regionInfo = new Path(regionDir, HRegion.REGIONINFO_FILE);
172
173 if (!fs.exists(regionInfo)) {
174 throw new CorruptedSnapshotException("No region info found for region:" + region, snapshot);
175 }
176 FSDataInputStream in = fs.open(regionInfo);
177 HRegionInfo found = new HRegionInfo();
178 try {
179 found.readFields(in);
180 if (!region.equals(found)) {
181 throw new CorruptedSnapshotException("Found region info (" + found
182 + ") doesn't match expected region:" + region, snapshot);
183 }
184 } finally {
185 in.close();
186 }
187
188
189 TakeSnapshotUtils.verifyRecoveredEdits(fs, snapshotDir, found, snapshot);
190
191
192 PathFilter familiesDirs = new FSUtils.FamilyDirFilter(fs);
193 FileStatus[] columnFamilies = FSUtils.listStatus(fs, regionDir, familiesDirs);
194
195 if (columnFamilies == null) return;
196
197
198 Path tableNameSuffix = new Path(tableName);
199 Path regionNameSuffix = new Path(tableNameSuffix, region.getEncodedName());
200
201
202 Path archivedRegion = new Path(HFileArchiveUtil.getArchivePath(services.getConfiguration()),
203 regionNameSuffix);
204 Path realRegion = new Path(rootDir, regionNameSuffix);
205
206
207 for (FileStatus cf : columnFamilies) {
208 FileStatus[] hfiles = FSUtils.listStatus(fs, cf.getPath(), null);
209
210 if (hfiles == null || hfiles.length == 0) continue;
211
212 Path realCfDir = new Path(realRegion, cf.getPath().getName());
213 Path archivedCfDir = new Path(archivedRegion, cf.getPath().getName());
214 for (FileStatus hfile : hfiles) {
215
216 if (!StoreFile.validateStoreFileName(hfile.getPath().getName())) {
217 throw new CorruptedSnapshotException("HFile: " + hfile.getPath()
218 + " is not a valid hfile name.", snapshot);
219 }
220
221
222 String fileName = hfile.getPath().getName();
223 Path file = new Path(realCfDir, fileName);
224 Path archived = new Path(archivedCfDir, fileName);
225 if (!fs.exists(file) && !fs.exists(archived)) {
226 throw new CorruptedSnapshotException("Can't find hfile: " + hfile.getPath()
227 + " in the real (" + realCfDir + ") or archive (" + archivedCfDir
228 + ") directory for the primary table.", snapshot);
229 }
230 }
231 }
232 }
233
234
235
236
237
238
239
240
241
242 private void verifyLogs(Path snapshotDir, Set<String> snapshotServers)
243 throws CorruptedSnapshotException, IOException {
244 Path snapshotLogDir = new Path(snapshotDir, HConstants.HREGION_LOGDIR_NAME);
245 Path logsDir = new Path(rootDir, HConstants.HREGION_LOGDIR_NAME);
246 TakeSnapshotUtils.verifyAllLogsGotReferenced(fs, logsDir, snapshotServers, snapshot,
247 snapshotLogDir);
248 }
249 }