1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.wal;
20
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.classification.InterfaceAudience;
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.HConstants;
33 import org.apache.hadoop.hbase.util.FSUtils;
34 import org.apache.hadoop.hbase.wal.WAL.Entry;
35
36 import static org.apache.hadoop.hbase.wal.DefaultWALProvider.DEFAULT_PROVIDER_ID;
37 import static org.apache.hadoop.hbase.wal.DefaultWALProvider.META_WAL_PROVIDER_ID;
38 import static org.apache.hadoop.hbase.wal.DefaultWALProvider.WAL_FILE_NAME_DELIMITER;
39
40
41
42 import org.apache.hadoop.hbase.regionserver.wal.FSHLog;
43 import org.apache.hadoop.hbase.regionserver.wal.ProtobufLogWriter;
44 import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
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
73 @InterfaceAudience.Private
74 public class IOTestProvider implements WALProvider {
75 private static final Log LOG = LogFactory.getLog(IOTestProvider.class);
76
77 private static final String ALLOWED_OPERATIONS = "hbase.wal.iotestprovider.operations";
78 private enum AllowedOperations {
79 all,
80 append,
81 sync,
82 fileroll,
83 none;
84 }
85
86 private FSHLog log = null;
87
88
89
90
91
92
93
94
95 @Override
96 public void init(final WALFactory factory, final Configuration conf,
97 final List<WALActionsListener> listeners, String providerId) throws IOException {
98 if (null != log) {
99 throw new IllegalStateException("WALProvider.init should only be called once.");
100 }
101 if (null == providerId) {
102 providerId = DEFAULT_PROVIDER_ID;
103 }
104 final String logPrefix = factory.factoryId + WAL_FILE_NAME_DELIMITER + providerId;
105 log = new IOTestWAL(FSUtils.getWALFileSystem(conf), FSUtils.getWALRootDir(conf),
106 DefaultWALProvider.getWALDirectoryName(factory.factoryId),
107 HConstants.HREGION_OLDLOGDIR_NAME, conf, listeners,
108 true, logPrefix, META_WAL_PROVIDER_ID.equals(providerId) ? META_WAL_PROVIDER_ID : null);
109 }
110
111 @Override
112 public List<WAL> getWALs() throws IOException {
113 List<WAL> wals = new ArrayList<WAL>();
114 wals.add(log);
115 return wals;
116 }
117
118 @Override
119 public WAL getWAL(final byte[] identifier, byte[] namespace) throws IOException {
120 return log;
121 }
122
123 @Override
124 public void close() throws IOException {
125 log.close();
126 }
127
128 @Override
129 public void shutdown() throws IOException {
130 log.shutdown();
131 }
132
133 private static class IOTestWAL extends FSHLog {
134
135 private final boolean doFileRolls;
136
137
138 private final boolean initialized;
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164 public IOTestWAL(final FileSystem fs, final Path rootDir, final String logDir,
165 final String archiveDir, final Configuration conf,
166 final List<WALActionsListener> listeners,
167 final boolean failIfWALExists, final String prefix, final String suffix)
168 throws IOException {
169 super(fs, rootDir, logDir, archiveDir, conf, listeners, failIfWALExists, prefix, suffix);
170 Collection<String> operations = conf.getStringCollection(ALLOWED_OPERATIONS);
171 doFileRolls = operations.isEmpty() || operations.contains(AllowedOperations.all.name()) ||
172 operations.contains(AllowedOperations.fileroll.name());
173 initialized = true;
174 LOG.info("Initialized with file rolling " + (doFileRolls ? "enabled" : "disabled"));
175 }
176
177 private Writer noRollsWriter;
178
179
180
181 @Override
182 protected Writer createWriterInstance(final Path path) throws IOException {
183
184
185
186 if (!initialized || doFileRolls) {
187 LOG.info("creating new writer instance.");
188 final ProtobufLogWriter writer = new IOTestWriter();
189 writer.init(fs, path, conf, false);
190 if (!initialized) {
191 LOG.info("storing initial writer instance in case file rolling isn't allowed.");
192 noRollsWriter = writer;
193 }
194 return writer;
195 } else {
196 LOG.info("WAL rolling disabled, returning the first writer.");
197
198
199 return noRollsWriter;
200 }
201 }
202 }
203
204
205
206
207 private static class IOTestWriter extends ProtobufLogWriter {
208 private boolean doAppends;
209 private boolean doSyncs;
210
211 @Override
212 public void init(FileSystem fs, Path path, Configuration conf, boolean overwritable) throws IOException {
213 Collection<String> operations = conf.getStringCollection(ALLOWED_OPERATIONS);
214 if (operations.isEmpty() || operations.contains(AllowedOperations.all.name())) {
215 doAppends = doSyncs = true;
216 } else if (operations.contains(AllowedOperations.none.name())) {
217 doAppends = doSyncs = false;
218 } else {
219 doAppends = operations.contains(AllowedOperations.append.name());
220 doSyncs = operations.contains(AllowedOperations.sync.name());
221 }
222 LOG.info("IOTestWriter initialized with appends " + (doAppends ? "enabled" : "disabled") +
223 " and syncs " + (doSyncs ? "enabled" : "disabled"));
224 super.init(fs, path, conf, overwritable);
225 }
226
227 @Override
228 public void append(Entry entry) throws IOException {
229 if (doAppends) {
230 super.append(entry);
231 }
232 }
233
234 @Override
235 public void sync() throws IOException {
236 if (doSyncs) {
237 super.sync();
238 }
239 }
240 }
241
242 @Override
243 public long getNumLogFiles() {
244 return this.log.getNumLogFiles();
245 }
246
247 @Override
248 public long getLogFileSize() {
249 return this.log.getLogFileSize();
250 }
251 }