1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.zookeeper;
19
20 import java.io.IOException;
21 import java.io.InterruptedIOException;
22 import java.io.UnsupportedEncodingException;
23 import java.net.URLDecoder;
24 import java.net.URLEncoder;
25 import java.util.List;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.fs.FileSystem;
30 import org.apache.hadoop.fs.Path;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.classification.InterfaceAudience;
33 import org.apache.hadoop.hbase.exceptions.DeserializationException;
34 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos.RegionStoreSequenceIds;
35 import org.apache.zookeeper.KeeperException;
36
37
38
39
40
41
42
43 @InterfaceAudience.Private
44 public class ZKSplitLog {
45 private static final Log LOG = LogFactory.getLog(ZKSplitLog.class);
46
47
48
49
50
51
52
53 public static String getEncodedNodeName(ZooKeeperWatcher zkw, String filename) {
54 return ZKUtil.joinZNode(zkw.splitLogZNode, encode(filename));
55 }
56
57 public static String getFileName(String node) {
58 String basename = node.substring(node.lastIndexOf('/') + 1);
59 return decode(basename);
60 }
61
62 static String encode(String s) {
63 try {
64 return URLEncoder.encode(s, "UTF-8");
65 } catch (UnsupportedEncodingException e) {
66 throw new RuntimeException("URLENCODER doesn't support UTF-8");
67 }
68 }
69
70 static String decode(String s) {
71 try {
72 return URLDecoder.decode(s, "UTF-8");
73 } catch (UnsupportedEncodingException e) {
74 throw new RuntimeException("URLDecoder doesn't support UTF-8");
75 }
76 }
77
78 public static String getRescanNode(ZooKeeperWatcher zkw) {
79 return ZKUtil.joinZNode(zkw.splitLogZNode, "RESCAN");
80 }
81
82
83
84
85
86 public static boolean isRescanNode(String name) {
87 return name.startsWith("RESCAN");
88 }
89
90
91
92
93
94
95 public static boolean isRescanNode(ZooKeeperWatcher zkw, String path) {
96 String prefix = getRescanNode(zkw);
97 if (path.length() <= prefix.length()) {
98 return false;
99 }
100 for (int i = 0; i < prefix.length(); i++) {
101 if (prefix.charAt(i) != path.charAt(i)) {
102 return false;
103 }
104 }
105 return true;
106 }
107
108 public static boolean isTaskPath(ZooKeeperWatcher zkw, String path) {
109 String dirname = path.substring(0, path.lastIndexOf('/'));
110 return dirname.equals(zkw.splitLogZNode);
111 }
112
113 public static Path getSplitLogDir(Path rootdir, String tmpname) {
114 return new Path(new Path(rootdir, HConstants.SPLIT_LOGDIR_NAME), tmpname);
115 }
116
117
118 public static String getSplitLogDirTmpComponent(final String worker, String file) {
119 return worker + "_" + ZKSplitLog.encode(file);
120 }
121
122 public static void markCorrupted(Path rootdir, String logFileName,
123 FileSystem fs) {
124 Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
125 try {
126 fs.createNewFile(file);
127 } catch (IOException e) {
128 LOG.warn("Could not flag a log file as corrupted. Failed to create " +
129 file, e);
130 }
131 }
132
133 public static boolean isCorrupted(Path rootdir, String logFileName,
134 FileSystem fs) throws IOException {
135 Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
136 boolean isCorrupt;
137 isCorrupt = fs.exists(file);
138 return isCorrupt;
139 }
140
141
142
143
144
145
146
147
148
149
150
151
152
153 public static boolean
154 isRegionMarkedRecoveringInZK(ZooKeeperWatcher zkw, String regionEncodedName)
155 throws KeeperException {
156 boolean result = false;
157 String nodePath = ZKUtil.joinZNode(zkw.recoveringRegionsZNode, regionEncodedName);
158
159 byte[] node = ZKUtil.getDataAndWatch(zkw, nodePath);
160 if (node != null) {
161 result = true;
162 }
163 return result;
164 }
165
166
167
168
169
170 public static long parseLastFlushedSequenceIdFrom(final byte[] bytes) {
171 long lastRecordedFlushedSequenceId = -1l;
172 try {
173 lastRecordedFlushedSequenceId = ZKUtil.parseWALPositionFrom(bytes);
174 } catch (DeserializationException e) {
175 lastRecordedFlushedSequenceId = -1l;
176 LOG.warn("Can't parse last flushed sequence Id", e);
177 }
178 return lastRecordedFlushedSequenceId;
179 }
180
181 public static void deleteRecoveringRegionZNodes(ZooKeeperWatcher watcher, List<String> regions) {
182 try {
183 if (regions == null) {
184
185 LOG.debug("Garbage collecting all recovering region znodes");
186 ZKUtil.deleteChildrenRecursively(watcher, watcher.recoveringRegionsZNode);
187 } else {
188 for (String curRegion : regions) {
189 String nodePath = ZKUtil.joinZNode(watcher.recoveringRegionsZNode, curRegion);
190 ZKUtil.deleteNodeRecursively(watcher, nodePath);
191 }
192 }
193 } catch (KeeperException e) {
194 LOG.warn("Cannot remove recovering regions from ZooKeeper", e);
195 }
196 }
197
198
199
200
201
202
203
204
205
206
207 public static RegionStoreSequenceIds getRegionFlushedSequenceId(ZooKeeperWatcher zkw,
208 String serverName, String encodedRegionName) throws IOException {
209
210
211
212
213
214
215
216 RegionStoreSequenceIds result = null;
217 String nodePath = ZKUtil.joinZNode(zkw.recoveringRegionsZNode, encodedRegionName);
218 nodePath = ZKUtil.joinZNode(nodePath, serverName);
219 try {
220 byte[] data;
221 try {
222 data = ZKUtil.getData(zkw, nodePath);
223 } catch (InterruptedException e) {
224 throw new InterruptedIOException();
225 }
226 if (data != null) {
227 result = ZKUtil.parseRegionStoreSequenceIds(data);
228 }
229 } catch (KeeperException e) {
230 throw new IOException("Cannot get lastFlushedSequenceId from ZooKeeper for server="
231 + serverName + "; region=" + encodedRegionName, e);
232 } catch (DeserializationException e) {
233 LOG.warn("Can't parse last flushed sequence Id from znode:" + nodePath, e);
234 }
235 return result;
236 }
237 }