View Javadoc

1   /**
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with this
6    * work for additional information regarding copyright ownership. The ASF
7    * licenses this file to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance with the License.
9    * 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, WITHOUT
15   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16   * License for the specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.hadoop.hbase.regionserver;
20  
21  import java.io.IOException;
22  import java.util.List;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  import org.apache.hadoop.hbase.classification.InterfaceStability;
26  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
27  import org.apache.hadoop.hbase.HRegionInfo;
28  import org.apache.hadoop.hbase.Server;
29  import org.apache.hadoop.hbase.security.User;
30  
31  /**
32   * Executes region merge as a "transaction". It is similar with
33   * SplitTransaction. Call {@link #prepare(RegionServerServices)} to setup the
34   * transaction, {@link #execute(Server, RegionServerServices)} to run the
35   * transaction and {@link #rollback(Server, RegionServerServices)} to cleanup if
36   * execute fails.
37   * 
38   * <p>Here is an example of how you would use this interface:
39   * <pre>
40   *  RegionMergeTransactionFactory factory = new RegionMergeTransactionFactory(conf);
41   *  RegionMergeTransaction mt = factory.create(parent, midKey)
42   *    .registerTransactionListener(new TransactionListener() {
43   *       public void transition(RegionMergeTransaction transaction,
44   *         RegionMergeTransactionPhase from, RegionMergeTransactionPhase to) throws IOException {
45   *         // ...
46   *       }
47   *       public void rollback(RegionMergeTransaction transaction,
48   *         RegionMergeTransactionPhase from, RegionMergeTransactionPhase to) {
49   *         // ...
50   *       }
51   *    });
52   *  if (!mt.prepare()) return;
53   *  try {
54   *    mt.execute(server, services);
55   *  } catch (IOException ioe) {
56   *    try {
57   *      mt.rollback(server, services);
58   *      return;
59   *    } catch (RuntimeException e) {
60   *      // abort the server
61   *    }
62   *  }
63   * </Pre>
64   * <p>A merge transaction is not thread safe.  Callers must ensure a split is run by
65   * one thread only.
66   */
67  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
68  @InterfaceStability.Evolving
69  public interface RegionMergeTransaction {
70    /**
71     * Each enum is a step in the merge transaction.
72     */
73    enum RegionMergeTransactionPhase {
74      STARTED,
75      /**
76       * Prepared
77       */
78      PREPARED,
79      /**
80       * Set region as in transition, set it into MERGING state.
81       */
82      SET_MERGING,
83      /**
84       * We created the temporary merge data directory.
85       */
86      CREATED_MERGE_DIR,
87      /**
88       * Closed the merging region A.
89       */
90      CLOSED_REGION_A,
91      /**
92       * The merging region A has been taken out of the server's online regions list.
93       */
94      OFFLINED_REGION_A,
95      /**
96       * Closed the merging region B.
97       */
98      CLOSED_REGION_B,
99      /**
100      * The merging region B has been taken out of the server's online regions list.
101      */
102     OFFLINED_REGION_B,
103     /**
104      * Started in on creation of the merged region.
105      */
106     STARTED_MERGED_REGION_CREATION,
107     /**
108      * Point of no return. If we got here, then transaction is not recoverable
109      * other than by crashing out the regionserver.
110      */
111     PONR,
112     /**
113      * Completed
114      */
115     COMPLETED
116   }
117 
118   /**
119    * Split transaction journal entry
120    */
121   public interface JournalEntry {
122 
123     /** @return the completed phase marked by this journal entry */
124     RegionMergeTransactionPhase getPhase();
125 
126     /** @return the time of phase completion */
127     long getTimeStamp();
128   }
129 
130   /**
131    * Split transaction listener
132    */
133   public interface TransactionListener {
134 
135     /**
136      * Invoked when transitioning forward from one transaction phase to another
137      * @param transaction the transaction
138      * @param from the current phase
139      * @param to the next phase
140      * @throws IOException listener can throw this to abort
141      */
142     void transition(RegionMergeTransaction transaction, RegionMergeTransactionPhase from,
143         RegionMergeTransactionPhase to) throws IOException;
144 
145     /**
146      * Invoked when rolling back a transaction from one transaction phase to the
147      * previous
148      * @param transaction the transaction
149      * @param from the current phase
150      * @param to the previous phase
151      */
152     void rollback(RegionMergeTransaction transaction, RegionMergeTransactionPhase from,
153         RegionMergeTransactionPhase to);
154   }
155 
156   /**
157    * Check merge inputs and prepare the transaction.
158    * @param services
159    * @return <code>true</code> if the regions are mergeable else
160    *         <code>false</code> if they are not (e.g. its already closed, etc.).
161    * @throws IOException 
162    */
163   boolean prepare(RegionServerServices services) throws IOException;
164 
165   /**
166    * Run the transaction.
167    * @param server Hosting server instance. Can be null when testing
168    * @param services Used to online/offline regions.
169    * @throws IOException If thrown, transaction failed. Call
170    *           {@link #rollback(Server, RegionServerServices)}
171    * @return merged region
172    * @throws IOException
173    * @see #rollback(Server, RegionServerServices)
174    * @deprecated use #execute(Server, RegionServerServices, User)
175    */
176   @Deprecated
177   Region execute(Server server, RegionServerServices services) throws IOException;
178 
179   /**
180    * Run the transaction.
181    * @param server Hosting server instance. Can be null when testing
182    * @param services Used to online/offline regions.
183    * @param user
184    * @throws IOException If thrown, transaction failed. Call
185    *           {@link #rollback(Server, RegionServerServices)}
186    * @return merged region
187    * @throws IOException
188    * @see #rollback(Server, RegionServerServices, User)
189    */
190   Region execute(Server server, RegionServerServices services, User user) throws IOException;
191 
192   /**
193    * Roll back a failed transaction
194    * @param server Hosting server instance (May be null when testing).
195    * @param services Services of regionserver, used to online regions.
196    * @throws IOException If thrown, rollback failed. Take drastic action.
197    * @return True if we successfully rolled back, false if we got to the point
198    *         of no return and so now need to abort the server to minimize
199    *         damage.
200    * @deprecated use #rollback(Server, RegionServerServices, User)
201    */
202   @Deprecated
203   boolean rollback(Server server, RegionServerServices services) throws IOException;
204 
205   /**
206    * Roll back a failed transaction
207    * @param server Hosting server instance (May be null when testing).
208    * @param services Services of regionserver, used to online regions.
209    * @param user
210    * @throws IOException If thrown, rollback failed. Take drastic action.
211    * @return True if we successfully rolled back, false if we got to the point
212    *         of no return and so now need to abort the server to minimize
213    *         damage.
214    */
215   boolean rollback(Server server, RegionServerServices services, User user) throws IOException;
216 
217   /**
218    * Register a listener for transaction preparation, execution, and possibly
219    * rollback phases.
220    * <p>A listener can abort a transaction by throwing an exception. 
221    * @param listener the listener
222    * @return 'this' for chaining
223    */
224   RegionMergeTransaction registerTransactionListener(TransactionListener listener);
225 
226   /** @return merged region info */
227   HRegionInfo getMergedRegionInfo();
228 
229   /**
230    * Get the journal for the transaction.
231    * <p>Journal entries are an opaque type represented as JournalEntry. They can
232    * also provide useful debugging information via their toString method.
233    * @return the transaction journal
234    */
235   List<JournalEntry> getJournal();
236 
237   /**
238    * Get the Server running the transaction or rollback
239    * @return server instance
240    */
241   Server getServer();
242 
243   /**
244    * Get the RegonServerServices of the server running the transaction or rollback
245    * @return region server services
246    */
247   RegionServerServices getRegionServerServices();
248 }