All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.hbase.regionserver.wal.HLog Maven / Gradle / Ivy

There is a newer version: 3.0.0-beta-1
Show newest version
/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hadoop.hbase.regionserver.wal;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.WALTrailer;
import org.apache.hadoop.io.Writable;

import com.google.common.annotations.VisibleForTesting;


@InterfaceAudience.Private
// TODO: Rename interface to WAL
public interface HLog {
  Log LOG = LogFactory.getLog(HLog.class);

  /** File Extension used while splitting an HLog into regions (HBASE-2312) */
  // TODO: this seems like an implementation detail that does not belong here.
  String SPLITTING_EXT = "-splitting";
  boolean SPLIT_SKIP_ERRORS_DEFAULT = false;
  /** The hbase:meta region's HLog filename extension */
  String META_HLOG_FILE_EXTN = ".meta";

  /**
   * Configuration name of HLog Trailer's warning size. If a waltrailer's size is greater than the
   * configured size, a warning is logged. This is used with Protobuf reader/writer.
   */
  // TODO: Implementation detail.  Why in here?
  String WAL_TRAILER_WARN_SIZE = "hbase.regionserver.waltrailer.warn.size";
  int DEFAULT_WAL_TRAILER_WARN_SIZE = 1024 * 1024; // 1MB

  // TODO: Implemenation detail.  Why in here?
  Pattern EDITFILES_NAME_PATTERN = Pattern.compile("-?[0-9]+");
  String RECOVERED_LOG_TMPFILE_SUFFIX = ".temp";

  interface Reader {

    /**
     * @param fs File system.
     * @param path Path.
     * @param c Configuration.
     * @param s Input stream that may have been pre-opened by the caller; may be null.
     */
    void init(FileSystem fs, Path path, Configuration c, FSDataInputStream s) throws IOException;

    void close() throws IOException;

    Entry next() throws IOException;

    Entry next(Entry reuse) throws IOException;

    void seek(long pos) throws IOException;

    long getPosition() throws IOException;
    void reset() throws IOException;

    /**
     * @return the WALTrailer of the current HLog. It may be null in case of legacy or corrupt WAL
     *         files.
     */
    // TODO: What we need a trailer on WAL for?
    WALTrailer getWALTrailer();
  }

  interface Writer {
    void init(FileSystem fs, Path path, Configuration c, boolean overwritable) throws IOException;

    void close() throws IOException;

    void sync() throws IOException;

    void append(Entry entry) throws IOException;

    long getLength() throws IOException;

    /**
     * Sets HLog's WALTrailer. This trailer is appended at the end of WAL on closing.
     * @param walTrailer trailer to append to WAL.
     */
    void setWALTrailer(WALTrailer walTrailer);
  }

