[
https://issues.apache.org/jira/browse/HBASE-12975?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14341164#comment-14341164
]
Andrew Purtell commented on HBASE-12975:
----------------------------------------
Here's what I have for SplitTransaction. RegionMergeTransaction will be
similar, differing in ways you can infer.
{code:java}
/**
* Executes region split as a "transaction". Call {@link #prepare()} to setup
* the transaction, {@link #execute(Server, RegionServerServices)} to run the
* transaction and {@link #rollback(Server, RegionServerServices)} to cleanup
if execute fails.
*
* <p>Here is an example of how you would use this interface:
* <pre>
* SplitTransactionFactory factory = new SplitTransactionFactory(conf);
* SplitTransaction st = factory.create(parent, midKey)
* .registerTransactionListener(new TransactionListener() {
* public void transition(SplitTransaction transaction,
SplitTransactionPhase from,
* SplitTransactionPhase to) throws IOException {
* // ...
* }
* public void rollback(SplitTransaction transaction,
SplitTransactionPhase from,
* SplitTransactionPhase to) {
* // ...
* }
* });
* if (!st.prepare()) return;
* try {
* st.execute(server, services);
* } catch (IOException e) {
* try {
* st.rollback(server, services);
* return;
* } catch (RuntimeException e) {
* // abort the server
* }
* }
* </Pre>
* <p>A split transaction is not thread safe. Callers must ensure a split is
run by
* one thread only.
*/
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
@InterfaceStability.Evolving
public interface SplitTransaction {
/**
* Each enum is a step in the split transaction.
*/
public enum SplitTransactionPhase {
/**
* Started
*/
STARTED,
/**
* Prepared (after table lock)
*/
PREPARED,
/**
* Before preSplit coprocessor hook
*/
BEFORE_PRE_SPLIT_HOOK,
/**
* After preSplit coprocessor hook
*/
AFTER_PRE_SPLIT_HOOK,
/**
* Set region as in transition, set it into SPLITTING state.
*/
SET_SPLITTING,
/**
* We created the temporary split data directory.
*/
CREATE_SPLIT_DIR,
/**
* Closed the parent region.
*/
CLOSED_PARENT_REGION,
/**
* The parent has been taken out of the server's online regions list.
*/
OFFLINED_PARENT,
/**
* Started in on creation of the first daughter region.
*/
STARTED_REGION_A_CREATION,
/**
* Started in on the creation of the second daughter region.
*/
STARTED_REGION_B_CREATION,
/**
* Opened the first daughter region
*/
OPENED_REGION_A,
/**
* Opened the second daughter region
*/
OPENED_REGION_B,
/**
* Point of no return.
* If we got here, then transaction is not recoverable other than by
* crashing out the regionserver.
*/
PONR,
/**
* Before postSplit coprocessor hook
*/
BEFORE_POST_SPLIT_HOOK,
/**
* After postSplit coprocessor hook
*/
AFTER_POST_SPLIT_HOOK,
/**
* Completed
*/
COMPLETED
}
/**
* Split transaction journal entry
*/
public interface JournalEntry {
/** @return the completed phase marked by this journal entry */
SplitTransactionPhase getPhase();
/** @return the time of phase completion */
long getTimeStamp();
}
/**
* Split transaction listener
*/
public interface TransactionListener {
/**
* Invoked when transitioning forward from one transaction phase to another
* @param transaction the transaction
* @param from the current phase
* @param to the next phase
* @throws IOException listener can throw this to abort
*/
void transition(SplitTransaction transaction, SplitTransactionPhase from,
SplitTransactionPhase to) throws IOException;
/**
* Invoked when rolling back a transaction from one transaction phase to the
* previous
* @param transaction the transaction
* @param from the current phase
* @param to the previous phase
*/
void rollback(SplitTransaction transaction, SplitTransactionPhase from,
SplitTransactionPhase to);
}
/**
* Check split inputs and prepare the transaction.
* @return <code>true</code> if the region is splittable else
* <code>false</code> if it is not (e.g. its already closed, etc.).
* @throws IOException
*/
boolean prepare() throws IOException;
/**
* Run the transaction.
* @param server Hosting server instance. Can be null when testing.
* @param services Used to online/offline regions.
* @throws IOException If thrown, transaction failed.
* Call {@link #rollback(Server, RegionServerServices)}
* @return Regions created
* @throws IOException
* @see #rollback(Server, RegionServerServices)
*/
PairOfSameType<HRegion> execute(Server server, RegionServerServices services)
throws IOException;
/**
* Roll back a failed transaction
* @param server Hosting server instance (May be null when testing).
* @param services
* @throws IOException If thrown, rollback failed. Take drastic action.
* @return True if we successfully rolled back, false if we got to the point
* of no return and so now need to abort the server to minimize damage.
*/
boolean rollback(Server server, RegionServerServices services) throws
IOException;
/**
* Register a listener for transaction preparation, execution, and possibly
* rollback phases.
* <p>A listener can abort a transaction by throwing an exception.
* @param listener the listener
* @returns 'this' for chaining
*/
SplitTransaction registerTransactionListener(TransactionListener listener);
/**
* Get the journal for the transaction.
* <p>Journal entries are an opaque type represented as JournalEntry. They can
* also provide useful debugging information via their toString method.
* @return the transaction journal
*/
List<JournalEntry> getJournal();
/**
* Get the Server running the transaction or rollback
* @return server instance
*/
Server getServer();
/**
* Get the RegonServerServices of the server running the transaction or
rollback
* @return region server services
*/
RegionServerServices getRegionServerServices();
}
{code}
Working on RegionMergeTransaction now, then there are a bunch of tests I need
to clean up.
> Supportable SplitTransaction and RegionMergeTransaction interfaces
> ------------------------------------------------------------------
>
> Key: HBASE-12975
> URL: https://issues.apache.org/jira/browse/HBASE-12975
> Project: HBase
> Issue Type: Improvement
> Reporter: Rajeshbabu Chintaguntla
> Assignee: Andrew Purtell
> Fix For: 2.0.0, 1.1.0
>
> Attachments: HBASE-12975.patch
>
>
> Making SplitTransaction, RegionMergeTransaction limited private is required
> to support local indexing feature in Phoenix to ensure regions colocation.
> We can ensure region split, regions merge in the coprocessors in few method
> calls without touching internals like creating zk's, file layout changes or
> assignments.
> 1) stepsBeforePONR, stepsAfterPONR we can ensure split.
> 2) meta entries can pass through coprocessors to atomically update with the
> normal split/merge.
> 3) rollback on failure.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)