1 /* 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package org.apache.hadoop.hbase.coprocessor; 17 18 import java.io.IOException; 19 import java.util.List; 20 import java.util.NavigableSet; 21 22 import org.apache.hadoop.classification.InterfaceAudience; 23 import org.apache.hadoop.classification.InterfaceStability; 24 import org.apache.hadoop.fs.FileSystem; 25 import org.apache.hadoop.fs.Path; 26 import org.apache.hadoop.hbase.Cell; 27 import org.apache.hadoop.hbase.Coprocessor; 28 import org.apache.hadoop.hbase.HBaseInterfaceAudience; 29 import org.apache.hadoop.hbase.HRegionInfo; 30 import org.apache.hadoop.hbase.KeyValue; 31 import org.apache.hadoop.hbase.client.Append; 32 import org.apache.hadoop.hbase.client.Delete; 33 import org.apache.hadoop.hbase.client.Durability; 34 import org.apache.hadoop.hbase.client.Get; 35 import org.apache.hadoop.hbase.client.Increment; 36 import org.apache.hadoop.hbase.client.Mutation; 37 import org.apache.hadoop.hbase.client.Put; 38 import org.apache.hadoop.hbase.client.Result; 39 import org.apache.hadoop.hbase.client.Scan; 40 import org.apache.hadoop.hbase.filter.ByteArrayComparable; 41 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; 42 import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper; 43 import org.apache.hadoop.hbase.io.Reference; 44 import org.apache.hadoop.hbase.io.hfile.CacheConfig; 45 import org.apache.hadoop.hbase.regionserver.DeleteTracker; 46 import org.apache.hadoop.hbase.regionserver.HRegion; 47 import org.apache.hadoop.hbase.regionserver.HRegion.Operation; 48 import org.apache.hadoop.hbase.regionserver.InternalScanner; 49 import org.apache.hadoop.hbase.regionserver.KeyValueScanner; 50 import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress; 51 import org.apache.hadoop.hbase.regionserver.OperationStatus; 52 import org.apache.hadoop.hbase.regionserver.RegionScanner; 53 import org.apache.hadoop.hbase.regionserver.ScanType; 54 import org.apache.hadoop.hbase.regionserver.Store; 55 import org.apache.hadoop.hbase.regionserver.StoreFile; 56 import org.apache.hadoop.hbase.regionserver.StoreFileScanner; 57 import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest; 58 import org.apache.hadoop.hbase.regionserver.wal.HLogKey; 59 import org.apache.hadoop.hbase.regionserver.wal.WALEdit; 60 import org.apache.hadoop.hbase.util.Pair; 61 62 import com.google.common.collect.ImmutableList; 63 64 /** 65 * Coprocessors implement this interface to observe and mediate client actions 66 * on the region. 67 */ 68 @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) 69 @InterfaceStability.Evolving 70 public interface RegionObserver extends Coprocessor { 71 72 /** Mutation type for postMutationBeforeWAL hook */ 73 public enum MutationType { 74 APPEND, INCREMENT 75 } 76 77 /** 78 * Called before the region is reported as open to the master. 79 * @param c the environment provided by the region server 80 * @throws IOException if an error occurred on the coprocessor 81 */ 82 void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException; 83 84 /** 85 * Called after the region is reported as open to the master. 86 * @param c the environment provided by the region server 87 */ 88 void postOpen(final ObserverContext<RegionCoprocessorEnvironment> c); 89 90 /** 91 * Called after the log replay on the region is over. 92 * @param c the environment provided by the region server 93 */ 94 void postLogReplay(final ObserverContext<RegionCoprocessorEnvironment> c); 95 96 /** 97 * Called before a memstore is flushed to disk and prior to creating the scanner to read from 98 * the memstore. To override or modify how a memstore is flushed, 99 * implementing classes can return a new scanner to provide the KeyValues to be 100 * stored into the new {@code StoreFile} or null to perform the default processing. 101 * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 102 * effect in this hook. 103 * @param c the environment provided by the region server 104 * @param store the store being flushed 105 * @param memstoreScanner the scanner for the memstore that is flushed 106 * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain 107 * @return the scanner to use during the flush. {@code null} if the default implementation 108 * is to be used. 109 * @throws IOException if an error occurred on the coprocessor 110 */ 111 InternalScanner preFlushScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 112 final Store store, final KeyValueScanner memstoreScanner, final InternalScanner s) 113 throws IOException; 114 115 /** 116 * Called before the memstore is flushed to disk. 117 * @param c the environment provided by the region server 118 * @throws IOException if an error occurred on the coprocessor 119 * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead 120 */ 121 void preFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException; 122 123 /** 124 * Called before a Store's memstore is flushed to disk. 125 * @param c the environment provided by the region server 126 * @param store the store where compaction is being requested 127 * @param scanner the scanner over existing data used in the store file 128 * @return the scanner to use during compaction. Should not be {@code null} 129 * unless the implementation is writing new store files on its own. 130 * @throws IOException if an error occurred on the coprocessor 131 */ 132 InternalScanner preFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, 133 final InternalScanner scanner) throws IOException; 134 135 /** 136 * Called after the memstore is flushed to disk. 137 * @param c the environment provided by the region server 138 * @throws IOException if an error occurred on the coprocessor 139 * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead. 140 */ 141 void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException; 142 143 /** 144 * Called after a Store's memstore is flushed to disk. 145 * @param c the environment provided by the region server 146 * @param store the store being flushed 147 * @param resultFile the new store file written out during compaction 148 * @throws IOException if an error occurred on the coprocessor 149 */ 150 void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, 151 final StoreFile resultFile) throws IOException; 152 153 /** 154 * Called prior to selecting the {@link StoreFile StoreFiles} to compact from the list of 155 * available candidates. To alter the files used for compaction, you may mutate the passed in list 156 * of candidates. 157 * @param c the environment provided by the region server 158 * @param store the store where compaction is being requested 159 * @param candidates the store files currently available for compaction 160 * @param request custom compaction request 161 * @throws IOException if an error occurred on the coprocessor 162 */ 163 void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, 164 final Store store, final List<StoreFile> candidates, final CompactionRequest request) 165 throws IOException; 166 167 /** 168 * Called prior to selecting the {@link StoreFile}s to compact from the list of available 169 * candidates. To alter the files used for compaction, you may mutate the passed in list of 170 * candidates. 171 * @param c the environment provided by the region server 172 * @param store the store where compaction is being requested 173 * @param candidates the store files currently available for compaction 174 * @throws IOException if an error occurred on the coprocessor 175 * @deprecated Use {@link #preCompactSelection(ObserverContext, Store, List, CompactionRequest)} 176 * instead 177 */ 178 @Deprecated 179 void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, 180 final Store store, final List<StoreFile> candidates) throws IOException; 181 182 /** 183 * Called after the {@link StoreFile}s to compact have been selected from the available 184 * candidates. 185 * @param c the environment provided by the region server 186 * @param store the store being compacted 187 * @param selected the store files selected to compact 188 * @param request custom compaction request 189 */ 190 void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, 191 final Store store, final ImmutableList<StoreFile> selected, CompactionRequest request); 192 193 /** 194 * Called after the {@link StoreFile}s to compact have been selected from the available 195 * candidates. 196 * @param c the environment provided by the region server 197 * @param store the store being compacted 198 * @param selected the store files selected to compact 199 * @deprecated use {@link #postCompactSelection(ObserverContext, Store, ImmutableList, 200 * CompactionRequest)} instead. 201 */ 202 @Deprecated 203 void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c, 204 final Store store, final ImmutableList<StoreFile> selected); 205 206 /** 207 * Called prior to writing the {@link StoreFile}s selected for compaction into a new 208 * {@code StoreFile}. To override or modify the compaction process, implementing classes have two 209 * options: 210 * <ul> 211 * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned 212 * from this method. The custom scanner can then inspect {@link KeyValue}s from the wrapped 213 * scanner, applying its own policy to what gets written.</li> 214 * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a 215 * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations 216 * bypassing core compaction using this approach must write out new store files themselves or the 217 * existing data will no longer be available after compaction.</strong></li> 218 * </ul> 219 * @param c the environment provided by the region server 220 * @param store the store being compacted 221 * @param scanner the scanner over existing data used in the store file rewriting 222 * @param scanType type of Scan 223 * @param request the requested compaction 224 * @return the scanner to use during compaction. Should not be {@code null} unless the 225 * implementation is writing new store files on its own. 226 * @throws IOException if an error occurred on the coprocessor 227 */ 228 InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c, 229 final Store store, final InternalScanner scanner, final ScanType scanType, 230 CompactionRequest request) throws IOException; 231 232 /** 233 * Called prior to writing the {@link StoreFile}s selected for compaction into a new 234 * {@code StoreFile}. To override or modify the compaction process, implementing classes have two 235 * options: 236 * <ul> 237 * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned 238 * from this method. The custom scanner can then inspect {@link KeyValue}s from the wrapped 239 * scanner, applying its own policy to what gets written.</li> 240 * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a 241 * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations 242 * bypassing core compaction using this approach must write out new store files themselves or the 243 * existing data will no longer be available after compaction.</strong></li> 244 * </ul> 245 * @param c the environment provided by the region server 246 * @param store the store being compacted 247 * @param scanner the scanner over existing data used in the store file rewriting 248 * @param scanType type of Scan 249 * @return the scanner to use during compaction. Should not be {@code null} unless the 250 * implementation is writing new store files on its own. 251 * @throws IOException if an error occurred on the coprocessor 252 * @deprecated use 253 * {@link #preCompact(ObserverContext, Store, InternalScanner, 254 * ScanType, CompactionRequest)} instead 255 */ 256 @Deprecated 257 InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c, 258 final Store store, final InternalScanner scanner, final ScanType scanType) throws IOException; 259 260 /** 261 * Called prior to writing the {@link StoreFile}s selected for compaction into a new 262 * {@code StoreFile} and prior to creating the scanner used to read the input files. To override 263 * or modify the compaction process, implementing classes can return a new scanner to provide the 264 * KeyValues to be stored into the new {@code StoreFile} or null to perform the default 265 * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 266 * effect in this hook. 267 * @param c the environment provided by the region server 268 * @param store the store being compacted 269 * @param scanners the list {@link StoreFileScanner}s to be read from 270 * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction 271 * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store 272 * files 273 * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain 274 * @param request the requested compaction 275 * @return the scanner to use during compaction. {@code null} if the default implementation is to 276 * be used. 277 * @throws IOException if an error occurred on the coprocessor 278 */ 279 InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 280 final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType, 281 final long earliestPutTs, final InternalScanner s, CompactionRequest request) 282 throws IOException; 283 284 /** 285 * Called prior to writing the {@link StoreFile}s selected for compaction into a new 286 * {@code StoreFile} and prior to creating the scanner used to read the input files. To override 287 * or modify the compaction process, implementing classes can return a new scanner to provide the 288 * KeyValues to be stored into the new {@code StoreFile} or null to perform the default 289 * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 290 * effect in this hook. 291 * @param c the environment provided by the region server 292 * @param store the store being compacted 293 * @param scanners the list {@link StoreFileScanner}s to be read from 294 * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction 295 * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store 296 * files 297 * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain 298 * @return the scanner to use during compaction. {@code null} if the default implementation is to 299 * be used. 300 * @throws IOException if an error occurred on the coprocessor 301 * @deprecated Use 302 * {@link #preCompactScannerOpen(ObserverContext, Store, List, ScanType, long, 303 * InternalScanner, CompactionRequest)} instead. 304 */ 305 @Deprecated 306 InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 307 final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType, 308 final long earliestPutTs, final InternalScanner s) throws IOException; 309 310 /** 311 * Called after compaction has completed and the new store file has been moved in to place. 312 * @param c the environment provided by the region server 313 * @param store the store being compacted 314 * @param resultFile the new store file written out during compaction 315 * @param request the requested compaction 316 * @throws IOException if an error occurred on the coprocessor 317 */ 318 void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, 319 StoreFile resultFile, CompactionRequest request) throws IOException; 320 321 /** 322 * Called after compaction has completed and the new store file has been moved in to place. 323 * @param c the environment provided by the region server 324 * @param store the store being compacted 325 * @param resultFile the new store file written out during compaction 326 * @throws IOException if an error occurred on the coprocessor 327 * @deprecated Use {@link #postCompact(ObserverContext, Store, StoreFile, CompactionRequest)} 328 * instead 329 */ 330 @Deprecated 331 void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store, 332 StoreFile resultFile) throws IOException; 333 334 /** 335 * Called before the region is split. 336 * @param c the environment provided by the region server 337 * (e.getRegion() returns the parent region) 338 * @throws IOException if an error occurred on the coprocessor 339 * @deprecated Use preSplit( 340 * final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow) 341 */ 342 void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException; 343 344 /** 345 * Called before the region is split. 346 * @param c the environment provided by the region server 347 * (e.getRegion() returns the parent region) 348 * @throws IOException if an error occurred on the coprocessor 349 */ 350 void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow) 351 throws IOException; 352 353 /** 354 * Called after the region is split. 355 * @param c the environment provided by the region server 356 * (e.getRegion() returns the parent region) 357 * @param l the left daughter region 358 * @param r the right daughter region 359 * @throws IOException if an error occurred on the coprocessor 360 * @deprecated Use postCompleteSplit() instead 361 */ 362 void postSplit(final ObserverContext<RegionCoprocessorEnvironment> c, final HRegion l, 363 final HRegion r) throws IOException; 364 365 /** 366 * This will be called before PONR step as part of split transaction. Calling 367 * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} rollback the split 368 * @param ctx 369 * @param splitKey 370 * @param metaEntries 371 * @throws IOException 372 */ 373 void preSplitBeforePONR(final ObserverContext<RegionCoprocessorEnvironment> ctx, 374 byte[] splitKey, List<Mutation> metaEntries) throws IOException; 375 376 377 /** 378 * This will be called after PONR step as part of split transaction 379 * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 380 * effect in this hook. 381 * @param ctx 382 * @throws IOException 383 */ 384 void preSplitAfterPONR(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException; 385 386 /** 387 * This will be called before the roll back of the split region is completed 388 * @param ctx 389 * @throws IOException 390 */ 391 void preRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException; 392 393 /** 394 * This will be called after the roll back of the split region is completed 395 * @param ctx 396 * @throws IOException 397 */ 398 void postRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) 399 throws IOException; 400 401 /** 402 * Called after any split request is processed. This will be called irrespective of success or 403 * failure of the split. 404 * @param ctx 405 * @throws IOException 406 */ 407 void postCompleteSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) 408 throws IOException; 409 /** 410 * Called before the region is reported as closed to the master. 411 * @param c the environment provided by the region server 412 * @param abortRequested true if the region server is aborting 413 * @throws IOException 414 */ 415 void preClose(final ObserverContext<RegionCoprocessorEnvironment> c, 416 boolean abortRequested) throws IOException; 417 418 /** 419 * Called after the region is reported as closed to the master. 420 * @param c the environment provided by the region server 421 * @param abortRequested true if the region server is aborting 422 */ 423 void postClose(final ObserverContext<RegionCoprocessorEnvironment> c, 424 boolean abortRequested); 425 426 /** 427 * Called before a client makes a GetClosestRowBefore request. 428 * <p> 429 * Call CoprocessorEnvironment#bypass to skip default actions 430 * <p> 431 * Call CoprocessorEnvironment#complete to skip any subsequent chained 432 * coprocessors 433 * @param c the environment provided by the region server 434 * @param row the row 435 * @param family the family 436 * @param result The result to return to the client if default processing 437 * is bypassed. Can be modified. Will not be used if default processing 438 * is not bypassed. 439 * @throws IOException if an error occurred on the coprocessor 440 */ 441 void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c, 442 final byte [] row, final byte [] family, final Result result) 443 throws IOException; 444 445 /** 446 * Called after a client makes a GetClosestRowBefore request. 447 * <p> 448 * Call CoprocessorEnvironment#complete to skip any subsequent chained 449 * coprocessors 450 * @param c the environment provided by the region server 451 * @param row the row 452 * @param family the desired family 453 * @param result the result to return to the client, modify as necessary 454 * @throws IOException if an error occurred on the coprocessor 455 */ 456 void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c, 457 final byte [] row, final byte [] family, final Result result) 458 throws IOException; 459 460 /** 461 * Called before the client performs a Get 462 * <p> 463 * Call CoprocessorEnvironment#bypass to skip default actions 464 * <p> 465 * Call CoprocessorEnvironment#complete to skip any subsequent chained 466 * coprocessors 467 * @param c the environment provided by the region server 468 * @param get the Get request 469 * @param result The result to return to the client if default processing 470 * is bypassed. Can be modified. Will not be used if default processing 471 * is not bypassed. 472 * @throws IOException if an error occurred on the coprocessor 473 */ 474 void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 475 final List<Cell> result) 476 throws IOException; 477 478 /** 479 * WARNING: please override preGetOp instead of this method. This is to maintain some 480 * compatibility and to ease the transition from 0.94 -> 0.96. 481 */ 482 @Deprecated 483 void preGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 484 final List<KeyValue> result) 485 throws IOException; 486 487 /** 488 * Called after the client performs a Get 489 * <p> 490 * Call CoprocessorEnvironment#complete to skip any subsequent chained 491 * coprocessors 492 * @param c the environment provided by the region server 493 * @param get the Get request 494 * @param result the result to return to the client, modify as necessary 495 * @throws IOException if an error occurred on the coprocessor 496 */ 497 void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 498 final List<Cell> result) 499 throws IOException; 500 501 /** 502 * WARNING: please override postGetOp instead of this method. This is to maintain some 503 * compatibility and to ease the transition from 0.94 -> 0.96. 504 */ 505 @Deprecated 506 void postGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 507 final List<KeyValue> result) 508 throws IOException; 509 510 /** 511 * Called before the client tests for existence using a Get. 512 * <p> 513 * Call CoprocessorEnvironment#bypass to skip default actions 514 * <p> 515 * Call CoprocessorEnvironment#complete to skip any subsequent chained 516 * coprocessors 517 * @param c the environment provided by the region server 518 * @param get the Get request 519 * @param exists 520 * @return the value to return to the client if bypassing default processing 521 * @throws IOException if an error occurred on the coprocessor 522 */ 523 boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 524 final boolean exists) 525 throws IOException; 526 527 /** 528 * Called after the client tests for existence using a Get. 529 * <p> 530 * Call CoprocessorEnvironment#complete to skip any subsequent chained 531 * coprocessors 532 * @param c the environment provided by the region server 533 * @param get the Get request 534 * @param exists the result returned by the region server 535 * @return the result to return to the client 536 * @throws IOException if an error occurred on the coprocessor 537 */ 538 boolean postExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get, 539 final boolean exists) 540 throws IOException; 541 542 /** 543 * Called before the client stores a value. 544 * <p> 545 * Call CoprocessorEnvironment#bypass to skip default actions 546 * <p> 547 * Call CoprocessorEnvironment#complete to skip any subsequent chained 548 * coprocessors 549 * @param c the environment provided by the region server 550 * @param put The Put object 551 * @param edit The WALEdit object that will be written to the wal 552 * @param durability Persistence guarantee for this Put 553 * @throws IOException if an error occurred on the coprocessor 554 */ 555 void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, 556 final Put put, final WALEdit edit, final Durability durability) 557 throws IOException; 558 559 /** 560 * Called after the client stores a value. 561 * <p> 562 * Call CoprocessorEnvironment#complete to skip any subsequent chained 563 * coprocessors 564 * @param c the environment provided by the region server 565 * @param put The Put object 566 * @param edit The WALEdit object for the wal 567 * @param durability Persistence guarantee for this Put 568 * @throws IOException if an error occurred on the coprocessor 569 */ 570 void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 571 final Put put, final WALEdit edit, final Durability durability) 572 throws IOException; 573 574 /** 575 * Called before the client deletes a value. 576 * <p> 577 * Call CoprocessorEnvironment#bypass to skip default actions 578 * <p> 579 * Call CoprocessorEnvironment#complete to skip any subsequent chained 580 * coprocessors 581 * @param c the environment provided by the region server 582 * @param delete The Delete object 583 * @param edit The WALEdit object for the wal 584 * @param durability Persistence guarantee for this Delete 585 * @throws IOException if an error occurred on the coprocessor 586 */ 587 void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 588 final Delete delete, final WALEdit edit, final Durability durability) 589 throws IOException; 590 591 /** 592 * Called after the client deletes a value. 593 * <p> 594 * Call CoprocessorEnvironment#complete to skip any subsequent chained 595 * coprocessors 596 * @param c the environment provided by the region server 597 * @param delete The Delete object 598 * @param edit The WALEdit object for the wal 599 * @param durability Persistence guarantee for this Delete 600 * @throws IOException if an error occurred on the coprocessor 601 */ 602 void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 603 final Delete delete, final WALEdit edit, final Durability durability) 604 throws IOException; 605 606 /** 607 * This will be called for every batch mutation operation happening at the server. This will be 608 * called after acquiring the locks on the mutating rows and after applying the proper timestamp 609 * for each Mutation at the server. The batch may contain Put/Delete. By setting OperationStatus 610 * of Mutations ({@link MiniBatchOperationInProgress#setOperationStatus(int, OperationStatus)}), 611 * {@link RegionObserver} can make HRegion to skip these Mutations. 612 * @param c the environment provided by the region server 613 * @param miniBatchOp batch of Mutations getting applied to region. 614 * @throws IOException if an error occurred on the coprocessor 615 */ 616 void preBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c, 617 final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException; 618 619 /** 620 * This will be called after applying a batch of Mutations on a region. The Mutations are added to 621 * memstore and WAL. 622 * @param c the environment provided by the region server 623 * @param miniBatchOp batch of Mutations applied to region. 624 * @throws IOException if an error occurred on the coprocessor 625 */ 626 void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c, 627 final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException; 628 629 /** 630 * This will be called for region operations where read lock is acquired in 631 * {@link HRegion#startRegionOperation()}. 632 * @param ctx 633 * @param operation The operation is about to be taken on the region 634 * @throws IOException 635 */ 636 void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, 637 Operation operation) throws IOException; 638 639 /** 640 * Called after releasing read lock in {@link HRegion#closeRegionOperation(Operation)}. 641 * @param ctx 642 * @param operation 643 * @throws IOException 644 */ 645 void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx, 646 Operation operation) throws IOException; 647 648 /** 649 * Called after the completion of batch put/delete and will be called even if the batch operation 650 * fails 651 * @param ctx 652 * @param miniBatchOp 653 * @param success true if batch operation is successful otherwise false. 654 * @throws IOException 655 */ 656 void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx, 657 MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException; 658 659 /** 660 * Called before checkAndPut 661 * <p> 662 * Call CoprocessorEnvironment#bypass to skip default actions 663 * <p> 664 * Call CoprocessorEnvironment#complete to skip any subsequent chained 665 * coprocessors 666 * @param c the environment provided by the region server 667 * @param row row to check 668 * @param family column family 669 * @param qualifier column qualifier 670 * @param compareOp the comparison operation 671 * @param comparator the comparator 672 * @param put data to put if check succeeds 673 * @param result 674 * @return the return value to return to client if bypassing default 675 * processing 676 * @throws IOException if an error occurred on the coprocessor 677 */ 678 boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c, 679 final byte [] row, final byte [] family, final byte [] qualifier, 680 final CompareOp compareOp, final ByteArrayComparable comparator, 681 final Put put, final boolean result) 682 throws IOException; 683 684 /** 685 * Called after checkAndPut 686 * <p> 687 * Call CoprocessorEnvironment#complete to skip any subsequent chained 688 * coprocessors 689 * @param c the environment provided by the region server 690 * @param row row to check 691 * @param family column family 692 * @param qualifier column qualifier 693 * @param compareOp the comparison operation 694 * @param comparator the comparator 695 * @param put data to put if check succeeds 696 * @param result from the checkAndPut 697 * @return the possibly transformed return value to return to client 698 * @throws IOException if an error occurred on the coprocessor 699 */ 700 boolean postCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c, 701 final byte [] row, final byte [] family, final byte [] qualifier, 702 final CompareOp compareOp, final ByteArrayComparable comparator, 703 final Put put, final boolean result) 704 throws IOException; 705 706 /** 707 * Called before checkAndDelete 708 * <p> 709 * Call CoprocessorEnvironment#bypass to skip default actions 710 * <p> 711 * Call CoprocessorEnvironment#complete to skip any subsequent chained 712 * coprocessors 713 * @param c the environment provided by the region server 714 * @param row row to check 715 * @param family column family 716 * @param qualifier column qualifier 717 * @param compareOp the comparison operation 718 * @param comparator the comparator 719 * @param delete delete to commit if check succeeds 720 * @param result 721 * @return the value to return to client if bypassing default processing 722 * @throws IOException if an error occurred on the coprocessor 723 */ 724 boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 725 final byte [] row, final byte [] family, final byte [] qualifier, 726 final CompareOp compareOp, final ByteArrayComparable comparator, 727 final Delete delete, final boolean result) 728 throws IOException; 729 730 /** 731 * Called after checkAndDelete 732 * <p> 733 * Call CoprocessorEnvironment#complete to skip any subsequent chained 734 * coprocessors 735 * @param c the environment provided by the region server 736 * @param row row to check 737 * @param family column family 738 * @param qualifier column qualifier 739 * @param compareOp the comparison operation 740 * @param comparator the comparator 741 * @param delete delete to commit if check succeeds 742 * @param result from the CheckAndDelete 743 * @return the possibly transformed returned value to return to client 744 * @throws IOException if an error occurred on the coprocessor 745 */ 746 boolean postCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 747 final byte [] row, final byte [] family, final byte [] qualifier, 748 final CompareOp compareOp, final ByteArrayComparable comparator, 749 final Delete delete, final boolean result) 750 throws IOException; 751 752 /** 753 * Called before incrementColumnValue 754 * <p> 755 * Call CoprocessorEnvironment#bypass to skip default actions 756 * <p> 757 * Call CoprocessorEnvironment#complete to skip any subsequent chained 758 * coprocessors 759 * @param c the environment provided by the region server 760 * @param row row to check 761 * @param family column family 762 * @param qualifier column qualifier 763 * @param amount long amount to increment 764 * @param writeToWAL true if the change should be written to the WAL 765 * @return value to return to the client if bypassing default processing 766 * @throws IOException if an error occurred on the coprocessor 767 * @deprecated This hook is no longer called by the RegionServer 768 */ 769 @Deprecated 770 long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c, 771 final byte [] row, final byte [] family, final byte [] qualifier, 772 final long amount, final boolean writeToWAL) 773 throws IOException; 774 775 /** 776 * Called after incrementColumnValue 777 * <p> 778 * Call CoprocessorEnvironment#complete to skip any subsequent chained 779 * coprocessors 780 * @param c the environment provided by the region server 781 * @param row row to check 782 * @param family column family 783 * @param qualifier column qualifier 784 * @param amount long amount to increment 785 * @param writeToWAL true if the change should be written to the WAL 786 * @param result the result returned by incrementColumnValue 787 * @return the result to return to the client 788 * @throws IOException if an error occurred on the coprocessor 789 * @deprecated This hook is no longer called by the RegionServer 790 */ 791 @Deprecated 792 long postIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c, 793 final byte [] row, final byte [] family, final byte [] qualifier, 794 final long amount, final boolean writeToWAL, final long result) 795 throws IOException; 796 797 /** 798 * Called before Append 799 * <p> 800 * Call CoprocessorEnvironment#bypass to skip default actions 801 * <p> 802 * Call CoprocessorEnvironment#complete to skip any subsequent chained 803 * coprocessors 804 * @param c the environment provided by the region server 805 * @param append Append object 806 * @return result to return to the client if bypassing default processing 807 * @throws IOException if an error occurred on the coprocessor 808 */ 809 Result preAppend(final ObserverContext<RegionCoprocessorEnvironment> c, 810 final Append append) 811 throws IOException; 812 813 /** 814 * Called after Append 815 * <p> 816 * Call CoprocessorEnvironment#complete to skip any subsequent chained 817 * coprocessors 818 * @param c the environment provided by the region server 819 * @param append Append object 820 * @param result the result returned by increment 821 * @return the result to return to the client 822 * @throws IOException if an error occurred on the coprocessor 823 */ 824 Result postAppend(final ObserverContext<RegionCoprocessorEnvironment> c, 825 final Append append, final Result result) 826 throws IOException; 827 828 /** 829 * Called before Increment 830 * <p> 831 * Call CoprocessorEnvironment#bypass to skip default actions 832 * <p> 833 * Call CoprocessorEnvironment#complete to skip any subsequent chained 834 * coprocessors 835 * @param c the environment provided by the region server 836 * @param increment increment object 837 * @return result to return to the client if bypassing default processing 838 * @throws IOException if an error occurred on the coprocessor 839 */ 840 Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, 841 final Increment increment) 842 throws IOException; 843 844 /** 845 * Called after increment 846 * <p> 847 * Call CoprocessorEnvironment#complete to skip any subsequent chained 848 * coprocessors 849 * @param c the environment provided by the region server 850 * @param increment increment object 851 * @param result the result returned by increment 852 * @return the result to return to the client 853 * @throws IOException if an error occurred on the coprocessor 854 */ 855 Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c, 856 final Increment increment, final Result result) 857 throws IOException; 858 859 /** 860 * Called before the client opens a new scanner. 861 * <p> 862 * Call CoprocessorEnvironment#bypass to skip default actions 863 * <p> 864 * Call CoprocessorEnvironment#complete to skip any subsequent chained 865 * coprocessors 866 * @param c the environment provided by the region server 867 * @param scan the Scan specification 868 * @param s if not null, the base scanner 869 * @return an RegionScanner instance to use instead of the base scanner if 870 * overriding default behavior, null otherwise 871 * @throws IOException if an error occurred on the coprocessor 872 */ 873 RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 874 final Scan scan, final RegionScanner s) 875 throws IOException; 876 877 /** 878 * Called before a store opens a new scanner. 879 * This hook is called when a "user" scanner is opened. 880 * <p> 881 * See {@link #preFlushScannerOpen(ObserverContext, Store, KeyValueScanner, InternalScanner)} 882 * and {@link #preCompactScannerOpen(ObserverContext, 883 * Store, List, ScanType, long, InternalScanner)} 884 * to override scanners created for flushes or compactions, resp. 885 * <p> 886 * Call CoprocessorEnvironment#complete to skip any subsequent chained 887 * coprocessors. 888 * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 889 * effect in this hook. 890 * @param c the environment provided by the region server 891 * @param store the store being scanned 892 * @param scan the Scan specification 893 * @param targetCols columns to be used in the scanner 894 * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain 895 * @return a KeyValueScanner instance to use or {@code null} to use the default implementation 896 * @throws IOException if an error occurred on the coprocessor 897 */ 898 KeyValueScanner preStoreScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 899 final Store store, final Scan scan, final NavigableSet<byte[]> targetCols, 900 final KeyValueScanner s) throws IOException; 901 902 /** 903 * Called after the client opens a new scanner. 904 * <p> 905 * Call CoprocessorEnvironment#complete to skip any subsequent chained 906 * coprocessors 907 * @param c the environment provided by the region server 908 * @param scan the Scan specification 909 * @param s if not null, the base scanner 910 * @return the scanner instance to use 911 * @throws IOException if an error occurred on the coprocessor 912 */ 913 RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c, 914 final Scan scan, final RegionScanner s) 915 throws IOException; 916 917 /** 918 * Called before the client asks for the next row on a scanner. 919 * <p> 920 * Call CoprocessorEnvironment#bypass to skip default actions 921 * <p> 922 * Call CoprocessorEnvironment#complete to skip any subsequent chained 923 * coprocessors 924 * @param c the environment provided by the region server 925 * @param s the scanner 926 * @param result The result to return to the client if default processing 927 * is bypassed. Can be modified. Will not be returned if default processing 928 * is not bypassed. 929 * @param limit the maximum number of results to return 930 * @param hasNext the 'has more' indication 931 * @return 'has more' indication that should be sent to client 932 * @throws IOException if an error occurred on the coprocessor 933 */ 934 boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, 935 final InternalScanner s, final List<Result> result, 936 final int limit, final boolean hasNext) 937 throws IOException; 938 939 /** 940 * Called after the client asks for the next row on a scanner. 941 * <p> 942 * Call CoprocessorEnvironment#complete to skip any subsequent chained 943 * coprocessors 944 * @param c the environment provided by the region server 945 * @param s the scanner 946 * @param result the result to return to the client, can be modified 947 * @param limit the maximum number of results to return 948 * @param hasNext the 'has more' indication 949 * @return 'has more' indication that should be sent to client 950 * @throws IOException if an error occurred on the coprocessor 951 */ 952 boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c, 953 final InternalScanner s, final List<Result> result, final int limit, 954 final boolean hasNext) 955 throws IOException; 956 957 /** 958 * This will be called by the scan flow when the current scanned row is being filtered out by the 959 * filter. The filter may be filtering out the row via any of the below scenarios 960 * <ol> 961 * <li> 962 * <code>boolean filterRowKey(byte [] buffer, int offset, int length)</code> returning true</li> 963 * <li> 964 * <code>boolean filterRow()</code> returning true</li> 965 * <li> 966 * <code>void filterRow(List<KeyValue> kvs)</code> removing all the kvs from the passed List</li> 967 * </ol> 968 * @param c the environment provided by the region server 969 * @param s the scanner 970 * @param currentRow The current rowkey which got filtered out 971 * @param offset offset to rowkey 972 * @param length length of rowkey 973 * @param hasMore the 'has more' indication 974 * @return whether more rows are available for the scanner or not 975 * @throws IOException 976 */ 977 boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> c, 978 final InternalScanner s, final byte[] currentRow, final int offset, final short length, 979 final boolean hasMore) throws IOException; 980 981 /** 982 * Called before the client closes a scanner. 983 * <p> 984 * Call CoprocessorEnvironment#bypass to skip default actions 985 * <p> 986 * Call CoprocessorEnvironment#complete to skip any subsequent chained 987 * coprocessors 988 * @param c the environment provided by the region server 989 * @param s the scanner 990 * @throws IOException if an error occurred on the coprocessor 991 */ 992 void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, 993 final InternalScanner s) 994 throws IOException; 995 996 /** 997 * Called after the client closes a scanner. 998 * <p> 999 * Call CoprocessorEnvironment#complete to skip any subsequent chained 1000 * coprocessors 1001 * @param c the environment provided by the region server 1002 * @param s the scanner 1003 * @throws IOException if an error occurred on the coprocessor 1004 */ 1005 void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c, 1006 final InternalScanner s) 1007 throws IOException; 1008 1009 /** 1010 * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit} 1011 * replayed for this region. 1012 * 1013 * @param ctx 1014 * @param info 1015 * @param logKey 1016 * @param logEdit 1017 * @throws IOException 1018 */ 1019 void preWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1020 HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException; 1021 1022 /** 1023 * Called after a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit} 1024 * replayed for this region. 1025 * 1026 * @param ctx 1027 * @param info 1028 * @param logKey 1029 * @param logEdit 1030 * @throws IOException 1031 */ 1032 void postWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1033 HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException; 1034 1035 /** 1036 * Called before bulkLoadHFile. Users can create a StoreFile instance to 1037 * access the contents of a HFile. 1038 * 1039 * @param ctx 1040 * @param familyPaths pairs of { CF, HFile path } submitted for bulk load. Adding 1041 * or removing from this list will add or remove HFiles to be bulk loaded. 1042 * @throws IOException 1043 */ 1044 void preBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1045 List<Pair<byte[], String>> familyPaths) throws IOException; 1046 1047 /** 1048 * Called after bulkLoadHFile. 1049 * 1050 * @param ctx 1051 * @param familyPaths pairs of { CF, HFile path } submitted for bulk load 1052 * @param hasLoaded whether the bulkLoad was successful 1053 * @return the new value of hasLoaded 1054 * @throws IOException 1055 */ 1056 boolean postBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1057 List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException; 1058 1059 /** 1060 * Called before creation of Reader for a store file. 1061 * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 1062 * effect in this hook. 1063 * 1064 * @param ctx the environment provided by the region server 1065 * @param fs fileystem to read from 1066 * @param p path to the file 1067 * @param in {@link FSDataInputStreamWrapper} 1068 * @param size Full size of the file 1069 * @param cacheConf 1070 * @param r original reference file. This will be not null only when reading a split file. 1071 * @param reader the base reader, if not {@code null}, from previous RegionObserver in the chain 1072 * @return a Reader instance to use instead of the base reader if overriding 1073 * default behavior, null otherwise 1074 * @throws IOException 1075 */ 1076 StoreFile.Reader preStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1077 final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size, 1078 final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException; 1079 1080 /** 1081 * Called after the creation of Reader for a store file. 1082 * 1083 * @param ctx the environment provided by the region server 1084 * @param fs fileystem to read from 1085 * @param p path to the file 1086 * @param in {@link FSDataInputStreamWrapper} 1087 * @param size Full size of the file 1088 * @param cacheConf 1089 * @param r original reference file. This will be not null only when reading a split file. 1090 * @param reader the base reader instance 1091 * @return The reader to use 1092 * @throws IOException 1093 */ 1094 StoreFile.Reader postStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx, 1095 final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size, 1096 final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException; 1097 1098 /** 1099 * Called after a new cell has been created during an increment operation, but before 1100 * it is committed to the WAL or memstore. 1101 * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no 1102 * effect in this hook. 1103 * @param ctx the environment provided by the region server 1104 * @param opType the operation type 1105 * @param mutation the current mutation 1106 * @param oldCell old cell containing previous value 1107 * @param newCell the new cell containing the computed value 1108 * @return the new cell, possibly changed 1109 * @throws IOException 1110 */ 1111 Cell postMutationBeforeWAL(ObserverContext<RegionCoprocessorEnvironment> ctx, 1112 MutationType opType, Mutation mutation, Cell oldCell, Cell newCell) throws IOException; 1113 1114 /** 1115 * Called after the ScanQueryMatcher creates ScanDeleteTracker. Implementing 1116 * this hook would help in creating customised DeleteTracker and returning 1117 * the newly created DeleteTracker 1118 * 1119 * @param ctx the environment provided by the region server 1120 * @param delTracker the deleteTracker that is created by the QueryMatcher 1121 * @return the Delete Tracker 1122 * @throws IOException 1123 */ 1124 DeleteTracker postInstantiateDeleteTracker( 1125 final ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker) 1126 throws IOException; 1127 }