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.FileStatus;
27 import org.apache.hadoop.fs.FileSystem;
28 import org.apache.hadoop.fs.Path;
29 import org.apache.hadoop.fs.PathFilter;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.HRegionInfo;
32 import org.apache.hadoop.hbase.ServerName;
33 import org.apache.hadoop.hbase.catalog.MetaReader;
34 import org.apache.hadoop.hbase.master.MasterServices;
35 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
36 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
37 import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
38 import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
39 import org.apache.hadoop.hbase.snapshot.CorruptedSnapshotException;
40 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
41 import org.apache.hadoop.hbase.snapshot.TakeSnapshotUtils;
42 import org.apache.hadoop.hbase.util.FSTableDescriptors;
43 import org.apache.hadoop.hbase.util.FSUtils;
44 import org.apache.hadoop.hbase.util.HFileArchiveUtil;
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 @InterfaceAudience.Private
75 @InterfaceStability.Unstable
76 public final class MasterSnapshotVerifier {
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
107 verifySnapshotDescription(snapshotDir);
108
109
110 verifyTableInfo(snapshotDir);
111
112
113 verifyRegions(snapshotDir);
114 }
115
116
117
118
119
120 private void verifySnapshotDescription(Path snapshotDir) throws CorruptedSnapshotException {
121 SnapshotDescription found = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
122 if (!this.snapshot.equals(found)) {
123 throw new CorruptedSnapshotException("Snapshot read (" + found
124 + ") doesn't equal snapshot we ran (" + snapshot + ").", snapshot);
125 }
126 }
127
128
129
130
131
132 private void verifyTableInfo(Path snapshotDir) throws IOException {
133 FSTableDescriptors.getTableDescriptorFromFs(fs, snapshotDir);
134 }
135
136
137
138
139
140
141 private void verifyRegions(Path snapshotDir) throws IOException {
142 List<HRegionInfo> regions = MetaReader.getTableRegions(this.services.getCatalogTracker(),
143 tableName);
144 for (HRegionInfo region : regions) {
145
146 if (region.isOffline() && (region.isSplit() || region.isSplitParent())) {
147 continue;
148 }
149
150 verifyRegion(fs, snapshotDir, region);
151 }
152 }
153
154
155
156
157
158
159
160 private void verifyRegion(FileSystem fs, Path snapshotDir, HRegionInfo region) throws IOException {
161
162 Path regionDir = new Path(snapshotDir, region.getEncodedName());
163 if (!fs.exists(regionDir)) {
164
165 throw new CorruptedSnapshotException("No region directory found for region:" + region,
166 snapshot);
167 }
168
169 Path regionInfo = new Path(regionDir, HRegionFileSystem.REGION_INFO_FILE);
170
171 if (!fs.exists(regionInfo)) {
172 throw new CorruptedSnapshotException("No region info found for region:" + region, snapshot);
173 }
174
175 HRegionInfo found = HRegionFileSystem.loadRegionInfoFileContent(fs, regionDir);
176 if (!region.equals(found)) {
177 throw new CorruptedSnapshotException("Found region info (" + found
178 + ") doesn't match expected region:" + region, snapshot);
179 }
180
181
182 TakeSnapshotUtils.verifyRecoveredEdits(fs, snapshotDir, found, snapshot);
183
184
185 PathFilter familiesDirs = new FSUtils.FamilyDirFilter(fs);
186 FileStatus[] columnFamilies = FSUtils.listStatus(fs, regionDir, familiesDirs);
187
188 if (columnFamilies == null) return;
189
190
191 Path tableNameSuffix = FSUtils.getTableDir(new Path("./"), tableName);
192 Path regionNameSuffix = new Path(tableNameSuffix, region.getEncodedName());
193
194
195 Path archivedRegion = new Path(HFileArchiveUtil.getArchivePath(services.getConfiguration()),
196 regionNameSuffix);
197 Path realRegion = new Path(rootDir, regionNameSuffix);
198
199
200 for (FileStatus cf : columnFamilies) {
201 FileStatus[] hfiles = FSUtils.listStatus(fs, cf.getPath(), null);
202
203 if (hfiles == null || hfiles.length == 0) continue;
204
205 Path realCfDir = new Path(realRegion, cf.getPath().getName());
206 Path archivedCfDir = new Path(archivedRegion, cf.getPath().getName());
207 for (FileStatus hfile : hfiles) {
208
209 if (!StoreFileInfo.validateStoreFileName(hfile.getPath().getName())) {
210 throw new CorruptedSnapshotException("HFile: " + hfile.getPath()
211 + " is not a valid hfile name.", snapshot);
212 }
213
214
215 String fileName = hfile.getPath().getName();
216 Path file = new Path(realCfDir, fileName);
217 Path archived = new Path(archivedCfDir, fileName);
218 if (!fs.exists(file) && !fs.exists(archived)) {
219 throw new CorruptedSnapshotException("Can't find hfile: " + hfile.getPath()
220 + " in the real (" + realCfDir + ") or archive (" + archivedCfDir
221 + ") directory for the primary table.", snapshot);
222 }
223 }
224 }
225 }
226 }