1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver.wal;
21
22 import java.io.IOException;
23 import java.util.NavigableSet;
24 import java.util.TreeSet;
25 import java.util.regex.Matcher;
26 import java.util.regex.Pattern;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.fs.FileStatus;
32 import org.apache.hadoop.fs.FileSystem;
33 import org.apache.hadoop.fs.Path;
34 import org.apache.hadoop.fs.PathFilter;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.HConstants;
37 import org.apache.hadoop.hbase.HRegionInfo;
38 import org.apache.hadoop.hbase.HTableDescriptor;
39 import org.apache.hadoop.hbase.ServerName;
40 import org.apache.hadoop.hbase.protobuf.generated.WALProtos.CompactionDescriptor;
41 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
42 import org.apache.hadoop.hbase.util.FSUtils;
43
44 import com.google.protobuf.TextFormat;
45
46 public class HLogUtil {
47 static final Log LOG = LogFactory.getLog(HLogUtil.class);
48
49
50
51
52 private static final Pattern pattern =
53 Pattern.compile(".*\\.\\d*("+HLog.META_HLOG_FILE_EXTN+")*");
54
55
56
57
58
59
60
61 public static boolean validateHLogFilename(String filename) {
62 return pattern.matcher(filename).matches();
63 }
64
65
66
67
68
69
70
71
72
73
74
75 public static String getHLogDirectoryName(final String serverName) {
76 StringBuilder dirName = new StringBuilder(HConstants.HREGION_LOGDIR_NAME);
77 dirName.append("/");
78 dirName.append(serverName);
79 return dirName.toString();
80 }
81
82
83
84
85
86
87
88 public static Path getRegionDirRecoveredEditsDir(final Path regiondir) {
89 return new Path(regiondir, HConstants.RECOVERED_EDITS_DIR);
90 }
91
92
93
94
95
96
97
98
99
100
101 public static Path moveAsideBadEditsFile(final FileSystem fs, final Path edits)
102 throws IOException {
103 Path moveAsideName = new Path(edits.getParent(), edits.getName() + "."
104 + System.currentTimeMillis());
105 if (!fs.rename(edits, moveAsideName)) {
106 LOG.warn("Rename failed from " + edits + " to " + moveAsideName);
107 }
108 return moveAsideName;
109 }
110
111
112
113
114
115
116
117
118
119 public static ServerName getServerNameFromHLogDirectoryName(
120 Configuration conf, String path) throws IOException {
121 if (path == null
122 || path.length() <= HConstants.HREGION_LOGDIR_NAME.length()) {
123 return null;
124 }
125
126 if (conf == null) {
127 throw new IllegalArgumentException("parameter conf must be set");
128 }
129
130 final String rootDir = conf.get(HConstants.HBASE_DIR);
131 if (rootDir == null || rootDir.isEmpty()) {
132 throw new IllegalArgumentException(HConstants.HBASE_DIR
133 + " key not found in conf.");
134 }
135
136 final StringBuilder startPathSB = new StringBuilder(rootDir);
137 if (!rootDir.endsWith("/"))
138 startPathSB.append('/');
139 startPathSB.append(HConstants.HREGION_LOGDIR_NAME);
140 if (!HConstants.HREGION_LOGDIR_NAME.endsWith("/"))
141 startPathSB.append('/');
142 final String startPath = startPathSB.toString();
143
144 String fullPath;
145 try {
146 fullPath = FileSystem.get(conf).makeQualified(new Path(path)).toString();
147 } catch (IllegalArgumentException e) {
148 LOG.info("Call to makeQualified failed on " + path + " " + e.getMessage());
149 return null;
150 }
151
152 if (!fullPath.startsWith(startPath)) {
153 return null;
154 }
155
156 final String serverNameAndFile = fullPath.substring(startPath.length());
157
158 if (serverNameAndFile.indexOf('/') < "a,0,0".length()) {
159
160 return null;
161 }
162
163 Path p = new Path(path);
164 return getServerNameFromHLogDirectoryName(p);
165 }
166
167
168
169
170
171
172
173
174 public static ServerName getServerNameFromHLogDirectoryName(Path logFile) {
175 Path logDir = logFile.getParent();
176 String logDirName = logDir.getName();
177 if (logDirName.equals(HConstants.HREGION_LOGDIR_NAME)) {
178 logDir = logFile;
179 logDirName = logDir.getName();
180 }
181 ServerName serverName = null;
182 if (logDirName.endsWith(HLog.SPLITTING_EXT)) {
183 logDirName = logDirName.substring(0, logDirName.length() - HLog.SPLITTING_EXT.length());
184 }
185 try {
186 serverName = ServerName.parseServerName(logDirName);
187 } catch (IllegalArgumentException ex) {
188 serverName = null;
189 LOG.warn("Invalid log file path=" + logFile, ex);
190 }
191 if (serverName != null && serverName.getStartcode() < 0) {
192 LOG.warn("Invalid log file path=" + logFile);
193 return null;
194 }
195 return serverName;
196 }
197
198
199
200
201
202
203
204
205
206
207 public static NavigableSet<Path> getSplitEditFilesSorted(final FileSystem fs,
208 final Path regiondir) throws IOException {
209 NavigableSet<Path> filesSorted = new TreeSet<Path>();
210 Path editsdir = HLogUtil.getRegionDirRecoveredEditsDir(regiondir);
211 if (!fs.exists(editsdir))
212 return filesSorted;
213 FileStatus[] files = FSUtils.listStatus(fs, editsdir, new PathFilter() {
214 @Override
215 public boolean accept(Path p) {
216 boolean result = false;
217 try {
218
219
220
221
222 Matcher m = HLog.EDITFILES_NAME_PATTERN.matcher(p.getName());
223 result = fs.isFile(p) && m.matches();
224
225
226 if (p.getName().endsWith(HLog.RECOVERED_LOG_TMPFILE_SUFFIX)) {
227 result = false;
228 }
229 } catch (IOException e) {
230 LOG.warn("Failed isFile check on " + p);
231 }
232 return result;
233 }
234 });
235 if (files == null)
236 return filesSorted;
237 for (FileStatus status : files) {
238 filesSorted.add(status.getPath());
239 }
240 return filesSorted;
241 }
242
243 public static boolean isMetaFile(Path p) {
244 return isMetaFile(p.getName());
245 }
246
247 public static boolean isMetaFile(String p) {
248 if (p != null && p.endsWith(HLog.META_HLOG_FILE_EXTN)) {
249 return true;
250 }
251 return false;
252 }
253
254
255
256
257
258
259
260 public static void writeCompactionMarker(HLog log, HTableDescriptor htd, HRegionInfo info,
261 final CompactionDescriptor c) throws IOException {
262 WALEdit e = WALEdit.createCompaction(c);
263 log.append(info, TableName.valueOf(c.getTableName().toByteArray()), e,
264 EnvironmentEdgeManager.currentTimeMillis(), htd, false);
265 if (LOG.isTraceEnabled()) {
266 LOG.trace("Appended compaction marker " + TextFormat.shortDebugString(c));
267 }
268 }
269 }