1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.client;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.UUID;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.hbase.classification.InterfaceAudience;
30 import org.apache.hadoop.hbase.classification.InterfaceStability;
31 import org.apache.hadoop.conf.Configuration;
32 import org.apache.hadoop.fs.FileSystem;
33 import org.apache.hadoop.fs.Path;
34 import org.apache.hadoop.hbase.CellUtil;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.mapreduce.TableSnapshotInputFormat;
38 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
39 import org.apache.hadoop.hbase.protobuf.generated.SnapshotProtos.SnapshotRegionManifest;
40 import org.apache.hadoop.hbase.snapshot.ExportSnapshot;
41 import org.apache.hadoop.hbase.snapshot.RestoreSnapshotHelper;
42 import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
43 import org.apache.hadoop.hbase.snapshot.SnapshotManifest;
44 import org.apache.hadoop.hbase.util.FSUtils;
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 @InterfaceAudience.Public
73 @InterfaceStability.Evolving
74 public class TableSnapshotScanner extends AbstractClientScanner {
75
76 private static final Log LOG = LogFactory.getLog(TableSnapshotScanner.class);
77
78 private Configuration conf;
79 private String snapshotName;
80 private FileSystem fs;
81 private Path rootDir;
82 private Path restoreDir;
83 private Scan scan;
84 private ArrayList<HRegionInfo> regions;
85 private HTableDescriptor htd;
86
87 private ClientSideRegionScanner currentRegionScanner = null;
88 private int currentRegion = -1;
89
90
91
92
93
94
95
96
97
98
99
100 public TableSnapshotScanner(Configuration conf, Path restoreDir,
101 String snapshotName, Scan scan) throws IOException {
102 this(conf, FSUtils.getRootDir(conf), restoreDir, snapshotName, scan);
103 }
104
105
106
107
108
109
110
111
112
113
114
115
116 public TableSnapshotScanner(Configuration conf, Path rootDir,
117 Path restoreDir, String snapshotName, Scan scan) throws IOException {
118 this.conf = conf;
119 this.snapshotName = snapshotName;
120 this.rootDir = rootDir;
121
122 this.restoreDir = new Path(restoreDir, UUID.randomUUID().toString());
123 this.scan = scan;
124 this.fs = rootDir.getFileSystem(conf);
125 init();
126 }
127
128 private void init() throws IOException {
129 Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir);
130 SnapshotDescription snapshotDesc = SnapshotDescriptionUtils.readSnapshotInfo(fs, snapshotDir);
131 SnapshotManifest manifest = SnapshotManifest.open(conf, fs, snapshotDir, snapshotDesc);
132
133
134 htd = manifest.getTableDescriptor();
135
136 List<SnapshotRegionManifest> regionManifests = manifest.getRegionManifests();
137 if (regionManifests == null) {
138 throw new IllegalArgumentException("Snapshot seems empty");
139 }
140
141 regions = new ArrayList<HRegionInfo>(regionManifests.size());
142 for (SnapshotRegionManifest regionManifest : regionManifests) {
143
144 HRegionInfo hri = HRegionInfo.convert(regionManifest.getRegionInfo());
145
146 if (CellUtil.overlappingKeys(scan.getStartRow(), scan.getStopRow(),
147 hri.getStartKey(), hri.getEndKey())) {
148 regions.add(hri);
149 }
150 }
151
152
153 Collections.sort(regions);
154
155 initScanMetrics(scan);
156
157 RestoreSnapshotHelper.copySnapshotForScanner(conf, fs,
158 rootDir, restoreDir, snapshotName);
159 }
160
161 @Override
162 public Result next() throws IOException {
163 Result result = null;
164 while (true) {
165 if (currentRegionScanner == null) {
166 currentRegion++;
167 if (currentRegion >= regions.size()) {
168 return null;
169 }
170
171 HRegionInfo hri = regions.get(currentRegion);
172 currentRegionScanner = new ClientSideRegionScanner(conf, fs,
173 restoreDir, htd, hri, scan, scanMetrics);
174 if (this.scanMetrics != null) {
175 this.scanMetrics.countOfRegions.incrementAndGet();
176 }
177 }
178
179 try {
180 result = currentRegionScanner.next();
181 if (result != null) {
182 return result;
183 }
184 } finally {
185 if (result == null) {
186 currentRegionScanner.close();
187 currentRegionScanner = null;
188 }
189 }
190 }
191 }
192
193 @Override
194 public void close() {
195 if (currentRegionScanner != null) {
196 currentRegionScanner.close();
197 }
198 try {
199 fs.delete(this.restoreDir, true);
200 } catch (IOException ex) {
201 LOG.warn("Could not delete restore directory for the snapshot:" + ex);
202 }
203 }
204
205 }