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.regionserver.wal;
21  
22  import java.io.IOException;
23  import java.util.ArrayList;
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.Cell;
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  import org.apache.hadoop.hbase.HRegionInfo;
31  import org.apache.hadoop.hbase.HTableDescriptor;
32  import org.apache.hadoop.hbase.TableName;
33  import org.apache.hadoop.hbase.protobuf.generated.WALProtos;
34  import org.apache.hadoop.hbase.protobuf.generated.WALProtos.CompactionDescriptor;
35  import org.apache.hadoop.hbase.protobuf.generated.WALProtos.FlushDescriptor;
36  import org.apache.hadoop.hbase.protobuf.generated.WALProtos.RegionEventDescriptor;
37  import org.apache.hadoop.hbase.wal.WAL;
38  import org.apache.hadoop.hbase.wal.WALKey;
39  
40  import com.google.protobuf.TextFormat;
41  
42  /**
43   * Helper methods to ease Region Server integration with the write ahead log.
44   * Note that methods in this class specifically should not require access to anything
45   * other than the API found in {@link WAL}.
46   */
47  @InterfaceAudience.Private
48  public class WALUtil {
49    static final Log LOG = LogFactory.getLog(WALUtil.class);
50  
51    /**
52     * Write the marker that a compaction has succeeded and is about to be committed.
53     * This provides info to the HMaster to allow it to recover the compaction if
54     * this regionserver dies in the middle (This part is not yet implemented). It also prevents
55     * the compaction from finishing if this regionserver has already lost its lease on the log.
56     * @param sequenceId Used by WAL to get sequence Id for the waledit.
57     */
58    public static void writeCompactionMarker(WAL log, HTableDescriptor htd, HRegionInfo info,
59        final CompactionDescriptor c, AtomicLong sequenceId) throws IOException {
60      TableName tn = TableName.valueOf(c.getTableName().toByteArray());
61      // we use HLogKey here instead of WALKey directly to support legacy coprocessors.
62      WALKey key = new HLogKey(info.getEncodedNameAsBytes(), tn);
63      log.append(htd, info, key, WALEdit.createCompaction(info, c), sequenceId, false, null);
64      log.sync();
65      if (LOG.isTraceEnabled()) {
66        LOG.trace("Appended compaction marker " + TextFormat.shortDebugString(c));
67      }
68    }
69  
70    /**
71     * Write a flush marker indicating a start / abort or a complete of a region flush
72     */
73    public static long writeFlushMarker(WAL log, HTableDescriptor htd, HRegionInfo info,
74        final FlushDescriptor f, AtomicLong sequenceId, boolean sync) throws IOException {
75      TableName tn = TableName.valueOf(f.getTableName().toByteArray());
76      // we use HLogKey here instead of WALKey directly to support legacy coprocessors.
77      WALKey key = new HLogKey(info.getEncodedNameAsBytes(), tn);
78      long trx = log.append(htd, info, key, WALEdit.createFlushWALEdit(info, f), sequenceId, false,
79          null);
80      if (sync) log.sync(trx);
81      if (LOG.isTraceEnabled()) {
82        LOG.trace("Appended flush marker " + TextFormat.shortDebugString(f));
83      }
84      return trx;
85    }
86  
87    /**
88     * Write a region open marker indicating that the region is opened
89     */
90    public static long writeRegionEventMarker(WAL log, HTableDescriptor htd, HRegionInfo info,
91        final RegionEventDescriptor r, AtomicLong sequenceId) throws IOException {
92      TableName tn = TableName.valueOf(r.getTableName().toByteArray());
93      // we use HLogKey here instead of WALKey directly to support legacy coprocessors.
94      WALKey key = new HLogKey(info.getEncodedNameAsBytes(), tn);
95      long trx = log.append(htd, info, key, WALEdit.createRegionEventWALEdit(info, r),
96        sequenceId, false, null);
97      log.sync(trx);
98      if (LOG.isTraceEnabled()) {
99        LOG.trace("Appended region event marker " + TextFormat.shortDebugString(r));
100     }
101     return trx;
102   }
103 
104   /**
105    * Write a log marker that a bulk load has succeeded and is about to be committed.
106    *
107    * @param wal        The log to write into.
108    * @param htd        A description of the table that we are bulk loading into.
109    * @param info       A description of the region in the table that we are bulk loading into.
110    * @param descriptor A protocol buffers based description of the client's bulk loading request
111    * @param sequenceId The current sequenceId in the log at the time when we were to write the
112    *                   bulk load marker.
113    * @return txid of this transaction or if nothing to do, the last txid
114    * @throws IOException We will throw an IOException if we can not append to the HLog.
115    */
116   public static long writeBulkLoadMarkerAndSync(final WAL wal,
117                                                 final HTableDescriptor htd,
118                                                 final HRegionInfo info,
119                                                 final WALProtos.BulkLoadDescriptor descriptor,
120                                                 final AtomicLong sequenceId) throws IOException {
121     TableName tn = info.getTable();
122     WALKey key = new HLogKey(info.getEncodedNameAsBytes(), tn);
123 
124     // Add it to the log but the false specifies that we don't need to add it to the memstore
125     long trx = wal.append(htd,
126             info,
127             key,
128             WALEdit.createBulkLoadEvent(info, descriptor),
129             sequenceId,
130             false,
131             new ArrayList<Cell>());
132     wal.sync(trx);
133 
134     if (LOG.isTraceEnabled()) {
135       LOG.trace("Appended Bulk Load marker " + TextFormat.shortDebugString(descriptor));
136     }
137     return trx;
138   }
139   
140 }