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.List;
22 import java.util.concurrent.CopyOnWriteArrayList;
23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.concurrent.atomic.AtomicLong;
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.Cell;
33 import org.apache.hadoop.hbase.CellUtil;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.util.FSUtils;
38
39
40 import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
41 import org.apache.hadoop.hbase.regionserver.wal.WALCoprocessorHost;
42 import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
43
44
45
46
47
48
49
50 @InterfaceAudience.Private
51 class DisabledWALProvider implements WALProvider {
52
53 private static final Log LOG = LogFactory.getLog(DisabledWALProvider.class);
54
55 WAL disabled;
56
57 @Override
58 public void init(final WALFactory factory, final Configuration conf,
59 final List<WALActionsListener> listeners, String providerId) throws IOException {
60 if (null != disabled) {
61 throw new IllegalStateException("WALProvider.init should only be called once.");
62 }
63 if (null == providerId) {
64 providerId = "defaultDisabled";
65 }
66 disabled = new DisabledWAL(new Path(FSUtils.getRootDir(conf), providerId), conf, null);
67 }
68
69 @Override
70 public WAL getWAL(final byte[] identifier) throws IOException {
71 return disabled;
72 }
73
74 @Override
75 public void close() throws IOException {
76 disabled.close();
77 }
78
79 @Override
80 public void shutdown() throws IOException {
81 disabled.shutdown();
82 }
83
84 private static class DisabledWAL implements WAL {
85 protected final List<WALActionsListener> listeners =
86 new CopyOnWriteArrayList<WALActionsListener>();
87 protected final Path path;
88 protected final WALCoprocessorHost coprocessorHost;
89 protected final AtomicBoolean closed = new AtomicBoolean(false);
90
91 public DisabledWAL(final Path path, final Configuration conf,
92 final List<WALActionsListener> listeners) {
93 this.coprocessorHost = new WALCoprocessorHost(this, conf);
94 this.path = path;
95 if (null != listeners) {
96 for(WALActionsListener listener : listeners) {
97 registerWALActionsListener(listener);
98 }
99 }
100 }
101
102 @Override
103 public void registerWALActionsListener(final WALActionsListener listener) {
104 listeners.add(listener);
105 }
106
107 @Override
108 public boolean unregisterWALActionsListener(final WALActionsListener listener) {
109 return listeners.remove(listener);
110 }
111
112 @Override
113 public byte[][] rollWriter() {
114 if (!listeners.isEmpty()) {
115 for (WALActionsListener listener : listeners) {
116 listener.logRollRequested(false);
117 }
118 for (WALActionsListener listener : listeners) {
119 try {
120 listener.preLogRoll(path, path);
121 } catch (IOException exception) {
122 LOG.debug("Ignoring exception from listener.", exception);
123 }
124 }
125 for (WALActionsListener listener : listeners) {
126 try {
127 listener.postLogRoll(path, path);
128 } catch (IOException exception) {
129 LOG.debug("Ignoring exception from listener.", exception);
130 }
131 }
132 }
133 return null;
134 }
135
136 @Override
137 public byte[][] rollWriter(boolean force) {
138 return rollWriter();
139 }
140
141 @Override
142 public void shutdown() {
143 if(closed.compareAndSet(false, true)) {
144 if (!this.listeners.isEmpty()) {
145 for (WALActionsListener listener : this.listeners) {
146 listener.logCloseRequested();
147 }
148 }
149 }
150 }
151
152 @Override
153 public void close() {
154 shutdown();
155 }
156
157 @Override
158 public long append(HTableDescriptor htd, HRegionInfo info, WALKey key, WALEdit edits,
159 AtomicLong sequenceId, boolean inMemstore, List<Cell> memstoreKVs) {
160 if (!this.listeners.isEmpty()) {
161 final long start = System.nanoTime();
162 long len = 0;
163 for (Cell cell : edits.getCells()) {
164 len += CellUtil.estimatedSerializedSizeOf(cell);
165 }
166 final long elapsed = (System.nanoTime() - start)/1000000l;
167 for (WALActionsListener listener : this.listeners) {
168 listener.postAppend(len, elapsed);
169 }
170 }
171 return -1;
172 }
173
174 @Override
175 public void sync() {
176 if (!this.listeners.isEmpty()) {
177 for (WALActionsListener listener : this.listeners) {
178 listener.postSync(0l, 0);
179 }
180 }
181 }
182
183 @Override
184 public void sync(long txid) {
185 sync();
186 }
187
188 @Override
189 public boolean startCacheFlush(final byte[] encodedRegionName) {
190 return !(closed.get());
191 }
192
193 @Override
194 public void completeCacheFlush(final byte[] encodedRegionName) {
195 }
196
197 @Override
198 public void abortCacheFlush(byte[] encodedRegionName) {
199 }
200
201 @Override
202 public WALCoprocessorHost getCoprocessorHost() {
203 return coprocessorHost;
204 }
205
206 @Override
207 public long getEarliestMemstoreSeqNum(byte[] encodedRegionName) {
208 return HConstants.NO_SEQNUM;
209 }
210
211 @Override
212 public String toString() {
213 return "WAL disabled.";
214 }
215 }
216 }