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