View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.wal;
21  
22  import java.io.Closeable;
23  import java.io.IOException;
24  import java.util.Set;
25  
26  import org.apache.hadoop.hbase.HConstants;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.HTableDescriptor;
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  import org.apache.hadoop.hbase.classification.InterfaceStability;
31  // imports we use from yet-to-be-moved regionsever.wal
32  import org.apache.hadoop.hbase.regionserver.wal.CompressionContext;
33  import org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException;
34  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
35  import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener;
36  import org.apache.hadoop.hbase.regionserver.wal.WALCoprocessorHost;
37  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
38  
39  /**
40   * A Write Ahead Log (WAL) provides service for reading, writing waledits. This interface provides
41   * APIs for WAL users (such as RegionServer) to use the WAL (do append, sync, etc).
42   *
43   * Note that some internals, such as log rolling and performance evaluation tools, will use
44   * WAL.equals to determine if they have already seen a given WAL.
45   */
46  @InterfaceAudience.Private
47  @InterfaceStability.Evolving
48  public interface WAL extends Closeable {
49  
50    /**
51     * Registers WALActionsListener
52     */
53    void registerWALActionsListener(final WALActionsListener listener);
54  
55    /**
56     * Unregisters WALActionsListener
57     */
58    boolean unregisterWALActionsListener(final WALActionsListener listener);
59  
60    /**
61     * Roll the log writer. That is, start writing log messages to a new file.
62     *
63     * <p>
64     * The implementation is synchronized in order to make sure there's one rollWriter
65     * running at any given time.
66     *
67     * @return If lots of logs, flush the returned regions so next time through we
68     *         can clean logs. Returns null if nothing to flush. Names are actual
69     *         region names as returned by {@link HRegionInfo#getEncodedName()}
70     */
71    byte[][] rollWriter() throws FailedLogCloseException, IOException;
72  
73    /**
74     * Roll the log writer. That is, start writing log messages to a new file.
75     *
76     * <p>
77     * The implementation is synchronized in order to make sure there's one rollWriter
78     * running at any given time.
79     *
80     * @param force
81     *          If true, force creation of a new writer even if no entries have
82     *          been written to the current writer
83     * @return If lots of logs, flush the returned regions so next time through we
84     *         can clean logs. Returns null if nothing to flush. Names are actual
85     *         region names as returned by {@link HRegionInfo#getEncodedName()}
86     */
87    byte[][] rollWriter(boolean force) throws FailedLogCloseException, IOException;
88  
89    /**
90     * Stop accepting new writes. If we have unsynced writes still in buffer, sync them.
91     * Extant edits are left in place in backing storage to be replayed later.
92     */
93    void shutdown() throws IOException;
94  
95    /**
96     * Caller no longer needs any edits from this WAL. Implementers are free to reclaim
97     * underlying resources after this call; i.e. filesystem based WALs can archive or
98     * delete files.
99     */
100   @Override
101   void close() throws IOException;
102 
103   /**
104    * Append a set of edits to the WAL. The WAL is not flushed/sync'd after this transaction
105    * completes BUT on return this edit must have its region edit/sequence id assigned
106    * else it messes up our unification of mvcc and sequenceid.  On return <code>key</code> will
107    * have the region edit/sequence id filled in.
108    * @param info
109    * @param key Modified by this call; we add to it this edits region edit/sequence id.
110    * @param edits Edits to append. MAY CONTAIN NO EDITS for case where we want to get an edit
111    * sequence id that is after all currently appended edits.
112    * @param htd used to give scope for replication TODO refactor out in favor of table name and
113    * info
114    * @param inMemstore Always true except for case where we are writing a compaction completion
115    * record into the WAL; in this case the entry is just so we can finish an unfinished compaction
116    * -- it is not an edit for memstore.
117    * @return Returns a 'transaction id' and <code>key</code> will have the region edit/sequence id
118    * in it.
119    */
120   long append(HTableDescriptor htd, HRegionInfo info, WALKey key, WALEdit edits,
121     boolean inMemstore)
122   throws IOException;
123 
124   /**
125    * Sync what we have in the WAL.
126    * @throws IOException
127    */
128   void sync() throws IOException;
129 
130   /**
131    * Sync the WAL if the txId was not already sync'd.
132    * @param txid Transaction id to sync to.
133    * @throws IOException
134    */
135   void sync(long txid) throws IOException;
136 
137   /**
138    * @param forceSync Flag to force sync rather than flushing to the buffer. Example - Hadoop hflush
139    *          vs hsync.
140    * @throws IOException
141    */
142   void sync(boolean forceSync) throws IOException;
143 
144   /**
145    * @param txid
146    * @param forceSync Flag to force sync rather than flushing to the buffer. Example - Hadoop hflush
147    *          vs hsync.
148    * @throws IOException
149    */
150   void sync(long txid, boolean forceSync) throws IOException;
151 
152   /**
153    * WAL keeps track of the sequence numbers that are as yet not flushed im memstores
154    * in order to be able to do accounting to figure which WALs can be let go. This method tells WAL
155    * that some region is about to flush. The flush can be the whole region or for a column family
156    * of the region only.
157    *
158    * <p>Currently, it is expected that the update lock is held for the region; i.e. no
159    * concurrent appends while we set up cache flush.
160    * @param families Families to flush. May be a subset of all families in the region.
161    * @return Returns {@link HConstants#NO_SEQNUM} if we are flushing the whole region OR if
162    * we are flushing a subset of all families but there are no edits in those families not
163    * being flushed; in other words, this is effectively same as a flush of all of the region
164    * though we were passed a subset of regions. Otherwise, it returns the sequence id of the
165    * oldest/lowest outstanding edit.
166    * @see #completeCacheFlush(byte[])
167    * @see #abortCacheFlush(byte[])
168    */
169   Long startCacheFlush(final byte[] encodedRegionName, Set<byte[]> families);
170 
171   /**
172    * Complete the cache flush.
173    * @param encodedRegionName Encoded region name.
174    * @see #startCacheFlush(byte[], Set)
175    * @see #abortCacheFlush(byte[])
176    */
177   void completeCacheFlush(final byte[] encodedRegionName);
178 
179   /**
180    * Abort a cache flush. Call if the flush fails. Note that the only recovery
181    * for an aborted flush currently is a restart of the regionserver so the
182    * snapshot content dropped by the failure gets restored to the memstore.
183    * @param encodedRegionName Encoded region name.
184    */
185   void abortCacheFlush(byte[] encodedRegionName);
186 
187   /**
188    * @return Coprocessor host.
189    */
190   WALCoprocessorHost getCoprocessorHost();
191 
192   /**
193    * Gets the earliest unflushed sequence id in the memstore for the region.
194    * @param encodedRegionName The region to get the number for.
195    * @return The earliest/lowest/oldest sequence id if present, HConstants.NO_SEQNUM if absent.
196    * @deprecated Since version 1.2.0. Removing because not used and exposes subtle internal
197    * workings. Use {@link #getEarliestMemstoreSeqNum(byte[], byte[])}
198    */
199   @Deprecated
200   long getEarliestMemstoreSeqNum(byte[] encodedRegionName);
201 
202   /**
203    * Gets the earliest unflushed sequence id in the memstore for the store.
204    * @param encodedRegionName The region to get the number for.
205    * @param familyName The family to get the number for.
206    * @return The earliest/lowest/oldest sequence id if present, HConstants.NO_SEQNUM if absent.
207    */
208   long getEarliestMemstoreSeqNum(byte[] encodedRegionName, byte[] familyName);
209 
210   /**
211    * Human readable identifying information about the state of this WAL.
212    * Implementors are encouraged to include information appropriate for debugging.
213    * Consumers are advised not to rely on the details of the returned String; it does
214    * not have a defined structure.
215    */
216   @Override
217   String toString();
218 
219   /**
220    * When outside clients need to consume persisted WALs, they rely on a provided
221    * Reader.
222    */
223   interface Reader extends Closeable {
224     Entry next() throws IOException;
225     Entry next(Entry reuse) throws IOException;
226     void seek(long pos) throws IOException;
227     long getPosition() throws IOException;
228     void reset() throws IOException;
229   }
230 
231   /**
232    * Utility class that lets us keep track of the edit with it's key.
233    */
234   class Entry {
235     private WALEdit edit;
236     private WALKey key;
237 
238     public Entry() {
239       edit = new WALEdit();
240       // we use HLogKey here instead of WALKey directly to support legacy coprocessors.
241       key = new HLogKey();
242     }
243 
244     /**
245      * Constructor for both params
246      *
247      * @param edit log's edit
248      * @param key log's key
249      */
250     public Entry(WALKey key, WALEdit edit) {
251       super();
252       this.key = key;
253       this.edit = edit;
254     }
255 
256     /**
257      * Gets the edit
258      *
259      * @return edit
260      */
261     public WALEdit getEdit() {
262       return edit;
263     }
264 
265     /**
266      * Gets the key
267      *
268      * @return key
269      */
270     public WALKey getKey() {
271       return key;
272     }
273 
274     /**
275      * Set compression context for this entry.
276      *
277      * @param compressionContext
278      *          Compression context
279      */
280     public void setCompressionContext(CompressionContext compressionContext) {
281       edit.setCompressionContext(compressionContext);
282       key.setCompressionContext(compressionContext);
283     }
284 
285     @Override
286     public String toString() {
287       return this.key + "=" + this.edit;
288     }
289 
290   }
291 
292 }