View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.regionserver;
19  
20  import java.io.IOException;
21  import java.util.Collection;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.hadoop.fs.Path;
26  import org.apache.hadoop.hbase.Cell;
27  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
28  import org.apache.hadoop.hbase.HDFSBlocksDistribution;
29  import org.apache.hadoop.hbase.HRegionInfo;
30  import org.apache.hadoop.hbase.HTableDescriptor;
31  import org.apache.hadoop.hbase.classification.InterfaceAudience;
32  import org.apache.hadoop.hbase.classification.InterfaceStability;
33  import org.apache.hadoop.hbase.client.Append;
34  import org.apache.hadoop.hbase.client.Delete;
35  import org.apache.hadoop.hbase.client.Get;
36  import org.apache.hadoop.hbase.client.Increment;
37  import org.apache.hadoop.hbase.client.IsolationLevel;
38  import org.apache.hadoop.hbase.client.Mutation;
39  import org.apache.hadoop.hbase.client.Put;
40  import org.apache.hadoop.hbase.client.Result;
41  import org.apache.hadoop.hbase.client.RowMutations;
42  import org.apache.hadoop.hbase.client.Scan;
43  import org.apache.hadoop.hbase.conf.ConfigurationObserver;
44  import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;
45  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
46  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
47  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
48  import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceCall;
49  import org.apache.hadoop.hbase.util.Pair;
50  import org.apache.hadoop.hbase.wal.WALSplitter.MutationReplay;
51  
52  import com.google.protobuf.Message;
53  import com.google.protobuf.RpcController;
54  import com.google.protobuf.Service;
55  
56  /**
57   * Regions store data for a certain region of a table.  It stores all columns
58   * for each row. A given table consists of one or more Regions.
59   *
60   * <p>An Region is defined by its table and its key extent.
61   *
62   * <p>Locking at the Region level serves only one purpose: preventing the
63   * region from being closed (and consequently split) while other operations
64   * are ongoing. Each row level operation obtains both a row lock and a region
65   * read lock for the duration of the operation. While a scanner is being
66   * constructed, getScanner holds a read lock. If the scanner is successfully
67   * constructed, it holds a read lock until it is closed. A close takes out a
68   * write lock and consequently will block for ongoing operations and will block
69   * new operations from starting while the close is in progress.
70   */
71  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
72  @InterfaceStability.Evolving
73  public interface Region extends ConfigurationObserver {
74  
75    ///////////////////////////////////////////////////////////////////////////
76    // Region state
77  
78    /** @return region information for this region */
79    HRegionInfo getRegionInfo();
80  
81    /** @return table descriptor for this region */
82    HTableDescriptor getTableDesc();
83  
84    /** @return true if region is available (not closed and not closing) */
85    boolean isAvailable();
86  
87    /** @return true if region is closed */
88    boolean isClosed();
89  
90    /** @return True if closing process has started */
91    boolean isClosing();
92  
93    /** @return True if region is in recovering state */
94    boolean isRecovering();
95  
96    /** @return True if region is read only */
97    boolean isReadOnly();
98  
99    /**
100    * Return the list of Stores managed by this region
101    * <p>Use with caution.  Exposed for use of fixup utilities.
102    * @return a list of the Stores managed by this region
103    */
104   List<Store> getStores();
105 
106   /**
107    * Return the Store for the given family
108    * <p>Use with caution.  Exposed for use of fixup utilities.
109    * @return the Store for the given family
110    */
111   Store getStore(byte[] family);
112 
113   /** @return list of store file names for the given families */
114   List<String> getStoreFileList(byte [][] columns);
115 
116   /**
117    * Check the region's underlying store files, open the files that have not
118    * been opened yet, and remove the store file readers for store files no
119    * longer available.
120    * @throws IOException
121    */
122   boolean refreshStoreFiles() throws IOException;
123 
124   /** @return the latest sequence number that was read from storage when this region was opened */
125   long getOpenSeqNum();
126 
127   /** @return the max sequence id of flushed data on this region */
128   long getMaxFlushedSeqId();
129 
130   /** @return the oldest sequence id found in the store for the given family */
131   public long getOldestSeqIdOfStore(byte[] familyName);
132 
133   /**
134    * This can be used to determine the last time all files of this region were major compacted.
135    * @param majorCompactioOnly Only consider HFile that are the result of major compaction
136    * @return the timestamp of the oldest HFile for all stores of this region
137    */
138   long getOldestHfileTs(boolean majorCompactioOnly) throws IOException;
139 
140   /**
141    * @return map of column family names to max sequence id that was read from storage when this
142    * region was opened
143    */
144   public Map<byte[], Long> getMaxStoreSeqId();
145 
146   /** @return true if loading column families on demand by default */
147   boolean isLoadingCfsOnDemandDefault();
148 
149   /** @return readpoint considering given IsolationLevel */
150   long getReadpoint(IsolationLevel isolationLevel);
151 
152   /**
153    * @return The earliest time a store in the region was flushed. All
154    *         other stores in the region would have been flushed either at, or
155    *         after this time.
156    */
157   long getEarliestFlushTimeForAllStores();
158 
159   ///////////////////////////////////////////////////////////////////////////
160   // Metrics
161 
162   /** @return read requests count for this region */
163   long getReadRequestsCount();
164 
165   /**
166    * Update the read request count for this region
167    * @param i increment
168    */
169   void updateReadRequestsCount(long i);
170 
171   /** @return write request count for this region */
172   long getWriteRequestsCount();
173 
174   /**
175    * Update the write request count for this region
176    * @param i increment
177    */
178   void updateWriteRequestsCount(long i);
179 
180   /** @return memstore size for this region, in bytes */
181   long getMemstoreSize();
182 
183   /** @return the number of mutations processed bypassing the WAL */
184   long getNumMutationsWithoutWAL();
185 
186   /** @return the size of data processed bypassing the WAL, in bytes */
187   long getDataInMemoryWithoutWAL();
188 
189   /** @return the number of blocked requests */
190   long getBlockedRequestsCount();
191 
192   /** @return the number of checkAndMutate guards that passed */
193   long getCheckAndMutateChecksPassed();
194 
195   /** @return the number of failed checkAndMutate guards */
196   long getCheckAndMutateChecksFailed();
197 
198   /** @return the MetricsRegion for this region */
199   MetricsRegion getMetrics();
200 
201   /** @return the block distribution for all Stores managed by this region */
202   HDFSBlocksDistribution getHDFSBlocksDistribution();
203 
204   ///////////////////////////////////////////////////////////////////////////
205   // Locking
206 
207   // Region read locks
208 
209   /**
210    * Operation enum is used in {@link Region#startRegionOperation} to provide context for
211    * various checks before any region operation begins.
212    */
213   enum Operation {
214     ANY, GET, PUT, DELETE, SCAN, APPEND, INCREMENT, SPLIT_REGION, MERGE_REGION, BATCH_MUTATE,
215     REPLAY_BATCH_MUTATE, COMPACT_REGION, REPLAY_EVENT
216   }
217 
218   /**
219    * This method needs to be called before any public call that reads or
220    * modifies data.
221    * Acquires a read lock and checks if the region is closing or closed.
222    * <p>{@link #closeRegionOperation} MUST then always be called after
223    * the operation has completed, whether it succeeded or failed.
224    * @throws IOException
225    */
226   void startRegionOperation() throws IOException;
227 
228   /**
229    * This method needs to be called before any public call that reads or
230    * modifies data.
231    * Acquires a read lock and checks if the region is closing or closed.
232    * <p>{@link #closeRegionOperation} MUST then always be called after
233    * the operation has completed, whether it succeeded or failed.
234    * @param op The operation is about to be taken on the region
235    * @throws IOException
236    */
237   void startRegionOperation(Operation op) throws IOException;
238 
239   /**
240    * Closes the region operation lock.
241    * @throws IOException
242    */
243   void closeRegionOperation() throws IOException;
244 
245   // Row write locks
246 
247   /**
248    * Row lock held by a given thread.
249    * One thread may acquire multiple locks on the same row simultaneously.
250    * The locks must be released by calling release() from the same thread.
251    */
252   public interface RowLock {
253     /**
254      * Release the given lock.  If there are no remaining locks held by the current thread
255      * then unlock the row and allow other threads to acquire the lock.
256      * @throws IllegalArgumentException if called by a different thread than the lock owning
257      *     thread
258      */
259     void release();
260   }
261 
262   /**
263    * Tries to acquire a lock on the given row.
264    * @param waitForLock if true, will block until the lock is available.
265    *        Otherwise, just tries to obtain the lock and returns
266    *        false if unavailable.
267    * @return the row lock if acquired,
268    *   null if waitForLock was false and the lock was not acquired
269    * @throws IOException if waitForLock was true and the lock could not be acquired after waiting
270    */
271   RowLock getRowLock(byte[] row, boolean waitForLock) throws IOException;
272 
273   /**
274    * If the given list of row locks is not null, releases all locks.
275    */
276   void releaseRowLocks(List<RowLock> rowLocks);
277 
278   ///////////////////////////////////////////////////////////////////////////
279   // Region operations
280 
281   /**
282    * Perform one or more append operations on a row.
283    * @param append
284    * @param nonceGroup
285    * @param nonce
286    * @return result of the operation
287    * @throws IOException
288    */
289   Result append(Append append, long nonceGroup, long nonce) throws IOException;
290 
291   /**
292    * Perform a batch of mutations.
293    * <p>
294    * Note this supports only Put and Delete mutations and will ignore other types passed.
295    * @param mutations the list of mutations
296    * @param nonceGroup
297    * @param nonce
298    * @return an array of OperationStatus which internally contains the
299    *         OperationStatusCode and the exceptionMessage if any.
300    * @throws IOException
301    */
302   OperationStatus[] batchMutate(Mutation[] mutations, long nonceGroup, long nonce)
303       throws IOException;
304 
305   /**
306    * Replay a batch of mutations.
307    * @param mutations mutations to replay.
308    * @param replaySeqId
309    * @return an array of OperationStatus which internally contains the
310    *         OperationStatusCode and the exceptionMessage if any.
311    * @throws IOException
312    */
313    OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) throws IOException;
314 
315   /**
316    * Atomically checks if a row/family/qualifier value matches the expected val
317    * If it does, it performs the row mutations.  If the passed value is null, t
318    * is for the lack of column (ie: non-existence)
319    * @param row to check
320    * @param family column family to check
321    * @param qualifier column qualifier to check
322    * @param compareOp the comparison operator
323    * @param comparator
324    * @param mutation
325    * @param writeToWAL
326    * @return true if mutation was applied, false otherwise
327    * @throws IOException
328    */
329   boolean checkAndMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp,
330       ByteArrayComparable comparator, Mutation mutation, boolean writeToWAL) throws IOException;
331 
332   /**
333    * Atomically checks if a row/family/qualifier value matches the expected val
334    * If it does, it performs the row mutations.  If the passed value is null, t
335    * is for the lack of column (ie: non-existence)
336    * @param row to check
337    * @param family column family to check
338    * @param qualifier column qualifier to check
339    * @param compareOp the comparison operator
340    * @param comparator
341    * @param mutations
342    * @param writeToWAL
343    * @return true if mutation was applied, false otherwise
344    * @throws IOException
345    */
346   boolean checkAndRowMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp,
347       ByteArrayComparable comparator, RowMutations mutations, boolean writeToWAL)
348       throws IOException;
349 
350   /**
351    * Deletes the specified cells/row.
352    * @param delete
353    * @throws IOException
354    */
355   void delete(Delete delete) throws IOException;
356 
357   /**
358    * Do a get based on the get parameter.
359    * @param get query parameters
360    * @return result of the operation
361    */
362   Result get(Get get) throws IOException;
363 
364   /**
365    * Do a get based on the get parameter.
366    * @param get query parameters
367    * @param withCoprocessor invoke coprocessor or not. We don't want to
368    * always invoke cp.
369    * @return list of cells resulting from the operation
370    */
371   List<Cell> get(Get get, boolean withCoprocessor) throws IOException;
372 
373   /**
374    * Return all the data for the row that matches <i>row</i> exactly,
375    * or the one that immediately preceeds it, at or immediately before
376    * <i>ts</i>.
377    * @param row
378    * @param family
379    * @return result of the operation
380    * @throws IOException
381    */
382   Result getClosestRowBefore(byte[] row, byte[] family) throws IOException;
383 
384   /**
385    * Return an iterator that scans over the HRegion, returning the indicated
386    * columns and rows specified by the {@link Scan}.
387    * <p>
388    * This Iterator must be closed by the caller.
389    *
390    * @param scan configured {@link Scan}
391    * @return RegionScanner
392    * @throws IOException read exceptions
393    */
394   RegionScanner getScanner(Scan scan) throws IOException;
395 
396   /**
397    * Perform one or more increment operations on a row.
398    * @param increment
399    * @param nonceGroup
400    * @param nonce
401    * @return result of the operation
402    * @throws IOException
403    */
404   Result increment(Increment increment, long nonceGroup, long nonce) throws IOException;
405 
406   /**
407    * Performs multiple mutations atomically on a single row. Currently
408    * {@link Put} and {@link Delete} are supported.
409    *
410    * @param mutations object that specifies the set of mutations to perform atomically
411    * @throws IOException
412    */
413   void mutateRow(RowMutations mutations) throws IOException;
414 
415   /**
416    * Perform atomic mutations within the region.
417    *
418    * @param mutations The list of mutations to perform.
419    * <code>mutations</code> can contain operations for multiple rows.
420    * Caller has to ensure that all rows are contained in this region.
421    * @param rowsToLock Rows to lock
422    * @param nonceGroup Optional nonce group of the operation (client Id)
423    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
424    * If multiple rows are locked care should be taken that
425    * <code>rowsToLock</code> is sorted in order to avoid deadlocks.
426    * @throws IOException
427    */
428   void mutateRowsWithLocks(Collection<Mutation> mutations, Collection<byte[]> rowsToLock,
429       long nonceGroup, long nonce) throws IOException;
430 
431   /**
432    * Performs atomic multiple reads and writes on a given row.
433    *
434    * @param processor The object defines the reads and writes to a row.
435    */
436   void processRowsWithLocks(RowProcessor<?,?> processor) throws IOException;
437 
438   /**
439    * Performs atomic multiple reads and writes on a given row.
440    *
441    * @param processor The object defines the reads and writes to a row.
442    * @param nonceGroup Optional nonce group of the operation (client Id)
443    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
444    */
445   void processRowsWithLocks(RowProcessor<?,?> processor, long nonceGroup, long nonce)
446       throws IOException;
447 
448   /**
449    * Performs atomic multiple reads and writes on a given row.
450    *
451    * @param processor The object defines the reads and writes to a row.
452    * @param timeout The timeout of the processor.process() execution
453    *                Use a negative number to switch off the time bound
454    * @param nonceGroup Optional nonce group of the operation (client Id)
455    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
456    */
457   void processRowsWithLocks(RowProcessor<?,?> processor, long timeout, long nonceGroup, long nonce)
458       throws IOException;
459 
460   /**
461    * Puts some data in the table.
462    * @param put
463    * @throws IOException
464    */
465   void put(Put put) throws IOException;
466 
467   /**
468    * Listener class to enable callers of
469    * bulkLoadHFile() to perform any necessary
470    * pre/post processing of a given bulkload call
471    */
472   interface BulkLoadListener {
473     /**
474      * Called before an HFile is actually loaded
475      * @param family family being loaded to
476      * @param srcPath path of HFile
477      * @return final path to be used for actual loading
478      * @throws IOException
479      */
480     String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile)
481         throws IOException;
482 
483     /**
484      * Called after a successful HFile load
485      * @param family family being loaded to
486      * @param srcPath path of HFile
487      * @throws IOException
488      */
489     void doneBulkLoad(byte[] family, String srcPath) throws IOException;
490 
491     /**
492      * Called after a failed HFile load
493      * @param family family being loaded to
494      * @param srcPath path of HFile
495      * @throws IOException
496      */
497     void failedBulkLoad(byte[] family, String srcPath) throws IOException;
498   }
499 
500   /**
501    * Attempts to atomically load a group of hfiles.  This is critical for loading
502    * rows with multiple column families atomically.
503    *
504    * @param familyPaths List of Pair<byte[] column family, String hfilePath>
505    * @param bulkLoadListener Internal hooks enabling massaging/preparation of a
506    * file about to be bulk loaded
507    * @param assignSeqId
508    * @return Map from family to List of store file paths if successful, null if failed recoverably
509    * @throws IOException if failed unrecoverably.
510    */
511   Map<byte[], List<Path>> bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths,
512       boolean assignSeqId, BulkLoadListener bulkLoadListener) throws IOException;
513 
514   /**
515    * Attempts to atomically load a group of hfiles.  This is critical for loading
516    * rows with multiple column families atomically.
517    *
518    * @param familyPaths List of Pair&lt;byte[] column family, String hfilePath&gt;
519    * @param assignSeqId
520    * @param bulkLoadListener Internal hooks enabling massaging/preparation of a
521    * file about to be bulk loaded
522    * @param copyFile always copy hfiles if true
523    * @return Map from family to List of store file paths if successful, null if failed recoverably
524    * @throws IOException if failed unrecoverably.
525    */
526   Map<byte[], List<Path>> bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths,
527       boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile) throws IOException;
528 
529   ///////////////////////////////////////////////////////////////////////////
530   // Coprocessors
531 
532   /** @return the coprocessor host */
533   RegionCoprocessorHost getCoprocessorHost();
534 
535   /**
536    * Executes a single protocol buffer coprocessor endpoint {@link Service} method using
537    * the registered protocol handlers.  {@link Service} implementations must be registered via the
538    * {@link Region#registerService(com.google.protobuf.Service)}
539    * method before they are available.
540    *
541    * @param controller an {@code RpcContoller} implementation to pass to the invoked service
542    * @param call a {@code CoprocessorServiceCall} instance identifying the service, method,
543    *     and parameters for the method invocation
544    * @return a protocol buffer {@code Message} instance containing the method's result
545    * @throws IOException if no registered service handler is found or an error
546    *     occurs during the invocation
547    * @see org.apache.hadoop.hbase.regionserver.Region#registerService(com.google.protobuf.Service)
548    */
549   Message execService(RpcController controller, CoprocessorServiceCall call) throws IOException;
550 
551   /**
552    * Registers a new protocol buffer {@link Service} subclass as a coprocessor endpoint to
553    * be available for handling
554    * {@link Region#execService(com.google.protobuf.RpcController,
555    *    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceCall)}} calls.
556    *
557    * <p>
558    * Only a single instance may be registered per region for a given {@link Service} subclass (the
559    * instances are keyed on {@link com.google.protobuf.Descriptors.ServiceDescriptor#getFullName()}.
560    * After the first registration, subsequent calls with the same service name will fail with
561    * a return value of {@code false}.
562    * </p>
563    * @param instance the {@code Service} subclass instance to expose as a coprocessor endpoint
564    * @return {@code true} if the registration was successful, {@code false}
565    * otherwise
566    */
567   boolean registerService(Service instance);
568 
569   ///////////////////////////////////////////////////////////////////////////
570   // RowMutation processor support
571 
572   /**
573    * Check the collection of families for validity.
574    * @param families
575    * @throws NoSuchColumnFamilyException
576    */
577   void checkFamilies(Collection<byte[]> families) throws NoSuchColumnFamilyException;
578 
579   /**
580    * Check the collection of families for valid timestamps
581    * @param familyMap
582    * @param now current timestamp
583    * @throws FailedSanityCheckException
584    */
585   void checkTimestamps(Map<byte[], List<Cell>> familyMap, long now)
586       throws FailedSanityCheckException;
587 
588   /**
589    * Prepare a delete for a row mutation processor
590    * @param delete The passed delete is modified by this method. WARNING!
591    * @throws IOException
592    */
593   void prepareDelete(Delete delete) throws IOException;
594 
595   /**
596    * Set up correct timestamps in the KVs in Delete object.
597    * <p>Caller should have the row and region locks.
598    * @param mutation
599    * @param familyCellMap
600    * @param now
601    * @throws IOException
602    */
603   void prepareDeleteTimestamps(Mutation mutation, Map<byte[], List<Cell>> familyCellMap,
604       byte[] now) throws IOException;
605 
606   /**
607    * Replace any cell timestamps set to HConstants#LATEST_TIMESTAMP with the
608    * provided current timestamp.
609    * @param values
610    * @param now
611    */
612   void updateCellTimestamps(final Iterable<List<Cell>> values, final byte[] now)
613       throws IOException;
614 
615   ///////////////////////////////////////////////////////////////////////////
616   // Flushes, compactions, splits, etc.
617   // Wizards only, please
618 
619   interface FlushResult {
620     enum Result {
621       FLUSHED_NO_COMPACTION_NEEDED,
622       FLUSHED_COMPACTION_NEEDED,
623       // Special case where a flush didn't run because there's nothing in the memstores. Used when
624       // bulk loading to know when we can still load even if a flush didn't happen.
625       CANNOT_FLUSH_MEMSTORE_EMPTY,
626       CANNOT_FLUSH
627     }
628 
629     /** @return the detailed result code */
630     Result getResult();
631 
632     /** @return true if the memstores were flushed, else false */
633     boolean isFlushSucceeded();
634 
635     /** @return True if the flush requested a compaction, else false */
636     boolean isCompactionNeeded();
637   }
638 
639   /**
640    * Flush the cache.
641    *
642    * <p>When this method is called the cache will be flushed unless:
643    * <ol>
644    *   <li>the cache is empty</li>
645    *   <li>the region is closed.</li>
646    *   <li>a flush is already in progress</li>
647    *   <li>writes are disabled</li>
648    * </ol>
649    *
650    * <p>This method may block for some time, so it should not be called from a
651    * time-sensitive thread.
652    * @param force whether we want to force a flush of all stores
653    * @return FlushResult indicating whether the flush was successful or not and if
654    * the region needs compacting
655    *
656    * @throws IOException general io exceptions
657    * @throws DroppedSnapshotException Thrown when abort is required. The caller MUST catch this
658    * exception and MUST abort. Any further operation to the region may cause data loss.
659    * because a snapshot was not properly persisted.
660    */
661   FlushResult flush(boolean force) throws IOException;
662 
663   /**
664    * Synchronously compact all stores in the region.
665    * <p>This operation could block for a long time, so don't call it from a
666    * time-sensitive thread.
667    * <p>Note that no locks are taken to prevent possible conflicts between
668    * compaction and splitting activities. The regionserver does not normally compact
669    * and split in parallel. However by calling this method you may introduce
670    * unexpected and unhandled concurrency. Don't do this unless you know what
671    * you are doing.
672    *
673    * @param majorCompaction True to force a major compaction regardless of thresholds
674    * @throws IOException
675    */
676   void compact(final boolean majorCompaction) throws IOException;
677 
678   /**
679    * Trigger major compaction on all stores in the region.
680    * <p>
681    * Compaction will be performed asynchronously to this call by the RegionServer's
682    * CompactSplitThread. See also {@link Store#triggerMajorCompaction()}
683    * @throws IOException
684    */
685   void triggerMajorCompaction() throws IOException;
686 
687   /**
688    * @return if a given region is in compaction now.
689    */
690   CompactionState getCompactionState();
691 
692   /** Wait for all current flushes and compactions of the region to complete */
693   void waitForFlushesAndCompactions();
694 
695 }