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