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.hbase.classification.InterfaceAudience;
30 import org.apache.hadoop.fs.FileSystem;
31 import org.apache.hadoop.fs.Path;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.exceptions.DeserializationException;
34 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.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 public static boolean isRescanNode(ZooKeeperWatcher zkw, String path) {
83 String prefix = getRescanNode(zkw);
84 if (path.length() <= prefix.length()) {
85 return false;
86 }
87 for (int i = 0; i < prefix.length(); i++) {
88 if (prefix.charAt(i) != path.charAt(i)) {
89 return false;
90 }
91 }
92 return true;
93 }
94
95 public static boolean isTaskPath(ZooKeeperWatcher zkw, String path) {
96 String dirname = path.substring(0, path.lastIndexOf('/'));
97 return dirname.equals(zkw.splitLogZNode);
98 }
99
100 public static Path getSplitLogDir(Path rootdir, String tmpname) {
101 return new Path(new Path(rootdir, HConstants.SPLIT_LOGDIR_NAME), tmpname);
102 }
103
104
105 public static String getSplitLogDirTmpComponent(final String worker, String file) {
106 return worker + "_" + ZKSplitLog.encode(file);
107 }
108
109 public static void markCorrupted(Path rootdir, String logFileName,
110 FileSystem fs) {
111 Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
112 try {
113 fs.createNewFile(file);
114 } catch (IOException e) {
115 LOG.warn("Could not flag a log file as corrupted. Failed to create " +
116 file, e);
117 }
118 }
119
120 public static boolean isCorrupted(Path rootdir, String logFileName,
121 FileSystem fs) throws IOException {
122 Path file = new Path(getSplitLogDir(rootdir, logFileName), "corrupt");
123 boolean isCorrupt;
124 isCorrupt = fs.exists(file);
125 return isCorrupt;
126 }
127
128
129
130
131
132
133
134
135
136
137
138
139
140 public static boolean
141 isRegionMarkedRecoveringInZK(ZooKeeperWatcher zkw, String regionEncodedName)
142 throws KeeperException {
143 boolean result = false;
144 String nodePath = ZKUtil.joinZNode(zkw.recoveringRegionsZNode, regionEncodedName);
145
146 byte[] node = ZKUtil.getDataAndWatch(zkw, nodePath);
147 if (node != null) {
148 result = true;
149 }
150 return result;
151 }
152
153
154
155
156
157 public static long parseLastFlushedSequenceIdFrom(final byte[] bytes) {
158 long lastRecordedFlushedSequenceId = -1l;
159 try {
160 lastRecordedFlushedSequenceId = ZKUtil.parseWALPositionFrom(bytes);
161 } catch (DeserializationException e) {
162 lastRecordedFlushedSequenceId = -1l;
163 LOG.warn("Can't parse last flushed sequence Id", e);
164 }
165 return lastRecordedFlushedSequenceId;
166 }
167
168 public static void deleteRecoveringRegionZNodes(ZooKeeperWatcher watcher, List<String> regions) {
169 try {
170 if (regions == null) {
171
172 LOG.debug("Garbage collecting all recovering region znodes");
173 ZKUtil.deleteChildrenRecursively(watcher, watcher.recoveringRegionsZNode);
174 } else {
175 for (String curRegion : regions) {
176 String nodePath = ZKUtil.joinZNode(watcher.recoveringRegionsZNode, curRegion);
177 ZKUtil.deleteNodeRecursively(watcher, nodePath);
178 }
179 }
180 } catch (KeeperException e) {
181 LOG.warn("Cannot remove recovering regions from ZooKeeper", e);
182 }
183 }
184
185
186
187
188
189
190
191
192
193
194 public static RegionStoreSequenceIds getRegionFlushedSequenceId(ZooKeeperWatcher zkw,
195 String serverName, String encodedRegionName) throws IOException {
196
197
198
199
200
201
202
203 RegionStoreSequenceIds result = null;
204 String nodePath = ZKUtil.joinZNode(zkw.recoveringRegionsZNode, encodedRegionName);
205 nodePath = ZKUtil.joinZNode(nodePath, serverName);
206 try {
207 byte[] data;
208 try {
209 data = ZKUtil.getData(zkw, nodePath);
210 } catch (InterruptedException e) {
211 throw new InterruptedIOException();
212 }
213 if (data != null) {
214 result = ZKUtil.parseRegionStoreSequenceIds(data);
215 }
216 } catch (KeeperException e) {
217 throw new IOException("Cannot get lastFlushedSequenceId from ZooKeeper for server="
218 + serverName + "; region=" + encodedRegionName, e);
219 } catch (DeserializationException e) {
220 LOG.warn("Can't parse last flushed sequence Id from znode:" + nodePath, e);
221 }
222 return result;
223 }
224 }