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