  /**
   * Utility class that lets us keep track of the edit with it's key.
   * Only used when splitting logs.
   */
  // TODO: Remove this Writable.
  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.REPLICATION)
  class Entry implements Writable {
    private WALEdit edit;
    private HLogKey key;

    public Entry() {
      edit = new WALEdit();
      key = new HLogKey();
    }

    /**
     * Constructor for both params
     *
     * @param edit log's edit
     * @param key log's key
     */
    public Entry(HLogKey key, WALEdit edit) {
      super();
      this.key = key;
      this.edit = edit;
    }

    /**
     * Gets the edit
     *
     * @return edit
     */
    public WALEdit getEdit() {
      return edit;
    }

    /**
     * Gets the key
     *
     * @return key
     */
    public HLogKey getKey() {
      return key;
    }

    /**
     * Set compression context for this entry.
     *
     * @param compressionContext
     *          Compression context
     */
    public void setCompressionContext(CompressionContext compressionContext) {
      edit.setCompressionContext(compressionContext);
      key.setCompressionContext(compressionContext);
    }

    @Override
    public String toString() {
      return this.key + "=" + this.edit;
    }

    @Override
    @SuppressWarnings("deprecation")
    public void write(DataOutput dataOutput) throws IOException {
      this.key.write(dataOutput);
      this.edit.write(dataOutput);
    }

    @Override
    public void readFields(DataInput dataInput) throws IOException {
      this.key.readFields(dataInput);
      this.edit.readFields(dataInput);
    }
  }

  /**
   * registers WALActionsListener
   *
   * @param listener
   */
  void registerWALActionsListener(final WALActionsListener listener);

  /**
   * unregisters WALActionsListener
   *
   * @param listener
   */
  boolean unregisterWALActionsListener(final WALActionsListener listener);

  /**
   * @return Current state of the monotonically increasing file id.
   */
  // TODO: Remove.  Implementation detail.
  long getFilenum();

  /**
   * @return the number of HLog files
   */
  int getNumLogFiles();

  /**
   * @return the size of HLog files
   */
  long getLogFileSize();

  // TODO: Log rolling should not be in this interface.
  /**
   * Roll the log writer. That is, start writing log messages to a new file.
   *
   * 

* The implementation is synchronized in order to make sure there's one rollWriter * running at any given time. * * @return If lots of logs, flush the returned regions so next time through we * can clean logs. Returns null if nothing to flush. Names are actual * region names as returned by {@link HRegionInfo#getEncodedName()} * @throws org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException * @throws IOException */ byte[][] rollWriter() throws FailedLogCloseException, IOException; /** * Roll the log writer. That is, start writing log messages to a new file. * *

* The implementation is synchronized in order to make sure there's one rollWriter * running at any given time. * * @param force * If true, force creation of a new writer even if no entries have * been written to the current writer * @return If lots of logs, flush the returned regions so next time through we * can clean logs. Returns null if nothing to flush. Names are actual * region names as returned by {@link HRegionInfo#getEncodedName()} * @throws org.apache.hadoop.hbase.regionserver.wal.FailedLogCloseException * @throws IOException */ byte[][] rollWriter(boolean force) throws FailedLogCloseException, IOException; /** * Shut down the log. * * @throws IOException */ void close() throws IOException; /** * Shut down the log and delete the log directory * * @throws IOException */ void closeAndDelete() throws IOException; /** * Same as appendNoSync(HRegionInfo, TableName, WALEdit, List, long, HTableDescriptor), * except it causes a sync on the log * @param sequenceId of the region. */ @VisibleForTesting public void append(HRegionInfo info, TableName tableName, WALEdit edits, final long now, HTableDescriptor htd, AtomicLong sequenceId) throws IOException; /** * For notification post append to the writer. * @param entries */ void postAppend(final List entries); /** * For notification post writer sync. */ void postSync(); /** * Append a set of edits to the log. Log edits are keyed by (encoded) regionName, rowname, and * log-sequence-id. The HLog is not flushed after this transaction is written to the log. * @param info * @param tableName * @param edits * @param clusterIds The clusters that have consumed the change (for replication) * @param now * @param htd * @param sequenceId of the region * @return txid of this transaction * @throws IOException */ @Deprecated long appendNoSync(HRegionInfo info, TableName tableName, WALEdit edits, List clusterIds, final long now, HTableDescriptor htd, AtomicLong sequenceId, boolean isInMemstore, long nonceGroup, long nonce) throws IOException; // TODO: Do we need all these versions of sync? void hsync() throws IOException; void hflush() throws IOException; void sync() throws IOException; void sync(long txid) throws IOException; /** * WAL keeps track of the sequence numbers that were not yet flushed from memstores * in order to be able to do cleanup. This method tells WAL that some region is about * to flush memstore. * * We stash the oldest seqNum for the region, and let the the next edit inserted in this * region be recorded in {@link #append(HRegionInfo, TableName, WALEdit, long, HTableDescriptor, * AtomicLong)} as new oldest seqnum. * In case of flush being aborted, we put the stashed value back; in case of flush succeeding, * the seqNum of that first edit after start becomes the valid oldest seqNum for this region. * * @return true if the flush can proceed, false in case wal is closing (ususally, when server is * closing) and flush couldn't be started. */ boolean startCacheFlush(final byte[] encodedRegionName); /** * Complete the cache flush. * @param encodedRegionName Encoded region name. */ void completeCacheFlush(final byte[] encodedRegionName); /** * Abort a cache flush. Call if the flush fails. Note that the only recovery * for an aborted flush currently is a restart of the regionserver so the * snapshot content dropped by the failure gets restored to the memstore.v * @param encodedRegionName Encoded region name. */ void abortCacheFlush(byte[] encodedRegionName); /** * @return Coprocessor host. */ WALCoprocessorHost getCoprocessorHost(); /** * Get LowReplication-Roller status * * @return lowReplicationRollEnabled */ // TODO: This is implementation detail? boolean isLowReplicationRollEnabled(); /** Gets the earliest sequence number in the memstore for this particular region. * This can serve as best-effort "recent" WAL number for this region. * @param encodedRegionName The region to get the number for. * @return The number if present, HConstants.NO_SEQNUM if absent. */ long getEarliestMemstoreSeqNum(byte[] encodedRegionName); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy