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