View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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  // imports for things that haven't moved from regionserver.wal yet.
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   * No-op implementation of {@link WALProvider} used when the WAL is disabled.
46   *
47   * Should only be used when severe data loss is acceptable.
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 }