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.Set;
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.classification.InterfaceAudience;
30 import org.apache.hadoop.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.HConstants;
36 import org.apache.hadoop.hbase.HRegionInfo;
37 import org.apache.hadoop.hbase.HTableDescriptor;
38 import org.apache.hadoop.hbase.mapreduce.TableSnapshotInputFormat;
39 import org.apache.hadoop.hbase.regionserver.HRegionFileSystem;
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.SnapshotReferenceUtil;
44 import org.apache.hadoop.hbase.util.FSTableDescriptors;
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, new Path(conf.get(HConstants.HBASE_DIR)),
103 restoreDir, snapshotName, scan);
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117 public TableSnapshotScanner(Configuration conf, Path rootDir,
118 Path restoreDir, String snapshotName, Scan scan) throws IOException {
119 this.conf = conf;
120 this.snapshotName = snapshotName;
121 this.rootDir = rootDir;
122
123 this.restoreDir = new Path(restoreDir, UUID.randomUUID().toString());
124 this.scan = scan;
125 this.fs = rootDir.getFileSystem(conf);
126 init();
127 }
128
129 private void init() throws IOException {
130 Path snapshotDir = SnapshotDescriptionUtils.getCompletedSnapshotDir(snapshotName, rootDir);
131
132
133 htd = FSTableDescriptors.getTableDescriptorFromFs(fs, snapshotDir);
134
135 Set<String> snapshotRegionNames
136 = SnapshotReferenceUtil.getSnapshotRegionNames(fs, snapshotDir);
137 if (snapshotRegionNames == null) {
138 throw new IllegalArgumentException("Snapshot seems empty");
139 }
140
141 regions = new ArrayList<HRegionInfo>(snapshotRegionNames.size());
142 for (String regionName : snapshotRegionNames) {
143
144 Path regionDir = new Path(snapshotDir, regionName);
145 HRegionInfo hri = HRegionFileSystem.loadRegionInfoFileContent(fs,
146 regionDir);
147
148 if (CellUtil.overlappingKeys(scan.getStartRow(), scan.getStopRow(),
149 hri.getStartKey(), hri.getEndKey())) {
150 regions.add(hri);
151 }
152 }
153
154
155 Collections.sort(regions);
156
157 initScanMetrics(scan);
158
159 RestoreSnapshotHelper.copySnapshotForScanner(conf, fs,
160 rootDir, restoreDir, snapshotName);
161 }
162
163 @Override
164 public Result next() throws IOException {
165 Result result = null;
166 while (true) {
167 if (currentRegionScanner == null) {
168 currentRegion++;
169 if (currentRegion >= regions.size()) {
170 return null;
171 }
172
173 HRegionInfo hri = regions.get(currentRegion);
174 currentRegionScanner = new ClientSideRegionScanner(conf, fs,
175 restoreDir, htd, hri, scan, scanMetrics);
176 if (this.scanMetrics != null) {
177 this.scanMetrics.countOfRegions.incrementAndGet();
178 }
179 }
180
181 try {
182 result = currentRegionScanner.next();
183 if (result != null) {
184 return result;
185 }
186 } finally {
187 if (result == null) {
188 currentRegionScanner.close();
189 currentRegionScanner = null;
190 }
191 }
192 }
193 }
194
195 @Override
196 public void close() {
197 if (currentRegionScanner != null) {
198 currentRegionScanner.close();
199 }
200 try {
201 fs.delete(this.restoreDir, true);
202 } catch (IOException ex) {
203 LOG.warn("Could not delete restore directory for the snapshot:" + ex);
204 }
205 }
206
207 }