001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.wal; 019 020import java.io.Closeable; 021import java.io.IOException; 022import java.util.Map; 023import java.util.Set; 024import org.apache.hadoop.hbase.HConstants; 025import org.apache.hadoop.hbase.client.RegionInfo; 026import org.apache.hadoop.hbase.regionserver.wal.CompressionContext; 027import org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException; 028import org.apache.hadoop.hbase.regionserver.wal.WALActionsListener; 029import org.apache.hadoop.hbase.regionserver.wal.WALCoprocessorHost; 030import org.apache.hadoop.hbase.replication.regionserver.WALFileLengthProvider; 031import org.apache.yetus.audience.InterfaceAudience; 032import org.apache.yetus.audience.InterfaceStability; 033 034import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 035 036/** 037 * A Write Ahead Log (WAL) provides service for reading, writing waledits. This interface provides 038 * APIs for WAL users (such as RegionServer) to use the WAL (do append, sync, etc). 039 * 040 * Note that some internals, such as log rolling and performance evaluation tools, will use 041 * WAL.equals to determine if they have already seen a given WAL. 042 */ 043@InterfaceAudience.Private 044@InterfaceStability.Evolving 045public interface WAL extends Closeable, WALFileLengthProvider { 046 047 /** 048 * Registers WALActionsListener 049 */ 050 void registerWALActionsListener(final WALActionsListener listener); 051 052 /** 053 * Unregisters WALActionsListener 054 */ 055 boolean unregisterWALActionsListener(final WALActionsListener listener); 056 057 /** 058 * Roll the log writer. That is, start writing log messages to a new file. 059 * 060 * <p> 061 * The implementation is synchronized in order to make sure there's one rollWriter 062 * running at any given time. 063 * 064 * @return If lots of logs, flush the returned regions so next time through we 065 * can clean logs. Returns null if nothing to flush. Names are actual 066 * region names as returned by {@link RegionInfo#getEncodedName()} 067 */ 068 byte[][] rollWriter() throws FailedLogCloseException, IOException; 069 070 /** 071 * Roll the log writer. That is, start writing log messages to a new file. 072 * 073 * <p> 074 * The implementation is synchronized in order to make sure there's one rollWriter 075 * running at any given time. 076 * 077 * @param force 078 * If true, force creation of a new writer even if no entries have 079 * been written to the current writer 080 * @return If lots of logs, flush the returned regions so next time through we 081 * can clean logs. Returns null if nothing to flush. Names are actual 082 * region names as returned by {@link RegionInfo#getEncodedName()} 083 */ 084 byte[][] rollWriter(boolean force) throws FailedLogCloseException, IOException; 085 086 /** 087 * Stop accepting new writes. If we have unsynced writes still in buffer, sync them. 088 * Extant edits are left in place in backing storage to be replayed later. 089 */ 090 void shutdown() throws IOException; 091 092 /** 093 * Caller no longer needs any edits from this WAL. Implementers are free to reclaim 094 * underlying resources after this call; i.e. filesystem based WALs can archive or 095 * delete files. 096 */ 097 @Override 098 void close() throws IOException; 099 100 /** 101 * Append a set of edits to the WAL. The WAL is not flushed/sync'd after this transaction 102 * completes BUT on return this edit must have its region edit/sequence id assigned 103 * else it messes up our unification of mvcc and sequenceid. On return <code>key</code> will 104 * have the region edit/sequence id filled in. 105 * @param info the regioninfo associated with append 106 * @param key Modified by this call; we add to it this edits region edit/sequence id. 107 * @param edits Edits to append. MAY CONTAIN NO EDITS for case where we want to get an edit 108 * sequence id that is after all currently appended edits. 109 * @param inMemstore Always true except for case where we are writing a compaction completion 110 * record into the WAL; in this case the entry is just so we can finish an unfinished compaction 111 * -- it is not an edit for memstore. 112 * @return Returns a 'transaction id' and <code>key</code> will have the region edit/sequence id 113 * in it. 114 */ 115 long append(RegionInfo info, WALKeyImpl key, WALEdit edits, boolean inMemstore) throws IOException; 116 117 /** 118 * updates the seuence number of a specific store. 119 * depending on the flag: replaces current seq number if the given seq id is bigger, 120 * or even if it is lower than existing one 121 * @param encodedRegionName 122 * @param familyName 123 * @param sequenceid 124 * @param onlyIfGreater 125 */ 126 void updateStore(byte[] encodedRegionName, byte[] familyName, Long sequenceid, 127 boolean onlyIfGreater); 128 129 /** 130 * Sync what we have in the WAL. 131 * @throws IOException 132 */ 133 void sync() throws IOException; 134 135 /** 136 * Sync the WAL if the txId was not already sync'd. 137 * @param txid Transaction id to sync to. 138 * @throws IOException 139 */ 140 void sync(long txid) throws IOException; 141 142 /** 143 * @param forceSync Flag to force sync rather than flushing to the buffer. Example - Hadoop hflush 144 * vs hsync. 145 */ 146 default void sync(boolean forceSync) throws IOException { 147 sync(); 148 } 149 150 /** 151 * @param txid Transaction id to sync to. 152 * @param forceSync Flag to force sync rather than flushing to the buffer. Example - Hadoop hflush 153 * vs hsync. 154 */ 155 default void sync(long txid, boolean forceSync) throws IOException { 156 sync(txid); 157 } 158 159 /** 160 * WAL keeps track of the sequence numbers that are as yet not flushed im memstores 161 * in order to be able to do accounting to figure which WALs can be let go. This method tells WAL 162 * that some region is about to flush. The flush can be the whole region or for a column family 163 * of the region only. 164 * 165 * <p>Currently, it is expected that the update lock is held for the region; i.e. no 166 * concurrent appends while we set up cache flush. 167 * @param families Families to flush. May be a subset of all families in the region. 168 * @return Returns {@link HConstants#NO_SEQNUM} if we are flushing the whole region OR if 169 * we are flushing a subset of all families but there are no edits in those families not 170 * being flushed; in other words, this is effectively same as a flush of all of the region 171 * though we were passed a subset of regions. Otherwise, it returns the sequence id of the 172 * oldest/lowest outstanding edit. 173 * @see #completeCacheFlush(byte[]) 174 * @see #abortCacheFlush(byte[]) 175 */ 176 Long startCacheFlush(final byte[] encodedRegionName, Set<byte[]> families); 177 178 Long startCacheFlush(final byte[] encodedRegionName, Map<byte[], Long> familyToSeq); 179 180 /** 181 * Complete the cache flush. 182 * @param encodedRegionName Encoded region name. 183 * @see #startCacheFlush(byte[], Set) 184 * @see #abortCacheFlush(byte[]) 185 */ 186 void completeCacheFlush(final byte[] encodedRegionName); 187 188 /** 189 * Abort a cache flush. Call if the flush fails. Note that the only recovery 190 * for an aborted flush currently is a restart of the regionserver so the 191 * snapshot content dropped by the failure gets restored to the memstore. 192 * @param encodedRegionName Encoded region name. 193 */ 194 void abortCacheFlush(byte[] encodedRegionName); 195 196 /** 197 * @return Coprocessor host. 198 */ 199 WALCoprocessorHost getCoprocessorHost(); 200 201 /** 202 * Gets the earliest unflushed sequence id in the memstore for the region. 203 * @param encodedRegionName The region to get the number for. 204 * @return The earliest/lowest/oldest sequence id if present, HConstants.NO_SEQNUM if absent. 205 * @deprecated Since version 1.2.0. Removing because not used and exposes subtle internal 206 * workings. Use {@link #getEarliestMemStoreSeqNum(byte[], byte[])} 207 */ 208 @VisibleForTesting 209 @Deprecated 210 long getEarliestMemStoreSeqNum(byte[] encodedRegionName); 211 212 /** 213 * Gets the earliest unflushed sequence id in the memstore for the store. 214 * @param encodedRegionName The region to get the number for. 215 * @param familyName The family to get the number for. 216 * @return The earliest/lowest/oldest sequence id if present, HConstants.NO_SEQNUM if absent. 217 */ 218 long getEarliestMemStoreSeqNum(byte[] encodedRegionName, byte[] familyName); 219 220 /** 221 * Human readable identifying information about the state of this WAL. 222 * Implementors are encouraged to include information appropriate for debugging. 223 * Consumers are advised not to rely on the details of the returned String; it does 224 * not have a defined structure. 225 */ 226 @Override 227 String toString(); 228 229 /** 230 * When outside clients need to consume persisted WALs, they rely on a provided 231 * Reader. 232 */ 233 interface Reader extends Closeable { 234 Entry next() throws IOException; 235 Entry next(Entry reuse) throws IOException; 236 void seek(long pos) throws IOException; 237 long getPosition() throws IOException; 238 void reset() throws IOException; 239 } 240 241 /** 242 * Utility class that lets us keep track of the edit with it's key. 243 */ 244 class Entry { 245 private final WALEdit edit; 246 private final WALKeyImpl key; 247 248 public Entry() { 249 this(new WALKeyImpl(), new WALEdit()); 250 } 251 252 /** 253 * Constructor for both params 254 * 255 * @param edit log's edit 256 * @param key log's key 257 */ 258 public Entry(WALKeyImpl key, WALEdit edit) { 259 this.key = key; 260 this.edit = edit; 261 } 262 263 /** 264 * Gets the edit 265 * 266 * @return edit 267 */ 268 public WALEdit getEdit() { 269 return edit; 270 } 271 272 /** 273 * Gets the key 274 * 275 * @return key 276 */ 277 public WALKeyImpl getKey() { 278 return key; 279 } 280 281 /** 282 * Set compression context for this entry. 283 * 284 * @param compressionContext 285 * Compression context 286 * @deprecated deparcated since hbase 2.1.0 287 */ 288 @Deprecated 289 public void setCompressionContext(CompressionContext compressionContext) { 290 key.setCompressionContext(compressionContext); 291 } 292 293 @Override 294 public String toString() { 295 return this.key + "=" + this.edit; 296 } 297 } 298}