001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver;
019
020import java.io.IOException;
021import java.util.Collection;
022import java.util.List;
023import java.util.Map;
024
025import org.apache.hadoop.hbase.Cell;
026import org.apache.hadoop.hbase.CellComparator;
027import org.apache.hadoop.hbase.CompareOperator;
028import org.apache.hadoop.hbase.HBaseInterfaceAudience;
029import org.apache.hadoop.hbase.client.Append;
030import org.apache.hadoop.hbase.client.CheckAndMutate;
031import org.apache.hadoop.hbase.client.CheckAndMutateResult;
032import org.apache.hadoop.hbase.client.CompactionState;
033import org.apache.hadoop.hbase.client.Delete;
034import org.apache.hadoop.hbase.client.Get;
035import org.apache.hadoop.hbase.client.Increment;
036import org.apache.hadoop.hbase.client.Mutation;
037import org.apache.hadoop.hbase.client.Put;
038import org.apache.hadoop.hbase.client.RegionInfo;
039import org.apache.hadoop.hbase.client.Result;
040import org.apache.hadoop.hbase.client.RowMutations;
041import org.apache.hadoop.hbase.client.Scan;
042import org.apache.hadoop.hbase.client.TableDescriptor;
043import org.apache.hadoop.hbase.conf.ConfigurationObserver;
044import org.apache.hadoop.hbase.coprocessor.RegionCoprocessor;
045import org.apache.hadoop.hbase.filter.ByteArrayComparable;
046import org.apache.hadoop.hbase.filter.Filter;
047import org.apache.hadoop.hbase.io.TimeRange;
048import org.apache.hadoop.hbase.regionserver.compactions.CompactionLifeCycleTracker;
049import org.apache.yetus.audience.InterfaceAudience;
050import org.apache.yetus.audience.InterfaceStability;
051
052/**
053 * Region is a subset of HRegion with operations required for the {@link RegionCoprocessor
054 * Coprocessors}. The operations include ability to do mutations, requesting compaction, getting
055 * different counters/sizes, locking rows and getting access to {@linkplain Store}s.
056 */
057@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
058@InterfaceStability.Evolving
059public interface Region extends ConfigurationObserver {
060
061  ///////////////////////////////////////////////////////////////////////////
062  // Region state
063
064  /** @return region information for this region */
065  RegionInfo getRegionInfo();
066
067  /** @return table descriptor for this region */
068  TableDescriptor getTableDescriptor();
069
070  /** @return true if region is available (not closed and not closing) */
071  boolean isAvailable();
072
073  /** @return true if region is closed */
074  boolean isClosed();
075
076  /** @return True if closing process has started */
077  boolean isClosing();
078
079  /** @return True if region is read only */
080  boolean isReadOnly();
081
082  /** @return true if region is splittable */
083  boolean isSplittable();
084
085  /**
086   * @return true if region is mergeable
087   */
088  boolean isMergeable();
089
090  /**
091   * Return the list of Stores managed by this region
092   * <p>Use with caution.  Exposed for use of fixup utilities.
093   * @return a list of the Stores managed by this region
094   */
095  List<? extends Store> getStores();
096
097  /**
098   * Return the Store for the given family
099   * <p>Use with caution.  Exposed for use of fixup utilities.
100   * @return the Store for the given family
101   */
102  Store getStore(byte[] family);
103
104  /** @return list of store file names for the given families */
105  List<String> getStoreFileList(byte[][] columns);
106
107  /**
108   * Check the region's underlying store files, open the files that have not
109   * been opened yet, and remove the store file readers for store files no
110   * longer available.
111   * @throws IOException
112   */
113  boolean refreshStoreFiles() throws IOException;
114
115  /** @return the max sequence id of flushed data on this region; no edit in memory will have
116   * a sequence id that is less that what is returned here.
117   */
118  long getMaxFlushedSeqId();
119
120  /**
121   * This can be used to determine the last time all files of this region were major compacted.
122   * @param majorCompactionOnly Only consider HFile that are the result of major compaction
123   * @return the timestamp of the oldest HFile for all stores of this region
124   */
125  long getOldestHfileTs(boolean majorCompactionOnly) throws IOException;
126
127  /**
128   * @return map of column family names to max sequence id that was read from storage when this
129   * region was opened
130   */
131  public Map<byte[], Long> getMaxStoreSeqId();
132
133  /**
134   * @return The earliest time a store in the region was flushed. All
135   *         other stores in the region would have been flushed either at, or
136   *         after this time.
137   */
138  long getEarliestFlushTimeForAllStores();
139
140  ///////////////////////////////////////////////////////////////////////////
141  // Metrics
142
143  /** @return read requests count for this region */
144  long getReadRequestsCount();
145
146  /** @return filtered read requests count for this region */
147  long getFilteredReadRequestsCount();
148
149  /** @return write request count for this region */
150  long getWriteRequestsCount();
151
152  /**
153   * @return memstore size for this region, in bytes. It just accounts data size of cells added to
154   *         the memstores of this Region. Means size in bytes for key, value and tags within Cells.
155   *         It wont consider any java heap overhead for the cell objects or any other.
156   */
157  long getMemStoreDataSize();
158
159  /**
160   * @return memstore heap size for this region, in bytes. It accounts data size of cells
161   *         added to the memstores of this Region, as well as java heap overhead for the cell
162   *         objects or any other.
163   */
164  long getMemStoreHeapSize();
165
166  /**
167   * @return memstore off-heap size for this region, in bytes. It accounts data size of cells
168   *         added to the memstores of this Region, as well as overhead for the cell
169   *         objects or any other that is allocated off-heap.
170   */
171  long getMemStoreOffHeapSize();
172
173  /** @return the number of mutations processed bypassing the WAL */
174  long getNumMutationsWithoutWAL();
175
176  /** @return the size of data processed bypassing the WAL, in bytes */
177  long getDataInMemoryWithoutWAL();
178
179  /** @return the number of blocked requests */
180  long getBlockedRequestsCount();
181
182  /** @return the number of checkAndMutate guards that passed */
183  long getCheckAndMutateChecksPassed();
184
185  /** @return the number of failed checkAndMutate guards */
186  long getCheckAndMutateChecksFailed();
187
188  ///////////////////////////////////////////////////////////////////////////
189  // Locking
190
191  // Region read locks
192
193  /**
194   * Operation enum is used in {@link Region#startRegionOperation} and elsewhere to provide
195   * context for various checks.
196   */
197  enum Operation {
198    ANY, GET, PUT, DELETE, SCAN, APPEND, INCREMENT, SPLIT_REGION, MERGE_REGION, BATCH_MUTATE,
199    REPLAY_BATCH_MUTATE, COMPACT_REGION, REPLAY_EVENT, SNAPSHOT, COMPACT_SWITCH,
200    CHECK_AND_MUTATE
201  }
202
203  /**
204   * This method needs to be called before any public call that reads or
205   * modifies data.
206   * Acquires a read lock and checks if the region is closing or closed.
207   * <p>{@link #closeRegionOperation} MUST then always be called after
208   * the operation has completed, whether it succeeded or failed.
209   * @throws IOException
210   */
211  // TODO Exposing this and closeRegionOperation() as we have getRowLock() exposed.
212  // Remove if we get rid of exposing getRowLock().
213  void startRegionOperation() throws IOException;
214
215  /**
216   * This method needs to be called before any public call that reads or
217   * modifies data.
218   * Acquires a read lock and checks if the region is closing or closed.
219   * <p>{@link #closeRegionOperation} MUST then always be called after
220   * the operation has completed, whether it succeeded or failed.
221   * @param op The operation is about to be taken on the region
222   * @throws IOException
223   */
224  void startRegionOperation(Operation op) throws IOException;
225
226  /**
227   * Closes the region operation lock.
228   * @throws IOException
229   */
230  void closeRegionOperation() throws IOException;
231
232  /**
233   * Closes the region operation lock. This needs to be called in the finally block corresponding
234   * to the try block of {@link #startRegionOperation(Operation)}
235   * @throws IOException
236   */
237  void closeRegionOperation(Operation op) throws IOException;
238
239  // Row write locks
240
241  /**
242   * Row lock held by a given thread.
243   * One thread may acquire multiple locks on the same row simultaneously.
244   * The locks must be released by calling release() from the same thread.
245   */
246  public interface RowLock {
247    /**
248     * Release the given lock.  If there are no remaining locks held by the current thread
249     * then unlock the row and allow other threads to acquire the lock.
250     * @throws IllegalArgumentException if called by a different thread than the lock owning
251     *     thread
252     */
253    void release();
254  }
255
256  /**
257   *
258   * Get a row lock for the specified row. All locks are reentrant.
259   *
260   * Before calling this function make sure that a region operation has already been
261   * started (the calling thread has already acquired the region-close-guard lock).
262   * <p>
263   * The obtained locks should be released after use by {@link RowLock#release()}
264   * <p>
265   * NOTE: the boolean passed here has changed. It used to be a boolean that
266   * stated whether or not to wait on the lock. Now it is whether it an exclusive
267   * lock is requested.
268   *
269   * @param row The row actions will be performed against
270   * @param readLock is the lock reader or writer. True indicates that a non-exclusive
271   * lock is requested
272   * @see #startRegionOperation()
273   * @see #startRegionOperation(Operation)
274   */
275  // TODO this needs to be exposed as we have RowProcessor now. If RowProcessor is removed, we can
276  // remove this too..
277  RowLock getRowLock(byte[] row, boolean readLock) throws IOException;
278
279  ///////////////////////////////////////////////////////////////////////////
280  // Region operations
281
282  /**
283   * Perform one or more append operations on a row.
284   * @param append
285   * @return result of the operation
286   * @throws IOException
287   */
288  Result append(Append append) throws IOException;
289
290  /**
291   * Perform a batch of mutations.
292   * <p>
293   * Please do not operate on a same column of a single row in a batch, we will not consider the
294   * previous operation in the same batch when performing the operations in the batch.
295   *
296   * @param mutations the list of mutations
297   * @return an array of OperationStatus which internally contains the
298   *         OperationStatusCode and the exceptionMessage if any.
299   * @throws IOException
300   */
301  OperationStatus[] batchMutate(Mutation[] mutations)
302      throws IOException;
303
304  /**
305   * Atomically checks if a row/family/qualifier value matches the expected value and if it does,
306   * it performs the mutation. If the passed value is null, the lack of column value
307   * (ie: non-existence) is used. See checkAndRowMutate to do many checkAndPuts at a time on a
308   * single row.
309   * @param row to check
310   * @param family column family to check
311   * @param qualifier column qualifier to check
312   * @param op the comparison operator
313   * @param comparator the expected value
314   * @param mutation data to put if check succeeds
315   * @return true if mutation was applied, false otherwise
316   *
317   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
318   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
319   */
320  @Deprecated
321  default boolean checkAndMutate(byte [] row, byte [] family, byte [] qualifier, CompareOperator op,
322    ByteArrayComparable comparator, Mutation mutation) throws IOException {
323    return checkAndMutate(row, family, qualifier, op, comparator, TimeRange.allTime(), mutation);
324  }
325
326  /**
327   * Atomically checks if a row/family/qualifier value matches the expected value and if it does,
328   * it performs the mutation. If the passed value is null, the lack of column value
329   * (ie: non-existence) is used. See checkAndRowMutate to do many checkAndPuts at a time on a
330   * single row.
331   * @param row to check
332   * @param family column family to check
333   * @param qualifier column qualifier to check
334   * @param op the comparison operator
335   * @param comparator the expected value
336   * @param mutation data to put if check succeeds
337   * @param timeRange time range to check
338   * @return true if mutation was applied, false otherwise
339   *
340   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
341   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
342   */
343  @Deprecated
344  boolean checkAndMutate(byte [] row, byte [] family, byte [] qualifier, CompareOperator op,
345      ByteArrayComparable comparator, TimeRange timeRange, Mutation mutation) throws IOException;
346
347  /**
348   * Atomically checks if a row matches the filter and if it does, it performs the mutation. See
349   * checkAndRowMutate to do many checkAndPuts at a time on a single row.
350   * @param row to check
351   * @param filter the filter
352   * @param mutation data to put if check succeeds
353   * @return true if mutation was applied, false otherwise
354   *
355   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
356   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
357   */
358  @Deprecated
359  default boolean checkAndMutate(byte [] row, Filter filter, Mutation mutation)
360    throws IOException {
361    return checkAndMutate(row, filter, TimeRange.allTime(), mutation);
362  }
363
364  /**
365   * Atomically checks if a row value matches the filter and if it does, it performs the mutation.
366   * See checkAndRowMutate to do many checkAndPuts at a time on a single row.
367   * @param row to check
368   * @param filter the filter
369   * @param mutation data to put if check succeeds
370   * @param timeRange time range to check
371   * @return true if mutation was applied, false otherwise
372   *
373   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
374   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
375   */
376  @Deprecated
377  boolean checkAndMutate(byte [] row, Filter filter, TimeRange timeRange, Mutation mutation)
378    throws IOException;
379
380  /**
381   * Atomically checks if a row/family/qualifier value matches the expected values and if it does,
382   * it performs the row mutations. If the passed value is null, the lack of column value
383   * (ie: non-existence) is used. Use to do many mutations on a single row. Use checkAndMutate
384   * to do one checkAndMutate at a time.
385   * @param row to check
386   * @param family column family to check
387   * @param qualifier column qualifier to check
388   * @param op the comparison operator
389   * @param comparator the expected value
390   * @param mutations data to put if check succeeds
391   * @return true if mutations were applied, false otherwise
392   *
393   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
394   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
395   */
396  @Deprecated
397  default boolean checkAndRowMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator op,
398    ByteArrayComparable comparator, RowMutations mutations) throws IOException {
399    return checkAndRowMutate(row, family, qualifier, op, comparator, TimeRange.allTime(),
400      mutations);
401  }
402
403  /**
404   * Atomically checks if a row/family/qualifier value matches the expected values and if it does,
405   * it performs the row mutations. If the passed value is null, the lack of column value
406   * (ie: non-existence) is used. Use to do many mutations on a single row. Use checkAndMutate
407   * to do one checkAndMutate at a time.
408   * @param row to check
409   * @param family column family to check
410   * @param qualifier column qualifier to check
411   * @param op the comparison operator
412   * @param comparator the expected value
413   * @param mutations data to put if check succeeds
414   * @param timeRange time range to check
415   * @return true if mutations were applied, false otherwise
416   *
417   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
418   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
419   */
420  @Deprecated
421  boolean checkAndRowMutate(byte [] row, byte [] family, byte [] qualifier, CompareOperator op,
422      ByteArrayComparable comparator, TimeRange timeRange, RowMutations mutations)
423      throws IOException;
424
425  /**
426   * Atomically checks if a row matches the filter and if it does, it performs the row mutations.
427   * Use to do many mutations on a single row. Use checkAndMutate to do one checkAndMutate at a
428   * time.
429   * @param row to check
430   * @param filter the filter
431   * @param mutations data to put if check succeeds
432   * @return true if mutations were applied, false otherwise
433   *
434   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
435   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
436   */
437  @Deprecated
438  default boolean checkAndRowMutate(byte[] row, Filter filter, RowMutations mutations)
439    throws IOException {
440    return checkAndRowMutate(row, filter, TimeRange.allTime(), mutations);
441  }
442
443  /**
444   * Atomically checks if a row matches the filter and if it does, it performs the row mutations.
445   * Use to do many mutations on a single row. Use checkAndMutate to do one checkAndMutate at a
446   * time.
447   * @param row to check
448   * @param filter the filter
449   * @param mutations data to put if check succeeds
450   * @param timeRange time range to check
451   * @return true if mutations were applied, false otherwise
452   *
453   * @deprecated since 2.4.0 and will be removed in 4.0.0. Use
454   *   {@link #checkAndMutate(CheckAndMutate)}  instead.
455   */
456  @Deprecated
457  boolean checkAndRowMutate(byte [] row, Filter filter, TimeRange timeRange,
458    RowMutations mutations) throws IOException;
459
460  /**
461   * Atomically checks if a row matches the conditions and if it does, it performs the actions.
462   * Use to do many mutations on a single row. Use checkAndMutate to do one checkAndMutate at a
463   * time.
464   * @param checkAndMutate the CheckAndMutate object
465   * @return true if mutations were applied, false otherwise
466   * @throws IOException if an error occurred in this method
467   */
468  CheckAndMutateResult checkAndMutate(CheckAndMutate checkAndMutate) throws IOException;
469
470  /**
471   * Deletes the specified cells/row.
472   * @param delete
473   * @throws IOException
474   */
475  void delete(Delete delete) throws IOException;
476
477  /**
478   * Do a get based on the get parameter.
479   * @param get query parameters
480   * @return result of the operation
481   */
482  Result get(Get get) throws IOException;
483
484  /**
485   * Do a get based on the get parameter.
486   * @param get query parameters
487   * @param withCoprocessor invoke coprocessor or not. We don't want to
488   * always invoke cp.
489   * @return list of cells resulting from the operation
490   */
491  List<Cell> get(Get get, boolean withCoprocessor) throws IOException;
492
493  /**
494   * Return an iterator that scans over the HRegion, returning the indicated
495   * columns and rows specified by the {@link Scan}.
496   * <p>
497   * This Iterator must be closed by the caller.
498   *
499   * @param scan configured {@link Scan}
500   * @return RegionScanner
501   * @throws IOException read exceptions
502   */
503  RegionScanner getScanner(Scan scan) throws IOException;
504
505  /**
506   * Return an iterator that scans over the HRegion, returning the indicated columns and rows
507   * specified by the {@link Scan}. The scanner will also include the additional scanners passed
508   * along with the scanners for the specified Scan instance. Should be careful with the usage to
509   * pass additional scanners only within this Region
510   * <p>
511   * This Iterator must be closed by the caller.
512   *
513   * @param scan configured {@link Scan}
514   * @param additionalScanners Any additional scanners to be used
515   * @return RegionScanner
516   * @throws IOException read exceptions
517   */
518  RegionScanner getScanner(Scan scan, List<KeyValueScanner> additionalScanners) throws IOException;
519
520  /** The comparator to be used with the region */
521  CellComparator getCellComparator();
522
523  /**
524   * Perform one or more increment operations on a row.
525   * @param increment
526   * @return result of the operation
527   * @throws IOException
528   */
529  Result increment(Increment increment) throws IOException;
530
531  /**
532   * Performs multiple mutations atomically on a single row.
533   *
534   * @param mutations object that specifies the set of mutations to perform atomically
535   * @return results of Increment/Append operations. If no Increment/Append operations, it returns
536   *   null
537   * @throws IOException
538   */
539  Result mutateRow(RowMutations mutations) throws IOException;
540
541  /**
542   * Perform atomic mutations within the region.
543   *
544   * @param mutations The list of mutations to perform.
545   * <code>mutations</code> can contain operations for multiple rows.
546   * Caller has to ensure that all rows are contained in this region.
547   * @param rowsToLock Rows to lock
548   * @param nonceGroup Optional nonce group of the operation (client Id)
549   * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
550   * If multiple rows are locked care should be taken that
551   * <code>rowsToLock</code> is sorted in order to avoid deadlocks.
552   * @throws IOException
553   */
554  // TODO Should not be exposing with params nonceGroup, nonce. Change when doing the jira for
555  // Changing processRowsWithLocks and RowProcessor
556  void mutateRowsWithLocks(Collection<Mutation> mutations, Collection<byte[]> rowsToLock,
557      long nonceGroup, long nonce) throws IOException;
558
559  /**
560   * Performs atomic multiple reads and writes on a given row.
561   *
562   * @param processor The object defines the reads and writes to a row.
563   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. For customization, use
564   * Coprocessors instead.
565   */
566  @Deprecated
567  void processRowsWithLocks(RowProcessor<?,?> processor) throws IOException;
568
569  /**
570   * Performs atomic multiple reads and writes on a given row.
571   *
572   * @param processor The object defines the reads and writes to a row.
573   * @param nonceGroup Optional nonce group of the operation (client Id)
574   * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
575   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. For customization, use
576   * Coprocessors instead.
577   */
578  // TODO Should not be exposing with params nonceGroup, nonce. Change when doing the jira for
579  // Changing processRowsWithLocks and RowProcessor
580  @Deprecated
581  void processRowsWithLocks(RowProcessor<?,?> processor, long nonceGroup, long nonce)
582      throws IOException;
583
584  /**
585   * Performs atomic multiple reads and writes on a given row.
586   *
587   * @param processor The object defines the reads and writes to a row.
588   * @param timeout The timeout of the processor.process() execution
589   *                Use a negative number to switch off the time bound
590   * @param nonceGroup Optional nonce group of the operation (client Id)
591   * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
592   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. For customization, use
593   * Coprocessors instead.
594   */
595  // TODO Should not be exposing with params nonceGroup, nonce. Change when doing the jira for
596  // Changing processRowsWithLocks and RowProcessor
597  @Deprecated
598  void processRowsWithLocks(RowProcessor<?,?> processor, long timeout, long nonceGroup, long nonce)
599      throws IOException;
600
601  /**
602   * Puts some data in the table.
603   * @param put
604   * @throws IOException
605   */
606  void put(Put put) throws IOException;
607
608  ///////////////////////////////////////////////////////////////////////////
609  // Flushes, compactions, splits, etc.
610  // Wizards only, please
611
612  /**
613   * @return if a given region is in compaction now.
614   */
615  CompactionState getCompactionState();
616
617  /**
618   * Request compaction on this region.
619   */
620  void requestCompaction(String why, int priority, boolean major,
621      CompactionLifeCycleTracker tracker) throws IOException;
622
623  /**
624   * Request compaction for the given family
625   */
626  void requestCompaction(byte[] family, String why, int priority, boolean major,
627      CompactionLifeCycleTracker tracker) throws IOException;
628
629  /**
630   * Request flush on this region.
631   */
632  void requestFlush(FlushLifeCycleTracker tracker) throws IOException;
633
634  /**
635   * Wait for all current flushes of the region to complete
636   *
637   * @param timeout The maximum time to wait in milliseconds.
638   * @return False when timeout elapsed but flushes are not over. True when flushes are over within
639   * max wait time period.
640   */
641  boolean waitForFlushes(long timeout);
642}