1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.wal;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Set;
24 import java.util.concurrent.CopyOnWriteArrayList;
25 import java.util.concurrent.atomic.AtomicBoolean;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.conf.Configuration;
29 import org.apache.hadoop.fs.Path;
30 import org.apache.hadoop.hbase.Cell;
31 import org.apache.hadoop.hbase.CellUtil;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.HRegionInfo;
34 import org.apache.hadoop.hbase.HTableDescriptor;
35 import org.apache.hadoop.hbase.classification.InterfaceAudience;
36
37 import org.apache.hadoop.hbase.regionserver.MultiVersionConcurrencyControl.WriteEntry;
38 import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
39 import org.apache.hadoop.hbase.regionserver.wal.WALCoprocessorHost;
40 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
41 import org.apache.hadoop.hbase.util.FSUtils;
42
43
44
45
46
47
48
49 @InterfaceAudience.Private
50 class DisabledWALProvider implements WALProvider {
51
52 private static final Log LOG = LogFactory.getLog(DisabledWALProvider.class);
53
54 WAL disabled;
55
56 @Override
57 public void init(final WALFactory factory, final Configuration conf,
58 final List<WALActionsListener> listeners, String providerId) throws IOException {
59 if (null != disabled) {
60 throw new IllegalStateException("WALProvider.init should only be called once.");
61 }
62 if (null == providerId) {
63 providerId = "defaultDisabled";
64 }
65 disabled = new DisabledWAL(new Path(FSUtils.getWALRootDir(conf), providerId), conf, null);
66 }
67
68 @Override
69 public List<WAL> getWALs() throws IOException {
70 List<WAL> wals = new ArrayList<WAL>();
71 wals.add(disabled);
72 return wals;
73 }
74
75 @Override
76 public WAL getWAL(final byte[] identifier, byte[] namespace) throws IOException {
77 return disabled;
78 }
79
80 @Override
81 public void close() throws IOException {
82 disabled.close();
83 }
84
85 @Override
86 public void shutdown() throws IOException {
87 disabled.shutdown();
88 }
89
90 private static class DisabledWAL implements WAL {
91 protected final List<WALActionsListener> listeners =
92 new CopyOnWriteArrayList<WALActionsListener>();
93 protected final Path path;
94 protected final WALCoprocessorHost coprocessorHost;
95 protected final AtomicBoolean closed = new AtomicBoolean(false);
96
97 public DisabledWAL(final Path path, final Configuration conf,
98 final List<WALActionsListener> listeners) {
99 this.coprocessorHost = new WALCoprocessorHost(this, conf);
100 this.path = path;
101 if (null != listeners) {
102 for(WALActionsListener listener : listeners) {
103 registerWALActionsListener(listener);
104 }
105 }
106 }
107
108 @Override
109 public void registerWALActionsListener(final WALActionsListener listener) {
110 listeners.add(listener);
111 }
112
113 @Override
114 public boolean unregisterWALActionsListener(final WALActionsListener listener) {
115 return listeners.remove(listener);
116 }
117
118 @Override
119 public byte[][] rollWriter() {
120 if (!listeners.isEmpty()) {
121 for (WALActionsListener listener : listeners) {
122 listener.logRollRequested(WALActionsListener.RollRequestReason.ERROR);
123 }
124 for (WALActionsListener listener : listeners) {
125 try {
126 listener.preLogRoll(path, path);
127 } catch (IOException exception) {
128 LOG.debug("Ignoring exception from listener.", exception);
129 }
130 }
131 for (WALActionsListener listener : listeners) {
132 try {
133 listener.postLogRoll(path, path);
134 } catch (IOException exception) {
135 LOG.debug("Ignoring exception from listener.", exception);
136 }
137 }
138 }
139 return null;
140 }
141
142 @Override
143 public byte[][] rollWriter(boolean force) {
144 return rollWriter();
145 }
146
147 @Override
148 public void shutdown() {
149 if(closed.compareAndSet(false, true)) {
150 if (!this.listeners.isEmpty()) {
151 for (WALActionsListener listener : this.listeners) {
152 listener.logCloseRequested();
153 }
154 }
155 }
156 }
157
158 @Override
159 public void close() {
160 shutdown();
161 }
162
163 @Override
164 public long append(HTableDescriptor htd, HRegionInfo info, WALKey key, WALEdit edits,
165 boolean inMemstore) throws IOException {
166 WriteEntry writeEntry = key.getMvcc().begin();
167 if (!edits.isReplay()) {
168 for (Cell cell : edits.getCells()) {
169 CellUtil.setSequenceId(cell, writeEntry.getWriteNumber());
170 }
171 }
172 key.setWriteEntry(writeEntry);
173 if (!this.listeners.isEmpty()) {
174 final long start = System.nanoTime();
175 long len = 0;
176 for (Cell cell : edits.getCells()) {
177 len += CellUtil.estimatedSerializedSizeOf(cell);
178 }
179 final long elapsed = (System.nanoTime() - start)/1000000l;
180 for (WALActionsListener listener : this.listeners) {
181 listener.postAppend(len, elapsed, key, edits);
182 }
183 }
184 return -1;
185 }
186
187 @Override
188 public void sync() {
189 if (!this.listeners.isEmpty()) {
190 for (WALActionsListener listener : this.listeners) {
191 listener.postSync(0l, 0);
192 }
193 }
194 }
195
196 @Override
197 public void sync(long txid) {
198 sync();
199 }
200
201 @Override
202 public void sync(boolean forceSync) throws IOException {
203 sync();
204 }
205
206 @Override
207 public void sync(long txid, boolean forceSync) throws IOException {
208 sync(txid);
209 }
210
211 @Override
212 public Long startCacheFlush(final byte[] encodedRegionName, Set<byte[]> flushedFamilyNames) {
213 if (closed.get()) return null;
214 return HConstants.NO_SEQNUM;
215 }
216
217 @Override
218 public void completeCacheFlush(final byte[] encodedRegionName) {
219 }
220
221 @Override
222 public void abortCacheFlush(byte[] encodedRegionName) {
223 }
224
225 @Override
226 public WALCoprocessorHost getCoprocessorHost() {
227 return coprocessorHost;
228 }
229
230 @Override
231 public long getEarliestMemstoreSeqNum(byte[] encodedRegionName) {
232 return HConstants.NO_SEQNUM;
233 }
234
235 @Override
236 public long getEarliestMemstoreSeqNum(byte[] encodedRegionName, byte[] familyName) {
237 return HConstants.NO_SEQNUM;
238 }
239
240 @Override
241 public String toString() {
242 return "WAL disabled.";
243 }
244 }
245
246 @Override
247 public long getNumLogFiles() {
248 return 0;
249 }
250
251 @Override
252 public long getLogFileSize() {
253 return 0;
254 }
255 }