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 }