From 9081a1e0de886fa33f445cf48e6a468571166c24 Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 18:12:38 +0900 Subject: [PATCH 1/7] HBASE-28599 ADD clone columnFamily and Qualifier logic in Increment mutation --- .../main/java/org/apache/hadoop/hbase/regionserver/HRegion.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index c55090d3a756..4dcf8ab58093 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -4041,6 +4041,8 @@ private static Get toGet(final Mutation mutation) throws IOException { get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } if (mutation instanceof Increment) { + Cell cell = cellScanner.current(); + get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); // Increment Increment increment = (Increment) mutation; get.setTimeRange(increment.getTimeRange().getMin(), increment.getTimeRange().getMax()); From 11364718fe68893cd5e02d75032ece8d63e1306d Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:22:30 +0900 Subject: [PATCH 2/7] Rollback 9081a1e0de886fa33f445cf48e6a468571166c24 --- .../hadoop/hbase/regionserver/HRegion.java | 3229 ++++++++++------- 1 file changed, 1863 insertions(+), 1366 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 4dcf8ab58093..62732f96fa7f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -222,65 +222,74 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.StoreDescriptor; /** - * Regions store data for a certain region of a table. It stores all columns for each row. A given + * Regions store data for a certain region of a table. It stores all columns for + * each row. A given * table consists of one or more Regions. *

* An Region is defined by its table and its key extent. *

- * Locking at the Region level serves only one purpose: preventing the region from being closed (and - * consequently split) while other operations are ongoing. Each row level operation obtains both a - * row lock and a region read lock for the duration of the operation. While a scanner is being - * constructed, getScanner holds a read lock. If the scanner is successfully constructed, it holds a - * read lock until it is closed. A close takes out a write lock and consequently will block for - * ongoing operations and will block new operations from starting while the close is in progress. + * Locking at the Region level serves only one purpose: preventing the region + * from being closed (and + * consequently split) while other operations are ongoing. Each row level + * operation obtains both a + * row lock and a region read lock for the duration of the operation. While a + * scanner is being + * constructed, getScanner holds a read lock. If the scanner is successfully + * constructed, it holds a + * read lock until it is closed. A close takes out a write lock and consequently + * will block for + * ongoing operations and will block new operations from starting while the + * close is in progress. */ @SuppressWarnings("deprecation") @InterfaceAudience.Private public class HRegion implements HeapSize, PropagatingConfigurationObserver, Region { private static final Logger LOG = LoggerFactory.getLogger(HRegion.class); - public static final String LOAD_CFS_ON_DEMAND_CONFIG_KEY = - "hbase.hregion.scan.loadColumnFamiliesOnDemand"; + public static final String LOAD_CFS_ON_DEMAND_CONFIG_KEY = "hbase.hregion.scan.loadColumnFamiliesOnDemand"; public static final String HBASE_MAX_CELL_SIZE_KEY = "hbase.server.keyvalue.maxsize"; public static final int DEFAULT_MAX_CELL_SIZE = 10485760; - public static final String HBASE_REGIONSERVER_MINIBATCH_SIZE = - "hbase.regionserver.minibatch.size"; + public static final String HBASE_REGIONSERVER_MINIBATCH_SIZE = "hbase.regionserver.minibatch.size"; public static final int DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE = 20000; public static final String WAL_HSYNC_CONF_KEY = "hbase.wal.hsync"; public static final boolean DEFAULT_WAL_HSYNC = false; /** Parameter name for compaction after bulkload */ - public static final String COMPACTION_AFTER_BULKLOAD_ENABLE = - "hbase.compaction.after.bulkload.enable"; + public static final String COMPACTION_AFTER_BULKLOAD_ENABLE = "hbase.compaction.after.bulkload.enable"; - /** Config for allow split when file count greater than the configured blocking file count */ - public static final String SPLIT_IGNORE_BLOCKING_ENABLED_KEY = - "hbase.hregion.split.ignore.blocking.enabled"; + /** + * Config for allow split when file count greater than the configured blocking + * file count + */ + public static final String SPLIT_IGNORE_BLOCKING_ENABLED_KEY = "hbase.hregion.split.ignore.blocking.enabled"; public static final String REGION_STORAGE_POLICY_KEY = "hbase.hregion.block.storage.policy"; public static final String DEFAULT_REGION_STORAGE_POLICY = "NONE"; /** - * This is for for using HRegion as a local storage, where we may put the recovered edits in a - * special place. Once this is set, we will only replay the recovered edits under this directory + * This is for for using HRegion as a local storage, where we may put the + * recovered edits in a + * special place. Once this is set, we will only replay the recovered edits + * under this directory * and ignore the original replay directory configs. */ - public static final String SPECIAL_RECOVERED_EDITS_DIR = - "hbase.hregion.special.recovered.edits.dir"; + public static final String SPECIAL_RECOVERED_EDITS_DIR = "hbase.hregion.special.recovered.edits.dir"; /** - * Mainly used for master local region, where we will replay the WAL file directly without - * splitting, so it is possible to have WAL files which are not closed cleanly, in this way, + * Mainly used for master local region, where we will replay the WAL file + * directly without + * splitting, so it is possible to have WAL files which are not closed cleanly, + * in this way, * hitting EOF is expected so should not consider it as a critical problem. */ - public static final String RECOVERED_EDITS_IGNORE_EOF = - "hbase.hregion.recovered.edits.ignore.eof"; + public static final String RECOVERED_EDITS_IGNORE_EOF = "hbase.hregion.recovered.edits.ignore.eof"; /** - * Whether to use {@link MetaCellComparator} even if we are not meta region. Used when creating + * Whether to use {@link MetaCellComparator} even if we are not meta region. + * Used when creating * master local region. */ public static final String USE_META_CELL_COMPARATOR = "hbase.region.use.meta.cell.comparator"; @@ -290,28 +299,35 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi final AtomicBoolean closed = new AtomicBoolean(false); /* - * Closing can take some time; use the closing flag if there is stuff we don't want to do while in - * closing state; e.g. like offer this region up to the master as a region to close if the + * Closing can take some time; use the closing flag if there is stuff we don't + * want to do while in + * closing state; e.g. like offer this region up to the master as a region to + * close if the * carrying regionserver is overloaded. Once set, it is never cleared. */ final AtomicBoolean closing = new AtomicBoolean(false); /** - * The max sequence id of flushed data on this region. There is no edit in memory that is less + * The max sequence id of flushed data on this region. There is no edit in + * memory that is less * that this sequence id. */ private volatile long maxFlushedSeqId = HConstants.NO_SEQNUM; /** - * Record the sequence id of last flush operation. Can be in advance of {@link #maxFlushedSeqId} - * when flushing a single column family. In this case, {@link #maxFlushedSeqId} will be older than + * Record the sequence id of last flush operation. Can be in advance of + * {@link #maxFlushedSeqId} + * when flushing a single column family. In this case, {@link #maxFlushedSeqId} + * will be older than * the oldest edit in memory. */ private volatile long lastFlushOpSeqId = HConstants.NO_SEQNUM; /** - * The sequence id of the last replayed open region event from the primary region. This is used to - * skip entries before this due to the possibility of replay edits coming out of order from + * The sequence id of the last replayed open region event from the primary + * region. This is used to + * skip entries before this due to the possibility of replay edits coming out of + * order from * replication. */ protected volatile long lastReplayedOpenRegionSeqId = -1L; @@ -326,11 +342,9 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // - the thread that owns the lock (allow reentrancy) // - reference count of (reentrant) locks held by the thread // - the row itself - private final ConcurrentHashMap lockedRows = - new ConcurrentHashMap<>(); + private final ConcurrentHashMap lockedRows = new ConcurrentHashMap<>(); - protected final Map stores = - new ConcurrentSkipListMap<>(Bytes.BYTES_RAWCOMPARATOR); + protected final Map stores = new ConcurrentSkipListMap<>(Bytes.BYTES_RAWCOMPARATOR); // TODO: account for each registered handler in HeapSize computation private Map coprocessorServiceHandlers = Maps.newHashMap(); @@ -378,7 +392,8 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi private Path regionWalDir; private FileSystem walFS; - // set to true if the region is restored from snapshot for reading by ClientSideRegionScanner + // set to true if the region is restored from snapshot for reading by + // ClientSideRegionScanner private boolean isRestoredRegion = false; public void setRestoredRegion(boolean restoredRegion) { @@ -426,7 +441,8 @@ public MetricsTableRequests getMetricsTableRequests() { private long openSeqNum = HConstants.NO_SEQNUM; /** - * The default setting for whether to enable on-demand CF loading for scan requests to this + * The default setting for whether to enable on-demand CF loading for scan + * requests to this * region. Requests can override it. */ private boolean isLoadingCfsOnDemandDefault = false; @@ -442,7 +458,8 @@ public MetricsTableRequests getMetricsTableRequests() { // The following map is populated when opening the region Map maxSeqIdInStores = new TreeMap<>(Bytes.BYTES_COMPARATOR); - // lock used to protect the replay operation for secondary replicas, so the below two fields does + // lock used to protect the replay operation for secondary replicas, so the + // below two fields does // not need to be volatile. private Lock replayLock; @@ -461,7 +478,8 @@ public MetricsTableRequests getMetricsTableRequests() { private final int minBlockSizeBytes; /** - * @return The smallest mvcc readPoint across all the scanners in this region. Writes older than + * @return The smallest mvcc readPoint across all the scanners in this region. + * Writes older than * this readPoint, are included in every read operation. */ public long getSmallestReadPoint() { @@ -480,7 +498,8 @@ public long getSmallestReadPoint() { } /* - * Data structure of write state flags used coordinating flushes, compactions and closes. + * Data structure of write state flags used coordinating flushes, compactions + * and closes. */ static class WriteState { // Set while a memstore flush is happening. @@ -493,12 +512,14 @@ static class WriteState { volatile boolean writesEnabled = true; // Set if region is read-only volatile boolean readOnly = false; - // whether the reads are enabled. This is different than readOnly, because readOnly is + // whether the reads are enabled. This is different than readOnly, because + // readOnly is // static in the lifetime of the region, while readsEnabled is dynamic volatile boolean readsEnabled = true; /** * Set flags that make this region read-only. + * * @param onOff flip value for region r/o setting */ synchronized void setReadOnly(final boolean onOff) { @@ -522,9 +543,12 @@ void setReadsEnabled(boolean readsEnabled) { } /** - * Objects from this class are created when flushing to describe all the different states that - * that method ends up in. The Result enum describes those states. The sequence id should only be - * specified if the flush was successful, and the failure message should only be specified if it + * Objects from this class are created when flushing to describe all the + * different states that + * that method ends up in. The Result enum describes those states. The sequence + * id should only be + * specified if the flush was successful, and the failure message should only be + * specified if it * didn't flush. */ public static class FlushResultImpl implements FlushResult { @@ -534,20 +558,25 @@ public static class FlushResultImpl implements FlushResult { final boolean wroteFlushWalMarker; /** - * Convenience constructor to use when the flush is successful, the failure message is set to + * Convenience constructor to use when the flush is successful, the failure + * message is set to * null. - * @param result Expecting FLUSHED_NO_COMPACTION_NEEDED or FLUSHED_COMPACTION_NEEDED. - * @param flushSequenceId Generated sequence id that comes right after the edits in the + * + * @param result Expecting FLUSHED_NO_COMPACTION_NEEDED or + * FLUSHED_COMPACTION_NEEDED. + * @param flushSequenceId Generated sequence id that comes right after the edits + * in the * memstores. */ FlushResultImpl(Result result, long flushSequenceId) { this(result, flushSequenceId, null, false); assert result == Result.FLUSHED_NO_COMPACTION_NEEDED - || result == Result.FLUSHED_COMPACTION_NEEDED; + || result == Result.FLUSHED_COMPACTION_NEEDED; } /** * Convenience constructor to use when we cannot flush. + * * @param result Expecting CANNOT_FLUSH_MEMSTORE_EMPTY or CANNOT_FLUSH. * @param failureReason Reason why we couldn't flush. */ @@ -558,12 +587,14 @@ public static class FlushResultImpl implements FlushResult { /** * Constructor with all the parameters. + * * @param result Any of the Result. - * @param flushSequenceId Generated sequence id if the memstores were flushed else -1. + * @param flushSequenceId Generated sequence id if the memstores were flushed + * else -1. * @param failureReason Reason why we couldn't flush, or null. */ FlushResultImpl(Result result, long flushSequenceId, String failureReason, - boolean wroteFlushMarker) { + boolean wroteFlushMarker) { this.result = result; this.flushSequenceId = flushSequenceId; this.failureReason = failureReason; @@ -571,19 +602,24 @@ public static class FlushResultImpl implements FlushResult { } /** - * Convenience method, the equivalent of checking if result is FLUSHED_NO_COMPACTION_NEEDED or + * Convenience method, the equivalent of checking if result is + * FLUSHED_NO_COMPACTION_NEEDED or * FLUSHED_NO_COMPACTION_NEEDED. + * * @return true if the memstores were flushed, else false. */ @Override public boolean isFlushSucceeded() { return result == Result.FLUSHED_NO_COMPACTION_NEEDED - || result == Result.FLUSHED_COMPACTION_NEEDED; + || result == Result.FLUSHED_COMPACTION_NEEDED; } /** - * Convenience method, the equivalent of checking if result is FLUSHED_COMPACTION_NEEDED. - * @return True if the flush requested a compaction, else false (doesn't even mean it flushed). + * Convenience method, the equivalent of checking if result is + * FLUSHED_COMPACTION_NEEDED. + * + * @return True if the flush requested a compaction, else false (doesn't even + * mean it flushed). */ @Override public boolean isCompactionNeeded() { @@ -593,8 +629,8 @@ public boolean isCompactionNeeded() { @Override public String toString() { return new StringBuilder().append("flush result:").append(result).append(", ") - .append("failureReason:").append(failureReason).append(",").append("flush seq id") - .append(flushSequenceId).toString(); + .append("failureReason:").append(failureReason).append(",").append("flush seq id") + .append(flushSequenceId).toString(); } @Override @@ -621,16 +657,16 @@ protected static class PrepareFlushResult { /** Constructs a successful prepare flush result */ PrepareFlushResult(TreeMap storeFlushCtxs, - TreeMap> committedFiles, TreeMap storeFlushableSize, - long startTime, long flushSeqId, long flushedSeqId, MemStoreSizing totalFlushableSize) { + TreeMap> committedFiles, TreeMap storeFlushableSize, + long startTime, long flushSeqId, long flushedSeqId, MemStoreSizing totalFlushableSize) { this(null, storeFlushCtxs, committedFiles, storeFlushableSize, startTime, flushSeqId, - flushedSeqId, totalFlushableSize); + flushedSeqId, totalFlushableSize); } private PrepareFlushResult(FlushResultImpl result, - TreeMap storeFlushCtxs, TreeMap> committedFiles, - TreeMap storeFlushableSize, long startTime, long flushSeqId, - long flushedSeqId, MemStoreSizing totalFlushableSize) { + TreeMap storeFlushCtxs, TreeMap> committedFiles, + TreeMap storeFlushableSize, long startTime, long flushSeqId, + long flushedSeqId, MemStoreSizing totalFlushableSize) { this.result = result; this.storeFlushCtxs = storeFlushCtxs; this.committedFiles = committedFiles; @@ -647,7 +683,8 @@ public FlushResult getResult() { } /** - * A class that tracks exceptions that have been observed in one batch. Not thread safe. + * A class that tracks exceptions that have been observed in one batch. Not + * thread safe. */ static class ObservedExceptionsInBatch { private boolean wrongRegion = false; @@ -707,8 +744,10 @@ void sawNoSuchFamily() { private long blockingMemStoreSize; // Used to guard closes final ReentrantReadWriteLock lock; - // Used to track interruptible holders of the region lock. Currently that is only RPC handler - // threads. Boolean value in map determines if lock holder can be interrupted, normally true, + // Used to track interruptible holders of the region lock. Currently that is + // only RPC handler + // threads. Boolean value in map determines if lock holder can be interrupted, + // normally true, // but may be false when thread is transiting a critical section. final ConcurrentHashMap regionLockHolders; @@ -731,27 +770,34 @@ void sawNoSuchFamily() { private final boolean regionStatsEnabled; // Stores the replication scope of the various column families of the table // that has non-default scope - private final NavigableMap replicationScope = - new TreeMap<>(Bytes.BYTES_COMPARATOR); + private final NavigableMap replicationScope = new TreeMap<>(Bytes.BYTES_COMPARATOR); private final StoreHotnessProtector storeHotnessProtector; protected Optional regionReplicationSink = Optional.empty(); /** - * HRegion constructor. This constructor should only be used for testing and extensions. Instances + * HRegion constructor. This constructor should only be used for testing and + * extensions. Instances * of HRegion should be instantiated with the {@link HRegion#createHRegion} or * {@link HRegion#openHRegion} method. - * @param tableDir qualified path of directory where region should be located, usually the table + * + * @param tableDir qualified path of directory where region should be located, + * usually the table * directory. - * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a - * logfile from the previous execution that's custom-computed for this HRegion. - * The HRegionServer computes and sorts the appropriate wal info for this - * HRegion. If there is a previous wal file (implying that the HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion + * The wal file is a + * logfile from the previous execution that's custom-computed + * for this HRegion. + * The HRegionServer computes and sorts the appropriate wal + * info for this + * HRegion. If there is a previous wal file (implying that the + * HRegion has been * written-to before), then read it from the supplied path. * @param fs is the filesystem. * @param confParam is global configuration settings. - * @param regionInfo - RegionInfo that describes the region is new), then read them from the + * @param regionInfo - RegionInfo that describes the region is new), then read + * them from the * supplied path. * @param htd the table descriptor * @param rsServices reference to {@link RegionServerServices} or null @@ -759,28 +805,34 @@ void sawNoSuchFamily() { */ @Deprecated public HRegion(final Path tableDir, final WAL wal, final FileSystem fs, - final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd, - final RegionServerServices rsServices) { + final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd, + final RegionServerServices rsServices) { this(new HRegionFileSystem(confParam, fs, tableDir, regionInfo), wal, confParam, htd, - rsServices); + rsServices); } /** - * HRegion constructor. This constructor should only be used for testing and extensions. Instances + * HRegion constructor. This constructor should only be used for testing and + * extensions. Instances * of HRegion should be instantiated with the {@link HRegion#createHRegion} or * {@link HRegion#openHRegion} method. + * * @param fs is the filesystem. - * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a - * logfile from the previous execution that's custom-computed for this HRegion. - * The HRegionServer computes and sorts the appropriate wal info for this - * HRegion. If there is a previous wal file (implying that the HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion + * The wal file is a + * logfile from the previous execution that's custom-computed + * for this HRegion. + * The HRegionServer computes and sorts the appropriate wal + * info for this + * HRegion. If there is a previous wal file (implying that the + * HRegion has been * written-to before), then read it from the supplied path. * @param confParam is global configuration settings. * @param htd the table descriptor * @param rsServices reference to {@link RegionServerServices} or null */ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration confParam, - final TableDescriptor htd, final RegionServerServices rsServices) { + final TableDescriptor htd, final RegionServerServices rsServices) { if (htd == null) { throw new IllegalArgumentException("Need table descriptor"); } @@ -797,24 +849,22 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co this.baseConf = confParam; this.conf = new CompoundConfiguration().add(confParam).addBytesMap(htd.getValues()); this.cellComparator = htd.isMetaTable() - || conf.getBoolean(USE_META_CELL_COMPARATOR, DEFAULT_USE_META_CELL_COMPARATOR) - ? MetaCellComparator.META_COMPARATOR - : CellComparatorImpl.COMPARATOR; + || conf.getBoolean(USE_META_CELL_COMPARATOR, DEFAULT_USE_META_CELL_COMPARATOR) + ? MetaCellComparator.META_COMPARATOR + : CellComparatorImpl.COMPARATOR; this.lock = new ReentrantReadWriteLock( - conf.getBoolean(FAIR_REENTRANT_CLOSE_LOCK, DEFAULT_FAIR_REENTRANT_CLOSE_LOCK)); + conf.getBoolean(FAIR_REENTRANT_CLOSE_LOCK, DEFAULT_FAIR_REENTRANT_CLOSE_LOCK)); this.regionLockHolders = new ConcurrentHashMap<>(); - this.flushCheckInterval = - conf.getInt(MEMSTORE_PERIODIC_FLUSH_INTERVAL, DEFAULT_CACHE_FLUSH_INTERVAL); + this.flushCheckInterval = conf.getInt(MEMSTORE_PERIODIC_FLUSH_INTERVAL, DEFAULT_CACHE_FLUSH_INTERVAL); this.flushPerChanges = conf.getLong(MEMSTORE_FLUSH_PER_CHANGES, DEFAULT_FLUSH_PER_CHANGES); if (this.flushPerChanges > MAX_FLUSH_PER_CHANGES) { throw new IllegalArgumentException( - MEMSTORE_FLUSH_PER_CHANGES + " can not exceed " + MAX_FLUSH_PER_CHANGES); + MEMSTORE_FLUSH_PER_CHANGES + " can not exceed " + MAX_FLUSH_PER_CHANGES); } - int tmpRowLockDuration = - conf.getInt("hbase.rowlock.wait.duration", DEFAULT_ROWLOCK_WAIT_DURATION); + int tmpRowLockDuration = conf.getInt("hbase.rowlock.wait.duration", DEFAULT_ROWLOCK_WAIT_DURATION); if (tmpRowLockDuration <= 0) { LOG.info("Found hbase.rowlock.wait.duration set to {}. values <= 0 will cause all row " - + "locking to fail. Treating it as 1ms to avoid region failure.", tmpRowLockDuration); + + "locking to fail. Treating it as 1ms to avoid region failure.", tmpRowLockDuration); tmpRowLockDuration = 1; } this.rowLockWaitDuration = tmpRowLockDuration; @@ -849,32 +899,35 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co this.maxBusyWaitMultiplier = conf.getInt("hbase.busy.wait.multiplier.max", 2); if (busyWaitDuration * maxBusyWaitMultiplier <= 0L) { throw new IllegalArgumentException("Invalid hbase.busy.wait.duration (" + busyWaitDuration - + ") or hbase.busy.wait.multiplier.max (" + maxBusyWaitMultiplier - + "). Their product should be positive"); + + ") or hbase.busy.wait.multiplier.max (" + maxBusyWaitMultiplier + + "). Their product should be positive"); } - this.maxBusyWaitDuration = - conf.getLong("hbase.ipc.client.call.purge.timeout", 2 * HConstants.DEFAULT_HBASE_RPC_TIMEOUT); + this.maxBusyWaitDuration = conf.getLong("hbase.ipc.client.call.purge.timeout", + 2 * HConstants.DEFAULT_HBASE_RPC_TIMEOUT); /* - * timestamp.slop provides a server-side constraint on the timestamp. This assumes that you base - * your TS around EnvironmentEdgeManager.currentTime(). In this case, throw an error to the user - * if the user-specified TS is newer than now + slop. LATEST_TIMESTAMP == don't use this + * timestamp.slop provides a server-side constraint on the timestamp. This + * assumes that you base + * your TS around EnvironmentEdgeManager.currentTime(). In this case, throw an + * error to the user + * if the user-specified TS is newer than now + slop. LATEST_TIMESTAMP == don't + * use this * functionality */ - this.timestampSlop = - conf.getLong("hbase.hregion.keyvalue.timestamp.slop.millisecs", HConstants.LATEST_TIMESTAMP); + this.timestampSlop = conf.getLong("hbase.hregion.keyvalue.timestamp.slop.millisecs", HConstants.LATEST_TIMESTAMP); this.storeHotnessProtector = new StoreHotnessProtector(this, conf); boolean forceSync = conf.getBoolean(WAL_HSYNC_CONF_KEY, DEFAULT_WAL_HSYNC); /** - * This is the global default value for durability. All tables/mutations not defining a + * This is the global default value for durability. All tables/mutations not + * defining a * durability or using USE_DEFAULT will default to this value. */ Durability defaultDurability = forceSync ? Durability.FSYNC_WAL : Durability.SYNC_WAL; this.regionDurability = this.htableDescriptor.getDurability() == Durability.USE_DEFAULT - ? defaultDurability - : this.htableDescriptor.getDurability(); + ? defaultDurability + : this.htableDescriptor.getDurability(); decorateRegionConfiguration(conf); if (rsServices != null) { @@ -895,32 +948,32 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co configurationManager = null; - // disable stats tracking system tables, but check the config for everything else + // disable stats tracking system tables, but check the config for everything + // else this.regionStatsEnabled = htd.getTableName().getNamespaceAsString() - .equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) - ? false - : conf.getBoolean(HConstants.ENABLE_CLIENT_BACKPRESSURE, - HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE); + .equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) + ? false + : conf.getBoolean(HConstants.ENABLE_CLIENT_BACKPRESSURE, + HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE); this.maxCellSize = conf.getLong(HBASE_MAX_CELL_SIZE_KEY, DEFAULT_MAX_CELL_SIZE); - this.miniBatchSize = - conf.getInt(HBASE_REGIONSERVER_MINIBATCH_SIZE, DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE); + this.miniBatchSize = conf.getInt(HBASE_REGIONSERVER_MINIBATCH_SIZE, DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE); // recover the metrics of read and write requests count if they were retained if (rsServices != null && rsServices.getRegionServerAccounting() != null) { Pair retainedRWRequestsCnt = rsServices.getRegionServerAccounting() - .getRetainedRegionRWRequestsCnt().get(getRegionInfo().getEncodedName()); + .getRetainedRegionRWRequestsCnt().get(getRegionInfo().getEncodedName()); if (retainedRWRequestsCnt != null) { this.addReadRequestsCount(retainedRWRequestsCnt.getFirst()); this.addWriteRequestsCount(retainedRWRequestsCnt.getSecond()); // remove them since won't use again rsServices.getRegionServerAccounting().getRetainedRegionRWRequestsCnt() - .remove(getRegionInfo().getEncodedName()); + .remove(getRegionInfo().getEncodedName()); } } minBlockSizeBytes = Arrays.stream(this.htableDescriptor.getColumnFamilies()) - .mapToInt(ColumnFamilyDescriptor::getBlocksize).min().orElse(HConstants.DEFAULT_BLOCKSIZE); + .mapToInt(ColumnFamilyDescriptor::getBlocksize).min().orElse(HConstants.DEFAULT_BLOCKSIZE); } private void setHTableSpecificConf() { @@ -931,17 +984,19 @@ private void setHTableSpecificConf() { if (flushSize <= 0) { flushSize = conf.getLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, - TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE); + TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE); } this.memstoreFlushSize = flushSize; long mult = conf.getLong(HConstants.HREGION_MEMSTORE_BLOCK_MULTIPLIER, - HConstants.DEFAULT_HREGION_MEMSTORE_BLOCK_MULTIPLIER); + HConstants.DEFAULT_HREGION_MEMSTORE_BLOCK_MULTIPLIER); this.blockingMemStoreSize = this.memstoreFlushSize * mult; } /** - * Initialize this region. Used only by tests and SplitTransaction to reopen the region. You + * Initialize this region. Used only by tests and SplitTransaction to reopen the + * region. You * should use createHRegion() or openHRegion() + * * @return What the next sequence (edit) id should be. * @throws IOException e * @deprecated use HRegion.createHRegion() or HRegion.openHRegion() @@ -953,6 +1008,7 @@ public long initialize() throws IOException { /** * Initialize this region. + * * @param reporter Tickle every so often if initialize is taking a while. * @return What the next sequence (edit) id should be. */ @@ -961,18 +1017,17 @@ long initialize(final CancelableProgressable reporter) throws IOException { // Refuse to open the region if there is no column family in the table if (htableDescriptor.getColumnFamilyCount() == 0) { throw new DoNotRetryIOException("Table " + htableDescriptor.getTableName().getNameAsString() - + " should have at least one column family."); + + " should have at least one column family."); } - MonitoredTask status = - TaskMonitor.get().createStatus("Initializing region " + this, false, true); + MonitoredTask status = TaskMonitor.get().createStatus("Initializing region " + this, false, true); long nextSeqId = -1; try { nextSeqId = initializeRegionInternals(reporter, status); return nextSeqId; } catch (IOException e) { LOG.warn("Failed initialize of region= {}, starting to roll back memstore", - getRegionInfo().getRegionNameAsString(), e); + getRegionInfo().getRegionNameAsString(), e); // global memstore size will be decreased when dropping memstore try { // drop the memory used by memstore if open region fails @@ -980,9 +1035,9 @@ long initialize(final CancelableProgressable reporter) throws IOException { } catch (IOException ioE) { if (conf.getBoolean(MemStoreLAB.USEMSLAB_KEY, MemStoreLAB.USEMSLAB_DEFAULT)) { LOG.warn( - "Failed drop memstore of region= {}, " - + "some chunks may not released forever since MSLAB is enabled", - getRegionInfo().getRegionNameAsString()); + "Failed drop memstore of region= {}, " + + "some chunks may not released forever since MSLAB is enabled", + getRegionInfo().getRegionNameAsString()); } } @@ -995,18 +1050,18 @@ long initialize(final CancelableProgressable reporter) throws IOException { // At least it will be 0 otherwise. if (nextSeqId == -1) { status.abort("Exception during region " + getRegionInfo().getRegionNameAsString() - + " initialization."); + + " initialization."); } if (LOG.isDebugEnabled()) { LOG.debug("Region open journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } } private long initializeRegionInternals(final CancelableProgressable reporter, - final MonitoredTask status) throws IOException { + final MonitoredTask status) throws IOException { if (coprocessorHost != null) { status.setStatus("Running coprocessor pre-open hook"); coprocessorHost.preOpen(); @@ -1033,8 +1088,7 @@ private long initializeRegionInternals(final CancelableProgressable reporter, LOG.debug("replaying wal for " + this.getRegionInfo().getEncodedName()); stores.forEach(HStore::startReplayingFromWAL); // Recover any edits if available. - maxSeqId = - Math.max(maxSeqId, replayRecoveredEditsIfAny(maxSeqIdInStores, reporter, status)); + maxSeqId = Math.max(maxSeqId, replayRecoveredEditsIfAny(maxSeqIdInStores, reporter, status)); // Recover any hfiles if available maxSeqId = Math.max(maxSeqId, loadRecoveredHFilesIfAny(stores)); // Make sure mvcc is up to max. @@ -1076,23 +1130,28 @@ private long initializeRegionInternals(final CancelableProgressable reporter, // (particularly if no recovered edits, seqid will be -1). long nextSeqId = maxSeqId + 1; if (!isRestoredRegion) { - // always get openSeqNum from the default replica, even if we are secondary replicas + // always get openSeqNum from the default replica, even if we are secondary + // replicas long maxSeqIdFromFile = WALSplitUtil.getMaxRegionSequenceId(conf, - RegionReplicaUtil.getRegionInfoForDefaultReplica(getRegionInfo()), this::getFilesystem, - this::getWalFileSystem); + RegionReplicaUtil.getRegionInfoForDefaultReplica(getRegionInfo()), this::getFilesystem, + this::getWalFileSystem); nextSeqId = Math.max(maxSeqId, maxSeqIdFromFile) + 1; - // The openSeqNum will always be increase even for read only region, as we rely on it to - // determine whether a region has been successfully reopened, so here we always need to update + // The openSeqNum will always be increase even for read only region, as we rely + // on it to + // determine whether a region has been successfully reopened, so here we always + // need to update // the max sequence id file. if (RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { LOG.debug("writing seq id for {}", this.getRegionInfo().getEncodedName()); WALSplitUtil.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), - nextSeqId - 1); - // This means we have replayed all the recovered edits and also written out the max sequence - // id file, let's delete the wrong directories introduced in HBASE-20734, see HBASE-22617 + nextSeqId - 1); + // This means we have replayed all the recovered edits and also written out the + // max sequence + // id file, let's delete the wrong directories introduced in HBASE-20734, see + // HBASE-22617 // for more details. Path wrongRegionWALDir = CommonFSUtils.getWrongWALRegionDir(conf, - getRegionInfo().getTable(), getRegionInfo().getEncodedName()); + getRegionInfo().getTable(), getRegionInfo().getEncodedName()); FileSystem walFs = getWalFileSystem(); if (walFs.exists(wrongRegionWALDir)) { if (!walFs.delete(wrongRegionWALDir, true)) { @@ -1107,7 +1166,7 @@ private long initializeRegionInternals(final CancelableProgressable reporter, } LOG.info("Opened {}; next sequenceid={}; {}, {}", this.getRegionInfo().getShortNameToLog(), - nextSeqId, this.splitPolicy, this.flushPolicy); + nextSeqId, this.splitPolicy, this.flushPolicy); // A region can be reopened if failed a split; reset flags this.closing.set(false); @@ -1126,37 +1185,36 @@ private long initializeRegionInternals(final CancelableProgressable reporter, } private void initializeRegionReplicationSink(CancelableProgressable reporter, - MonitoredTask status) { + MonitoredTask status) { RegionServerServices rss = getRegionServerServices(); TableDescriptor td = getTableDescriptor(); int regionReplication = td.getRegionReplication(); RegionInfo regionInfo = getRegionInfo(); - if ( - regionReplication <= 1 || !RegionReplicaUtil.isDefaultReplica(regionInfo) + if (regionReplication <= 1 || !RegionReplicaUtil.isDefaultReplica(regionInfo) || !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(conf, regionInfo.getTable()) - || rss == null - ) { + || rss == null) { regionReplicationSink = Optional.empty(); return; } status.setStatus("Initializaing region replication sink"); regionReplicationSink = Optional.of(new RegionReplicationSink(conf, regionInfo, td, - rss.getRegionReplicationBufferManager(), () -> rss.getFlushRequester().requestFlush(this, - new ArrayList<>(td.getColumnFamilyNames()), FlushLifeCycleTracker.DUMMY), - rss.getAsyncClusterConnection())); + rss.getRegionReplicationBufferManager(), () -> rss.getFlushRequester().requestFlush(this, + new ArrayList<>(td.getColumnFamilyNames()), FlushLifeCycleTracker.DUMMY), + rss.getAsyncClusterConnection())); } /** * Open all Stores. + * * @return Highest sequenceId found out in a Store. */ private long initializeStores(CancelableProgressable reporter, MonitoredTask status) - throws IOException { + throws IOException { return initializeStores(reporter, status, false); } private long initializeStores(CancelableProgressable reporter, MonitoredTask status, - boolean warmup) throws IOException { + boolean warmup) throws IOException { // Load in all the HStores. long maxSeqId = -1; // initialized to -1 so that we pick up MemstoreTS from column families @@ -1164,10 +1222,9 @@ private long initializeStores(CancelableProgressable reporter, MonitoredTask sta if (htableDescriptor.getColumnFamilyCount() != 0) { // initialize the thread pool for opening stores in parallel. - ThreadPoolExecutor storeOpenerThreadPool = - getStoreOpenAndCloseThreadPool("StoreOpener-" + this.getRegionInfo().getShortNameToLog()); - CompletionService completionService = - new ExecutorCompletionService<>(storeOpenerThreadPool); + ThreadPoolExecutor storeOpenerThreadPool = getStoreOpenAndCloseThreadPool( + "StoreOpener-" + this.getRegionInfo().getShortNameToLog()); + CompletionService completionService = new ExecutorCompletionService<>(storeOpenerThreadPool); // initialize each store in parallel for (final ColumnFamilyDescriptor family : htableDescriptor.getColumnFamilies()) { @@ -1203,7 +1260,7 @@ public HStore call() throws IOException { allStoresOpened = true; if (hasSloppyStores) { htableDescriptor = TableDescriptorBuilder.newBuilder(htableDescriptor) - .setFlushPolicyClassName(FlushNonSloppyStoresFirstPolicy.class.getName()).build(); + .setFlushPolicyClassName(FlushNonSloppyStoresFirstPolicy.class.getName()).build(); LOG.info("Setting FlushNonSloppyStoresFirstPolicy for the region=" + this); } } catch (InterruptedException e) { @@ -1258,29 +1315,31 @@ private NavigableMap> getStoreFiles() { protected void writeRegionOpenMarker(WAL wal, long openSeqId) throws IOException { Map> storeFiles = getStoreFiles(); - RegionEventDescriptor regionOpenDesc = - ProtobufUtil.toRegionEventDescriptor(RegionEventDescriptor.EventType.REGION_OPEN, + RegionEventDescriptor regionOpenDesc = ProtobufUtil.toRegionEventDescriptor( + RegionEventDescriptor.EventType.REGION_OPEN, getRegionInfo(), openSeqId, getRegionServerServices().getServerName(), storeFiles); WALUtil.writeRegionEventMarker(wal, getReplicationScope(), getRegionInfo(), regionOpenDesc, - mvcc, regionReplicationSink.orElse(null)); + mvcc, regionReplicationSink.orElse(null)); } private void writeRegionCloseMarker(WAL wal) throws IOException { Map> storeFiles = getStoreFiles(); RegionEventDescriptor regionEventDesc = ProtobufUtil.toRegionEventDescriptor( - RegionEventDescriptor.EventType.REGION_CLOSE, getRegionInfo(), mvcc.getReadPoint(), - getRegionServerServices().getServerName(), storeFiles); - // we do not care region close event at secondary replica side so just pass a null + RegionEventDescriptor.EventType.REGION_CLOSE, getRegionInfo(), mvcc.getReadPoint(), + getRegionServerServices().getServerName(), storeFiles); + // we do not care region close event at secondary replica side so just pass a + // null // RegionReplicationSink WALUtil.writeRegionEventMarker(wal, getReplicationScope(), getRegionInfo(), regionEventDesc, - mvcc, null); + mvcc, null); // Store SeqId in WAL FileSystem when a region closes - // checking region folder exists is due to many tests which delete the table folder while a + // checking region folder exists is due to many tests which delete the table + // folder while a // table is still online if (getWalFileSystem().exists(getWALRegionDir())) { WALSplitUtil.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), - mvcc.getReadPoint()); + mvcc.getReadPoint()); } } @@ -1300,27 +1359,28 @@ public void unblockUpdates() { public HDFSBlocksDistribution getHDFSBlocksDistribution() { HDFSBlocksDistribution hdfsBlocksDistribution = new HDFSBlocksDistribution(); stores.values().stream().filter(s -> s.getStorefiles() != null) - .flatMap(s -> s.getStorefiles().stream()).map(HStoreFile::getHDFSBlockDistribution) - .forEachOrdered(hdfsBlocksDistribution::add); + .flatMap(s -> s.getStorefiles().stream()).map(HStoreFile::getHDFSBlockDistribution) + .forEachOrdered(hdfsBlocksDistribution::add); return hdfsBlocksDistribution; } /** * This is a helper function to compute HDFS block distribution on demand + * * @param conf configuration * @param tableDescriptor TableDescriptor of the table * @param regionInfo encoded name of the region * @return The HDFS blocks distribution for the given region. */ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf, - TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException { - Path tablePath = - CommonFSUtils.getTableDir(CommonFSUtils.getRootDir(conf), tableDescriptor.getTableName()); + TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException { + Path tablePath = CommonFSUtils.getTableDir(CommonFSUtils.getRootDir(conf), tableDescriptor.getTableName()); return computeHDFSBlocksDistribution(conf, tableDescriptor, regionInfo, tablePath); } /** * This is a helper function to compute HDFS block distribution on demand + * * @param conf configuration * @param tableDescriptor TableDescriptor of the table * @param regionInfo encoded name of the region @@ -1328,14 +1388,14 @@ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration * @return The HDFS blocks distribution for the given region. */ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf, - TableDescriptor tableDescriptor, RegionInfo regionInfo, Path tablePath) throws IOException { + TableDescriptor tableDescriptor, RegionInfo regionInfo, Path tablePath) throws IOException { HDFSBlocksDistribution hdfsBlocksDistribution = new HDFSBlocksDistribution(); FileSystem fs = tablePath.getFileSystem(conf); HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tablePath, regionInfo); for (ColumnFamilyDescriptor family : tableDescriptor.getColumnFamilies()) { - List locatedFileStatusList = - HRegionFileSystem.getStoreFilesLocatedStatus(regionFs, family.getNameAsString(), true); + List locatedFileStatusList = HRegionFileSystem.getStoreFilesLocatedStatus(regionFs, + family.getNameAsString(), true); if (locatedFileStatusList == null) { continue; } @@ -1360,45 +1420,48 @@ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration } /** - * Increase the size of mem store in this region and the size of global mem store + * Increase the size of mem store in this region and the size of global mem + * store */ private void incMemStoreSize(MemStoreSize mss) { incMemStoreSize(mss.getDataSize(), mss.getHeapSize(), mss.getOffHeapSize(), - mss.getCellsCount()); + mss.getCellsCount()); } void incMemStoreSize(long dataSizeDelta, long heapSizeDelta, long offHeapSizeDelta, - int cellsCountDelta) { + int cellsCountDelta) { if (this.rsAccounting != null) { rsAccounting.incGlobalMemStoreSize(dataSizeDelta, heapSizeDelta, offHeapSizeDelta); } long dataSize = this.memStoreSizing.incMemStoreSize(dataSizeDelta, heapSizeDelta, - offHeapSizeDelta, cellsCountDelta); + offHeapSizeDelta, cellsCountDelta); checkNegativeMemStoreDataSize(dataSize, dataSizeDelta); } void decrMemStoreSize(MemStoreSize mss) { decrMemStoreSize(mss.getDataSize(), mss.getHeapSize(), mss.getOffHeapSize(), - mss.getCellsCount()); + mss.getCellsCount()); } private void decrMemStoreSize(long dataSizeDelta, long heapSizeDelta, long offHeapSizeDelta, - int cellsCountDelta) { + int cellsCountDelta) { if (this.rsAccounting != null) { rsAccounting.decGlobalMemStoreSize(dataSizeDelta, heapSizeDelta, offHeapSizeDelta); } long dataSize = this.memStoreSizing.decMemStoreSize(dataSizeDelta, heapSizeDelta, - offHeapSizeDelta, cellsCountDelta); + offHeapSizeDelta, cellsCountDelta); checkNegativeMemStoreDataSize(dataSize, -dataSizeDelta); } private void checkNegativeMemStoreDataSize(long memStoreDataSize, long delta) { - // This is extremely bad if we make memStoreSizing negative. Log as much info on the offending - // caller as possible. (memStoreSizing might be a negative value already -- freeing memory) + // This is extremely bad if we make memStoreSizing negative. Log as much info on + // the offending + // caller as possible. (memStoreSizing might be a negative value already -- + // freeing memory) if (memStoreDataSize < 0) { LOG.error("Asked to modify this region's (" + this.toString() - + ") memStoreSizing to a negative value which is incorrect. Current memStoreSizing=" - + (memStoreDataSize - delta) + ", delta=" + delta, new Exception()); + + ") memStoreSizing to a negative value which is incorrect. Current memStoreSizing=" + + (memStoreDataSize - delta) + ", delta=" + delta, new Exception()); } } @@ -1408,7 +1471,8 @@ public RegionInfo getRegionInfo() { } /** - * Returns Instance of {@link RegionServerServices} used by this HRegion. Can be null. + * Returns Instance of {@link RegionServerServices} used by this HRegion. Can be + * null. */ RegionServerServices getRegionServerServices() { return this.rsServices; @@ -1449,7 +1513,10 @@ public long getMemStoreOffHeapSize() { return memStoreSizing.getOffHeapSize(); } - /** Returns store services for this region, to access services required by store level needs */ + /** + * Returns store services for this region, to access services required by store + * level needs + */ public RegionServicesForStores getRegionServicesForStores() { return regionServicesForStores; } @@ -1479,8 +1546,10 @@ public long getCheckAndMutateChecksFailed() { return checkAndMutateChecksFailed.sum(); } - // TODO Needs to check whether we should expose our metrics system to CPs. If CPs themselves doing - // the op and bypassing the core, this might be needed? Should be stop supporting the bypass + // TODO Needs to check whether we should expose our metrics system to CPs. If + // CPs themselves doing + // the op and bypassing the core, this might be needed? Should be stop + // supporting the bypass // feature? public MetricsRegion getMetrics() { return metricsRegion; @@ -1540,7 +1609,10 @@ public long getMaxFlushedSeqId() { return maxFlushedSeqId; } - /** Returns readpoint considering given IsolationLevel. Pass {@code null} for default */ + /** + * Returns readpoint considering given IsolationLevel. Pass {@code null} for + * default + */ public long getReadPoint(IsolationLevel isolationLevel) { if (isolationLevel != null && isolationLevel == IsolationLevel.READ_UNCOMMITTED) { // This scan can read even uncommitted transactions @@ -1554,15 +1626,22 @@ public boolean isLoadingCfsOnDemandDefault() { } /** - * Close down this HRegion. Flush the cache, shut down each HStore, don't service any more calls. + * Close down this HRegion. Flush the cache, shut down each HStore, don't + * service any more calls. *

- * This method could take some time to execute, so don't call it from a time-sensitive thread. - * @return Vector of all the storage files that the HRegion's component HStores make use of. It's - * a list of all StoreFile objects. Returns empty vector if already closed and null if + * This method could take some time to execute, so don't call it from a + * time-sensitive thread. + * + * @return Vector of all the storage files that the HRegion's component HStores + * make use of. It's + * a list of all StoreFile objects. Returns empty vector if already + * closed and null if * judged that it should not close. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was - * not properly persisted. The region is put in closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required + * because a Snapshot was + * not properly persisted. The region is put in + * closing mode, and * the caller MUST abort after this. */ public Map> close() throws IOException { @@ -1572,23 +1651,26 @@ public Map> close() throws IOException { private final Object closeLock = new Object(); /** Conf key for fair locking policy */ - public static final String FAIR_REENTRANT_CLOSE_LOCK = - "hbase.regionserver.fair.region.close.lock"; + public static final String FAIR_REENTRANT_CLOSE_LOCK = "hbase.regionserver.fair.region.close.lock"; public static final boolean DEFAULT_FAIR_REENTRANT_CLOSE_LOCK = true; /** Conf key for the periodic flush interval */ - public static final String MEMSTORE_PERIODIC_FLUSH_INTERVAL = - "hbase.regionserver.optionalcacheflushinterval"; + public static final String MEMSTORE_PERIODIC_FLUSH_INTERVAL = "hbase.regionserver.optionalcacheflushinterval"; /** Default interval for the memstore flush */ public static final int DEFAULT_CACHE_FLUSH_INTERVAL = 3600000; /** Default interval for System tables memstore flush */ public static final int SYSTEM_CACHE_FLUSH_INTERVAL = 300000; // 5 minutes - /** Conf key to force a flush if there are already enough changes for one region in memstore */ + /** + * Conf key to force a flush if there are already enough changes for one region + * in memstore + */ public static final String MEMSTORE_FLUSH_PER_CHANGES = "hbase.regionserver.flush.per.changes"; public static final long DEFAULT_FLUSH_PER_CHANGES = 30000000; // 30 millions /** - * The following MAX_FLUSH_PER_CHANGES is large enough because each KeyValue has 20+ bytes - * overhead. Therefore, even 1G empty KVs occupy at least 20GB memstore size for a single region + * The following MAX_FLUSH_PER_CHANGES is large enough because each KeyValue has + * 20+ bytes + * overhead. Therefore, even 1G empty KVs occupy at least 20GB memstore size for + * a single region */ public static final long MAX_FLUSH_PER_CHANGES = 1000000000; // 1G @@ -1605,44 +1687,57 @@ public Map> close(boolean abort) throws IOException { /** * Close this HRegion. + * * @param abort true if server is aborting (only during testing) * @param ignoreStatus true if ignore the status (won't be showed on task list) - * @return Vector of all the storage files that the HRegion's component HStores make use of. It's - * a list of StoreFile objects. Can be null if we are not to close at this time, or we are + * @return Vector of all the storage files that the HRegion's component HStores + * make use of. It's + * a list of StoreFile objects. Can be null if we are not to close at + * this time, or we are * already closed. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was - * not properly persisted. The region is put in closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required + * because a Snapshot was + * not properly persisted. The region is put in + * closing mode, and * the caller MUST abort after this. */ public Map> close(boolean abort, boolean ignoreStatus) - throws IOException { + throws IOException { return close(abort, ignoreStatus, false); } /** - * Close down this HRegion. Flush the cache unless abort parameter is true, Shut down each HStore, - * don't service any more calls. This method could take some time to execute, so don't call it + * Close down this HRegion. Flush the cache unless abort parameter is true, Shut + * down each HStore, + * don't service any more calls. This method could take some time to execute, so + * don't call it * from a time-sensitive thread. + * * @param abort true if server is aborting (only during testing) * @param ignoreStatus true if ignore the status (wont be showed on task list) - * @param isGracefulStop true if region is being closed during graceful stop and the blocks in the + * @param isGracefulStop true if region is being closed during graceful stop and + * the blocks in the * BucketCache should not be evicted. - * @return Vector of all the storage files that the HRegion's component HStores make use of. It's - * a list of StoreFile objects. Can be null if we are not to close at this time or we are + * @return Vector of all the storage files that the HRegion's component HStores + * make use of. It's + * a list of StoreFile objects. Can be null if we are not to close at + * this time or we are * already closed. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was - * not properly persisted. The region is put in closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required + * because a Snapshot was + * not properly persisted. The region is put in + * closing mode, and * the caller MUST abort after this. */ public Map> close(boolean abort, boolean ignoreStatus, - boolean isGracefulStop) throws IOException { + boolean isGracefulStop) throws IOException { // Only allow one thread to close at a time. Serialize them so dual // threads attempting to close will run up against each other. MonitoredTask status = TaskMonitor.get().createStatus( - "Closing region " + this.getRegionInfo().getEncodedName() + (abort ? " due to abort" : ""), - ignoreStatus, true); + "Closing region " + this.getRegionInfo().getEncodedName() + (abort ? " due to abort" : ""), + ignoreStatus, true); status.setStatus("Waiting for close lock"); try { synchronized (closeLock) { @@ -1653,9 +1748,9 @@ public Map> close(boolean abort, boolean ignoreStatus, if (l2 instanceof BucketCache) { if (((BucketCache) l2).isCachePersistenceEnabled()) { LOG.info( - "Closing region {} during a graceful stop, and cache persistence is on, " - + "so setting evict on close to false. ", - this.getRegionInfo().getRegionNameAsString()); + "Closing region {} during a graceful stop, and cache persistence is on, " + + "so setting evict on close to false. ", + this.getRegionInfo().getRegionNameAsString()); this.getStores().forEach(s -> s.getCacheConfig().setEvictOnClose(false)); } } @@ -1667,7 +1762,7 @@ public Map> close(boolean abort, boolean ignoreStatus, } finally { if (LOG.isDebugEnabled()) { LOG.debug("Region close journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } @@ -1681,9 +1776,12 @@ public void setClosing(boolean closing) { } /** - * The {@link HRegion#doClose} will block forever if someone tries proving the dead lock via the - * unit test. Instead of blocking, the {@link HRegion#doClose} will throw exception if you set the + * The {@link HRegion#doClose} will block forever if someone tries proving the + * dead lock via the + * unit test. Instead of blocking, the {@link HRegion#doClose} will throw + * exception if you set the * timeout. + * * @param timeoutForWriteLock the second time to wait for the write lock in * {@link HRegion#doClose} */ @@ -1692,10 +1790,9 @@ public void setTimeoutForWriteLock(long timeoutForWriteLock) { this.timeoutForWriteLock = timeoutForWriteLock; } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "UL_UNRELEASED_LOCK_EXCEPTION_PATH", - justification = "I think FindBugs is confused") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "UL_UNRELEASED_LOCK_EXCEPTION_PATH", justification = "I think FindBugs is confused") private Map> doClose(boolean abort, MonitoredTask status) - throws IOException { + throws IOException { if (isClosed()) { LOG.warn("Region " + this + " already closed"); return null; @@ -1713,7 +1810,7 @@ private Map> doClose(boolean abort, MonitoredTask statu canFlush = !writestate.readOnly; writestate.writesEnabled = false; LOG.debug("Closing {}, disabling compactions & flushes", - this.getRegionInfo().getEncodedName()); + this.getRegionInfo().getEncodedName()); waitForFlushesAndCompactions(); } // If we were not just flushing, is it worth doing a preflush...one @@ -1731,8 +1828,10 @@ private Map> doClose(boolean abort, MonitoredTask statu } if (regionReplicationSink.isPresent()) { // stop replicating to secondary replicas - // the open event marker can make secondary replicas refresh store files and catch up - // everything, so here we just give up replicating later edits, to speed up the reopen process + // the open event marker can make secondary replicas refresh store files and + // catch up + // everything, so here we just give up replicating later edits, to speed up the + // reopen process RegionReplicationSink sink = regionReplicationSink.get(); sink.stop(); try { @@ -1767,7 +1866,7 @@ private Map> doClose(boolean abort, MonitoredTask statu } if (LOG.isDebugEnabled()) { LOG.debug((useTimedWait ? "Time limited wait" : "Waiting without time limit") - + " for close lock on " + this); + + " for close lock on " + this); } final long closeWaitInterval = conf.getLong(CLOSE_WAIT_INTERVAL, DEFAULT_CLOSE_WAIT_INTERVAL); long elapsedWaitTime = 0; @@ -1776,8 +1875,8 @@ private Map> doClose(boolean abort, MonitoredTask statu long remainingWaitTime = timeoutForWriteLock; if (remainingWaitTime < closeWaitInterval) { LOG.warn("Time limit for close wait of " + timeoutForWriteLock - + " ms is less than the configured lock acquisition wait interval " + closeWaitInterval - + " ms, using wait interval as time limit"); + + " ms is less than the configured lock acquisition wait interval " + closeWaitInterval + + " ms, using wait interval as time limit"); remainingWaitTime = closeWaitInterval; } boolean acquired = false; @@ -1785,10 +1884,12 @@ private Map> doClose(boolean abort, MonitoredTask statu long start = EnvironmentEdgeManager.currentTime(); try { acquired = lock.writeLock().tryLock(Math.min(remainingWaitTime, closeWaitInterval), - TimeUnit.MILLISECONDS); + TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - // Interrupted waiting for close lock. More likely the server is shutting down, not - // normal operation, so aborting upon interrupt while waiting on this lock would not + // Interrupted waiting for close lock. More likely the server is shutting down, + // not + // normal operation, so aborting upon interrupt while waiting on this lock would + // not // provide much value. Throw an IOE (as IIOE) like we would in the case where we // fail to acquire the lock. String msg = "Interrupted while waiting for close lock on " + this; @@ -1805,17 +1906,17 @@ private Map> doClose(boolean abort, MonitoredTask statu // endRegionOperation. if (LOG.isDebugEnabled()) { LOG.debug("Interrupting region operations after waiting for close lock for " - + elapsedWaitTime + " ms on " + this + ", " + remainingWaitTime + " ms remaining"); + + elapsedWaitTime + " ms on " + this + ", " + remainingWaitTime + " ms remaining"); } interruptRegionOperations(); } } while (!acquired && remainingWaitTime > 0); - // If we fail to acquire the lock, trigger an abort if we can; otherwise throw an IOE + // If we fail to acquire the lock, trigger an abort if we can; otherwise throw + // an IOE // to let the caller know we could not proceed with the close. if (!acquired) { - String msg = - "Failed to acquire close lock on " + this + " after waiting " + elapsedWaitTime + " ms"; + String msg = "Failed to acquire close lock on " + this + " after waiting " + elapsedWaitTime + " ms"; LOG.error(msg); if (canAbort) { // If we failed to acquire the write lock, abort the server @@ -1866,7 +1967,7 @@ private Map> doClose(boolean abort, MonitoredTask statu // If we failed 5 times and are unable to clear memory, abort // so we do not lose data throw new DroppedSnapshotException("Failed clearing memory after " + flushCount - + " attempts on region: " + Bytes.toStringBinary(getRegionInfo().getRegionName())); + + " attempts on region: " + Bytes.toStringBinary(getRegionInfo().getRegionName())); } } catch (IOException ioe) { status.setStatus("Failed flush " + this + ", putting online again"); @@ -1882,10 +1983,10 @@ private Map> doClose(boolean abort, MonitoredTask statu Map> result = new TreeMap<>(Bytes.BYTES_COMPARATOR); if (!stores.isEmpty()) { // initialize the thread pool for closing stores in parallel. - ThreadPoolExecutor storeCloserThreadPool = - getStoreOpenAndCloseThreadPool("StoreCloser-" + getRegionInfo().getRegionNameAsString()); - CompletionService>> completionService = - new ExecutorCompletionService<>(storeCloserThreadPool); + ThreadPoolExecutor storeCloserThreadPool = getStoreOpenAndCloseThreadPool( + "StoreCloser-" + getRegionInfo().getRegionNameAsString()); + CompletionService>> completionService = new ExecutorCompletionService<>( + storeCloserThreadPool); // close each store in parallel for (HStore store : stores.values()) { @@ -1893,10 +1994,10 @@ private Map> doClose(boolean abort, MonitoredTask statu if (!(abort || mss.getDataSize() == 0 || writestate.readOnly)) { if (getRegionServerServices() != null) { getRegionServerServices().abort("Assertion failed while closing store " - + getRegionInfo().getRegionNameAsString() + " " + store - + ". flushableSize expected=0, actual={" + mss + "}. Current memStoreSize=" - + this.memStoreSizing.getMemStoreSize() + ". Maybe a coprocessor " - + "operation failed and left the memstore in a partially updated state.", null); + + getRegionInfo().getRegionNameAsString() + " " + store + + ". flushableSize expected=0, actual={" + mss + "}. Current memStoreSize=" + + this.memStoreSizing.getMemStoreSize() + ". Maybe a coprocessor " + + "operation failed and left the memstore in a partially updated state.", null); } } completionService.submit(new Callable>>() { @@ -1931,12 +2032,12 @@ public Pair> call() throws IOException { } status.setStatus("Writing region close event to WAL"); - // Always write close marker to wal even for read only table. This is not a big problem as we - // do not write any data into the region; it is just a meta edit in the WAL file. - if ( - !abort && wal != null && getRegionServerServices() != null - && RegionReplicaUtil.isDefaultReplica(getRegionInfo()) - ) { + // Always write close marker to wal even for read only table. This is not a big + // problem as we + // do not write any data into the region; it is just a meta edit in the WAL + // file. + if (!abort && wal != null && getRegionServerServices() != null + && RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { writeRegionCloseMarker(wal); } this.closed.set(true); @@ -1971,12 +2072,14 @@ public Pair> call() throws IOException { } /** Wait for all current flushes and compactions of the region to complete */ - // TODO HBASE-18906. Check the usage (if any) in Phoenix and expose this or give alternate way for + // TODO HBASE-18906. Check the usage (if any) in Phoenix and expose this or give + // alternate way for // Phoenix needs. public void waitForFlushesAndCompactions() { synchronized (writestate) { if (this.writestate.readOnly) { - // we should not wait for replayed flushed if we are read only (for example in case the + // we should not wait for replayed flushed if we are read only (for example in + // case the // region is a secondary replica). return; } @@ -1984,7 +2087,7 @@ public void waitForFlushesAndCompactions() { try { while (writestate.compacting.get() > 0 || writestate.flushing) { LOG.debug("waiting for " + writestate.compacting + " compactions" - + (writestate.flushing ? " & cache flush" : "") + " to complete for region " + this); + + (writestate.flushing ? " & cache flush" : "") + " to complete for region " + this); try { writestate.wait(); } catch (InterruptedException iex) { @@ -2013,18 +2116,21 @@ public void waitForFlushes() { public boolean waitForFlushes(long timeout) { synchronized (writestate) { if (this.writestate.readOnly) { - // we should not wait for replayed flushed if we are read only (for example in case the + // we should not wait for replayed flushed if we are read only (for example in + // case the // region is a secondary replica). return true; } - if (!writestate.flushing) return true; + if (!writestate.flushing) + return true; long start = EnvironmentEdgeManager.currentTime(); long duration = 0; boolean interrupted = false; LOG.debug("waiting for cache flush to complete for region " + this); try { while (writestate.flushing) { - if (timeout > 0 && duration >= timeout) break; + if (timeout > 0 && duration >= timeout) + break; try { long toWait = timeout == 0 ? 0 : (timeout - duration); writestate.wait(toWait); @@ -2060,34 +2166,33 @@ public int getMinBlockSizeBytes() { private ThreadPoolExecutor getStoreOpenAndCloseThreadPool(final String threadNamePrefix) { int numStores = Math.max(1, this.htableDescriptor.getColumnFamilyCount()); int maxThreads = Math.min(numStores, conf.getInt(HConstants.HSTORE_OPEN_AND_CLOSE_THREADS_MAX, - HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX)); + HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX)); return getOpenAndCloseThreadPool(maxThreads, threadNamePrefix); } ThreadPoolExecutor getStoreFileOpenAndCloseThreadPool(final String threadNamePrefix) { int numStores = Math.max(1, this.htableDescriptor.getColumnFamilyCount()); int maxThreads = Math.max(1, conf.getInt(HConstants.HSTORE_OPEN_AND_CLOSE_THREADS_MAX, - HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX) / numStores); + HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX) / numStores); return getOpenAndCloseThreadPool(maxThreads, threadNamePrefix); } private static ThreadPoolExecutor getOpenAndCloseThreadPool(int maxThreads, - final String threadNamePrefix) { + final String threadNamePrefix) { return Threads.getBoundedCachedThreadPool(maxThreads, 30L, TimeUnit.SECONDS, - new ThreadFactory() { - private int count = 1; + new ThreadFactory() { + private int count = 1; - @Override - public Thread newThread(Runnable r) { - return new Thread(r, threadNamePrefix + "-" + count++); - } - }); + @Override + public Thread newThread(Runnable r) { + return new Thread(r, threadNamePrefix + "-" + count++); + } + }); } /** Returns True if its worth doing a flush before we put up the close flag. */ private boolean worthPreFlushing() { - return this.memStoreSizing.getDataSize() - > this.conf.getLong("hbase.hregion.preclose.flush.size", 1024 * 1024 * 5); + return this.memStoreSizing.getDataSize() > this.conf.getLong("hbase.hregion.preclose.flush.size", 1024 * 1024 * 5); } ////////////////////////////////////////////////////////////////////////////// @@ -2136,10 +2241,14 @@ RegionSplitPolicy getSplitPolicy() { } /** - * A split takes the config from the parent region & passes it to the daughter region's - * constructor. If 'conf' was passed, you would end up using the HTD of the parent region in - * addition to the new daughter HTD. Pass 'baseConf' to the daughter regions to avoid this tricky + * A split takes the config from the parent region & passes it to the daughter + * region's + * constructor. If 'conf' was passed, you would end up using the HTD of the + * parent region in + * addition to the new daughter HTD. Pass 'baseConf' to the daughter regions to + * avoid this tricky * dedupe problem. + * * @return Configuration object */ Configuration getBaseConf() { @@ -2159,7 +2268,7 @@ public HRegionFileSystem getRegionFileSystem() { /** Returns the WAL {@link HRegionFileSystem} used by this region */ HRegionWALFileSystem getRegionWALFileSystem() throws IOException { return new HRegionWALFileSystem(conf, getWalFileSystem(), - CommonFSUtils.getWALTableDir(conf, htableDescriptor.getTableName()), fs.getRegionInfo()); + CommonFSUtils.getWALTableDir(conf, htableDescriptor.getTableName()), fs.getRegionInfo()); } /** Returns the WAL {@link FileSystem} being used by this region */ @@ -2177,7 +2286,7 @@ FileSystem getWalFileSystem() throws IOException { public Path getWALRegionDir() throws IOException { if (regionWalDir == null) { regionWalDir = CommonFSUtils.getWALRegionDir(conf, getRegionInfo().getTable(), - getRegionInfo().getEncodedName()); + getRegionInfo().getEncodedName()); } return regionWalDir; } @@ -2222,12 +2331,14 @@ RegionLoad.Builder setCompleteSequenceId(RegionLoad.Builder regionLoadBldr) { regionLoadBldr.clearStoreCompleteSequenceId(); for (byte[] familyName : this.stores.keySet()) { long earliest = this.wal.getEarliestMemStoreSeqNum(encodedRegionName, familyName); - // Subtract - 1 to go earlier than the current oldest, unflushed edit in memstore; this will - // give us a sequence id that is for sure flushed. We want edit replay to start after this + // Subtract - 1 to go earlier than the current oldest, unflushed edit in + // memstore; this will + // give us a sequence id that is for sure flushed. We want edit replay to start + // after this // sequence id in this region. If NO_SEQNUM, use the regions maximum flush id. long csid = (earliest == HConstants.NO_SEQNUM) ? lastFlushOpSeqIdLocal : earliest - 1; regionLoadBldr.addStoreCompleteSequenceId(StoreSequenceId.newBuilder() - .setFamilyName(UnsafeByteOperations.unsafeWrap(familyName)).setSequenceId(csid).build()); + .setFamilyName(UnsafeByteOperations.unsafeWrap(familyName)).setSequenceId(csid).build()); } return regionLoadBldr.setCompleteSequenceId(getMaxFlushedSeqId()); } @@ -2247,13 +2358,19 @@ protected void doRegionCompactionPrep() throws IOException { /** * Synchronously compact all stores in the region. *

- * This operation could block for a long time, so don't call it from a time-sensitive thread. + * This operation could block for a long time, so don't call it from a + * time-sensitive thread. *

- * Note that no locks are taken to prevent possible conflicts between compaction and splitting - * activities. The regionserver does not normally compact and split in parallel. However by - * calling this method you may introduce unexpected and unhandled concurrency. Don't do this + * Note that no locks are taken to prevent possible conflicts between compaction + * and splitting + * activities. The regionserver does not normally compact and split in parallel. + * However by + * calling this method you may introduce unexpected and unhandled concurrency. + * Don't do this * unless you know what you are doing. - * @param majorCompaction True to force a major compaction regardless of thresholds + * + * @param majorCompaction True to force a major compaction regardless of + * thresholds */ public void compact(boolean majorCompaction) throws IOException { if (majorCompaction) { @@ -2302,63 +2419,96 @@ void compactStore(byte[] family, ThroughputController throughputController) thro } /** - * Called by compaction thread and after region is opened to compact the HStores if necessary. + * Called by compaction thread and after region is opened to compact the HStores + * if necessary. *

- * This operation could block for a long time, so don't call it from a time-sensitive thread. Note - * that no locking is necessary at this level because compaction only conflicts with a region - * split, and that cannot happen because the region server does them sequentially and not in + * This operation could block for a long time, so don't call it from a + * time-sensitive thread. Note + * that no locking is necessary at this level because compaction only conflicts + * with a region + * split, and that cannot happen because the region server does them + * sequentially and not in * parallel. + * * @param compaction Compaction details, obtained by requestCompaction() * @return whether the compaction completed */ public boolean compact(CompactionContext compaction, HStore store, - ThroughputController throughputController) throws IOException { + ThroughputController throughputController) throws IOException { return compact(compaction, store, throughputController, null); } private boolean shouldForbidMajorCompaction() { if (rsServices != null && rsServices.getReplicationSourceService() != null) { return rsServices.getReplicationSourceService().getSyncReplicationPeerInfoProvider() - .checkState(getRegionInfo().getTable(), ForbidMajorCompactionChecker.get()); + .checkState(getRegionInfo().getTable(), ForbidMajorCompactionChecker.get()); } return false; } /** - * We are trying to remove / relax the region read lock for compaction. Let's see what are the - * potential race conditions among the operations (user scan, region split, region close and - * region bulk load). user scan ---> region read lock region split --> region close first --> - * region write lock region close --> region write lock region bulk load --> region write lock - * read lock is compatible with read lock. ---> no problem with user scan/read region bulk load - * does not cause problem for compaction (no consistency problem, store lock will help the store - * file accounting). They can run almost concurrently at the region level. The only remaining race - * condition is between the region close and compaction. So we will evaluate, below, how region - * close intervenes with compaction if compaction does not acquire region read lock. Here are the - * steps for compaction: 1. obtain list of StoreFile's 2. create StoreFileScanner's based on list - * from #1 3. perform compaction and save resulting files under tmp dir 4. swap in compacted files - * #1 is guarded by store lock. This patch does not change this --> no worse or better For #2, we - * obtain smallest read point (for region) across all the Scanners (for both default compactor and - * stripe compactor). The read points are for user scans. Region keeps the read points for all - * currently open user scanners. Compaction needs to know the smallest read point so that during - * re-write of the hfiles, it can remove the mvcc points for the cells if their mvccs are older - * than the smallest since they are not needed anymore. This will not conflict with compaction. - * For #3, it can be performed in parallel to other operations. For #4 bulk load and compaction - * don't conflict with each other on the region level (for multi-family atomicy). Region close and - * compaction are guarded pretty well by the 'writestate'. In HRegion#doClose(), we have : - * synchronized (writestate) { // Disable compacting and flushing by background threads for this + * We are trying to remove / relax the region read lock for compaction. Let's + * see what are the + * potential race conditions among the operations (user scan, region split, + * region close and + * region bulk load). user scan ---> region read lock region split --> region + * close first --> + * region write lock region close --> region write lock region bulk load --> + * region write lock + * read lock is compatible with read lock. ---> no problem with user scan/read + * region bulk load + * does not cause problem for compaction (no consistency problem, store lock + * will help the store + * file accounting). They can run almost concurrently at the region level. The + * only remaining race + * condition is between the region close and compaction. So we will evaluate, + * below, how region + * close intervenes with compaction if compaction does not acquire region read + * lock. Here are the + * steps for compaction: 1. obtain list of StoreFile's 2. create + * StoreFileScanner's based on list + * from #1 3. perform compaction and save resulting files under tmp dir 4. swap + * in compacted files + * #1 is guarded by store lock. This patch does not change this --> no worse or + * better For #2, we + * obtain smallest read point (for region) across all the Scanners (for both + * default compactor and + * stripe compactor). The read points are for user scans. Region keeps the read + * points for all + * currently open user scanners. Compaction needs to know the smallest read + * point so that during + * re-write of the hfiles, it can remove the mvcc points for the cells if their + * mvccs are older + * than the smallest since they are not needed anymore. This will not conflict + * with compaction. + * For #3, it can be performed in parallel to other operations. For #4 bulk load + * and compaction + * don't conflict with each other on the region level (for multi-family + * atomicy). Region close and + * compaction are guarded pretty well by the 'writestate'. In HRegion#doClose(), + * we have : + * synchronized (writestate) { // Disable compacting and flushing by background + * threads for this * // region. canFlush = !writestate.readOnly; writestate.writesEnabled = false; * LOG.debug("Closing " + this + ": disabling compactions & flushes"); - * waitForFlushesAndCompactions(); } waitForFlushesAndCompactions() would wait for - * writestate.compacting to come down to 0. and in HRegion.compact() try { synchronized - * (writestate) { if (writestate.writesEnabled) { wasStateSet = true; ++writestate.compacting; } - * else { String msg = "NOT compacting region " + this + ". Writes disabled."; LOG.info(msg); - * status.abort(msg); return false; } } Also in compactor.performCompaction(): check periodically + * waitForFlushesAndCompactions(); } waitForFlushesAndCompactions() would wait + * for + * writestate.compacting to come down to 0. and in HRegion.compact() try { + * synchronized + * (writestate) { if (writestate.writesEnabled) { wasStateSet = true; + * ++writestate.compacting; } + * else { String msg = "NOT compacting region " + this + ". Writes disabled."; + * LOG.info(msg); + * status.abort(msg); return false; } } Also in compactor.performCompaction(): + * check periodically * to see if a system stop is requested if (closeChecker != null && - * closeChecker.isTimeLimit(store, now)) { progress.cancel(); return false; } if (closeChecker != - * null && closeChecker.isSizeLimit(store, len)) { progress.cancel(); return false; } + * closeChecker.isTimeLimit(store, now)) { progress.cancel(); return false; } if + * (closeChecker != + * null && closeChecker.isSizeLimit(store, len)) { progress.cancel(); return + * false; } */ public boolean compact(CompactionContext compaction, HStore store, - ThroughputController throughputController, User user) throws IOException { + ThroughputController throughputController, User user) throws IOException { assert compaction != null && compaction.hasSelection(); assert !compaction.getRequest().getFiles().isEmpty(); if (this.closing.get() || this.closed.get()) { @@ -2369,8 +2519,8 @@ public boolean compact(CompactionContext compaction, HStore store, if (compaction.getRequest().isAllFiles() && shouldForbidMajorCompaction()) { LOG.warn("Skipping major compaction on " + this - + " because this cluster is transiting sync replication state" - + " from STANDBY to DOWNGRADE_ACTIVE"); + + " because this cluster is transiting sync replication state" + + " from STANDBY to DOWNGRADE_ACTIVE"); store.cancelRequestedCompaction(compaction); return false; } @@ -2381,8 +2531,8 @@ public boolean compact(CompactionContext compaction, HStore store, byte[] cf = Bytes.toBytes(store.getColumnFamilyName()); if (stores.get(cf) != store) { LOG.warn("Store " + store.getColumnFamilyName() + " on region " + this - + " has been re-instantiated, cancel this compaction request. " - + " It may be caused by the roll back of split transaction"); + + " has been re-instantiated, cancel this compaction request. " + + " It may be caused by the roll back of split transaction"); return false; } @@ -2407,7 +2557,7 @@ public boolean compact(CompactionContext compaction, HStore store, } } LOG.info("Starting compaction of {} in {}{}", store, this, - (compaction.getRequest().isOffPeak() ? " as an off-peak compaction" : "")); + (compaction.getRequest().isOffPeak() ? " as an off-peak compaction" : "")); doRegionCompactionPrep(); try { status.setStatus("Compacting store " + store); @@ -2434,10 +2584,11 @@ public boolean compact(CompactionContext compaction, HStore store, status.markComplete("Compaction complete"); return true; } finally { - if (requestNeedsCancellation) store.cancelRequestedCompaction(compaction); + if (requestNeedsCancellation) + store.cancelRequestedCompaction(compaction); if (status != null) { LOG.debug("Compaction status journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); status.cleanup(); } } @@ -2454,11 +2605,15 @@ public boolean compact(CompactionContext compaction, HStore store, *

  • writes are disabled
  • * *

    - * This method may block for some time, so it should not be called from a time-sensitive thread. + * This method may block for some time, so it should not be called from a + * time-sensitive thread. + * * @param flushAllStores whether we want to force a flush of all stores - * @return FlushResult indicating whether the flush was successful or not and if the region needs + * @return FlushResult indicating whether the flush was successful or not and if + * the region needs * compacting - * @throws IOException general io exceptions because a snapshot was not properly persisted. + * @throws IOException general io exceptions because a snapshot was not properly + * persisted. */ // TODO HBASE-18905. We might have to expose a requestFlush API for CPs public FlushResult flush(boolean flushAllStores) throws IOException { @@ -2469,7 +2624,8 @@ public interface FlushResult { enum Result { FLUSHED_NO_COMPACTION_NEEDED, FLUSHED_COMPACTION_NEEDED, - // Special case where a flush didn't run because there's nothing in the memstores. Used when + // Special case where a flush didn't run because there's nothing in the + // memstores. Used when // bulk loading to know when we can still load even if a flush didn't happen. CANNOT_FLUSH_MEMSTORE_EMPTY, CANNOT_FLUSH @@ -2486,7 +2642,7 @@ enum Result { } public FlushResultImpl flushcache(boolean flushAllStores, boolean writeFlushRequestWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + FlushLifeCycleTracker tracker) throws IOException { List families = null; if (flushAllStores) { families = new ArrayList<>(); @@ -2504,18 +2660,23 @@ public FlushResultImpl flushcache(boolean flushAllStores, boolean writeFlushRequ *

  • writes are disabled
  • * *

    - * This method may block for some time, so it should not be called from a time-sensitive thread. + * This method may block for some time, so it should not be called from a + * time-sensitive thread. + * * @param families stores of region to flush. - * @param writeFlushRequestWalMarker whether to write the flush request marker to WAL + * @param writeFlushRequestWalMarker whether to write the flush request marker + * to WAL * @param tracker used to track the life cycle of this flush * @return whether the flush is success and whether the region needs compacting * @throws IOException general io exceptions - * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was - * not properly persisted. The region is put in closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required + * because a Snapshot was + * not properly persisted. The region is put in + * closing mode, and * the caller MUST abort after this. */ public FlushResultImpl flushcache(List families, boolean writeFlushRequestWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + FlushLifeCycleTracker tracker) throws IOException { // fail-fast instead of waiting on the lock if (this.closing.get()) { String msg = "Skipping flush on " + this + " because closing"; @@ -2539,7 +2700,8 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque status.setStatus("Running coprocessor pre-flush hooks"); coprocessorHost.preFlush(tracker); } - // TODO: this should be managed within memstore with the snapshot, updated only after flush + // TODO: this should be managed within memstore with the snapshot, updated only + // after flush // successful if (numMutationsWithoutWAL.sum() > 0) { numMutationsWithoutWAL.reset(); @@ -2550,7 +2712,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque this.writestate.flushing = true; } else { String msg = "NOT flushing " + this + " as " - + (writestate.flushing ? "already flushing" : "writes are not enabled"); + + (writestate.flushing ? "already flushing" : "writes are not enabled"); LOG.debug(msg); status.abort(msg); flushed = false; @@ -2568,8 +2730,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque } else { specificStoresToFlush = flushPolicy.selectStoresToFlush(); } - FlushResultImpl fs = - internalFlushcache(specificStoresToFlush, status, writeFlushRequestWalMarker, tracker); + FlushResultImpl fs = internalFlushcache(specificStoresToFlush, status, writeFlushRequestWalMarker, tracker); if (coprocessorHost != null) { status.setStatus("Running post-flush coprocessor hooks"); @@ -2594,7 +2755,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque if (flushed) { // Don't log this journal stuff if no flush -- confusing. LOG.debug("Flush status journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } @@ -2602,6 +2763,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque /** * get stores which matches the specified families + * * @return the stores need to be flushed. */ private Collection getSpecificStores(List families) { @@ -2615,18 +2777,20 @@ private Collection getSpecificStores(List families) { /** * Should the store be flushed because it is old enough. *

    - * Every FlushPolicy should call this to determine whether a store is old enough to flush (except - * that you always flush all stores). Otherwise the method will always returns true which will + * Every FlushPolicy should call this to determine whether a store is old enough + * to flush (except + * that you always flush all stores). Otherwise the method will always returns + * true which will * make a lot of flush requests. */ boolean shouldFlushStore(HStore store) { long earliest = this.wal.getEarliestMemStoreSeqNum(getRegionInfo().getEncodedNameAsBytes(), - store.getColumnFamilyDescriptor().getName()) - 1; + store.getColumnFamilyDescriptor().getName()) - 1; if (earliest > 0 && earliest + flushPerChanges < mvcc.getReadPoint()) { if (LOG.isDebugEnabled()) { LOG.debug("Flush column family " + store.getColumnFamilyName() + " of " - + getRegionInfo().getEncodedName() + " because unflushed sequenceid=" + earliest - + " is > " + this.flushPerChanges + " from current=" + mvcc.getReadPoint()); + + getRegionInfo().getEncodedName() + " because unflushed sequenceid=" + earliest + + " is > " + this.flushPerChanges + " from current=" + mvcc.getReadPoint()); } return true; } @@ -2637,8 +2801,8 @@ boolean shouldFlushStore(HStore store) { if (store.timeOfOldestEdit() < now - this.flushCheckInterval) { if (LOG.isDebugEnabled()) { LOG.debug("Flush column family: " + store.getColumnFamilyName() + " of " - + getRegionInfo().getEncodedName() + " because time of oldest edit=" - + store.timeOfOldestEdit() + " is > " + this.flushCheckInterval + " from now =" + now); + + getRegionInfo().getEncodedName() + " because time of oldest edit=" + + store.timeOfOldestEdit() + " is > " + this.flushCheckInterval + " from now =" + now); } return true; } @@ -2651,18 +2815,14 @@ boolean shouldFlushStore(HStore store) { boolean shouldFlush(final StringBuilder whyFlush) { whyFlush.setLength(0); // This is a rough measure. - if ( - this.maxFlushedSeqId > 0 - && (this.maxFlushedSeqId + this.flushPerChanges < this.mvcc.getReadPoint()) - ) { + if (this.maxFlushedSeqId > 0 + && (this.maxFlushedSeqId + this.flushPerChanges < this.mvcc.getReadPoint())) { whyFlush.append("more than max edits, " + this.flushPerChanges + ", since last flush"); return true; } long modifiedFlushCheckInterval = flushCheckInterval; - if ( - getRegionInfo().getTable().isSystemTable() - && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID - ) { + if (getRegionInfo().getTable().isSystemTable() + && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID) { modifiedFlushCheckInterval = SYSTEM_CACHE_FLUSH_INTERVAL; } if (modifiedFlushCheckInterval <= 0) { // disabled @@ -2687,7 +2847,9 @@ && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID /** * Flushing all stores. - * @see #internalFlushcache(Collection, MonitoredTask, boolean, FlushLifeCycleTracker) + * + * @see #internalFlushcache(Collection, MonitoredTask, boolean, + * FlushLifeCycleTracker) */ private FlushResult internalFlushcache(MonitoredTask status) throws IOException { return internalFlushcache(stores.values(), status, false, FlushLifeCycleTracker.DUMMY); @@ -2695,37 +2857,48 @@ private FlushResult internalFlushcache(MonitoredTask status) throws IOException /** * Flushing given stores. - * @see #internalFlushcache(WAL, long, Collection, MonitoredTask, boolean, FlushLifeCycleTracker) + * + * @see #internalFlushcache(WAL, long, Collection, MonitoredTask, boolean, + * FlushLifeCycleTracker) */ private FlushResultImpl internalFlushcache(Collection storesToFlush, MonitoredTask status, - boolean writeFlushWalMarker, FlushLifeCycleTracker tracker) throws IOException { + boolean writeFlushWalMarker, FlushLifeCycleTracker tracker) throws IOException { return internalFlushcache(this.wal, HConstants.NO_SEQNUM, storesToFlush, status, - writeFlushWalMarker, tracker); + writeFlushWalMarker, tracker); } /** - * Flush the memstore. Flushing the memstore is a little tricky. We have a lot of updates in the - * memstore, all of which have also been written to the wal. We need to write those updates in the - * memstore out to disk, while being able to process reads/writes as much as possible during the + * Flush the memstore. Flushing the memstore is a little tricky. We have a lot + * of updates in the + * memstore, all of which have also been written to the wal. We need to write + * those updates in the + * memstore out to disk, while being able to process reads/writes as much as + * possible during the * flush operation. *

    - * This method may block for some time. Every time you call it, we up the regions sequence id even - * if we don't flush; i.e. the returned region id will be at least one larger than the last edit - * applied to this region. The returned id does not refer to an actual edit. The returned id can - * be used for say installing a bulk loaded file just ahead of the last hfile that was the result + * This method may block for some time. Every time you call it, we up the + * regions sequence id even + * if we don't flush; i.e. the returned region id will be at least one larger + * than the last edit + * applied to this region. The returned id does not refer to an actual edit. The + * returned id can + * be used for say installing a bulk loaded file just ahead of the last hfile + * that was the result * of this flush, etc. + * * @param wal Null if we're NOT to go via wal. - * @param myseqid The seqid to use if wal is null writing out flush file. + * @param myseqid The seqid to use if wal is null writing out + * flush file. * @param storesToFlush The list of stores to flush. * @return object describing the flush's state * @throws IOException general io exceptions * @throws DroppedSnapshotException Thrown when replay of WAL is required. */ protected FlushResultImpl internalFlushcache(WAL wal, long myseqid, - Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, - FlushLifeCycleTracker tracker) throws IOException { - PrepareFlushResult result = - internalPrepareFlushCache(wal, myseqid, storesToFlush, status, writeFlushWalMarker, tracker); + Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, + FlushLifeCycleTracker tracker) throws IOException { + PrepareFlushResult result = internalPrepareFlushCache(wal, myseqid, storesToFlush, status, writeFlushWalMarker, + tracker); if (result.result == null) { return internalFlushCacheAndCommit(wal, status, result, storesToFlush); } else { @@ -2733,20 +2906,22 @@ protected FlushResultImpl internalFlushcache(WAL wal, long myseqid, } } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DLS_DEAD_LOCAL_STORE", - justification = "FindBugs seems confused about trxId") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "FindBugs seems confused about trxId") protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, - Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, + FlushLifeCycleTracker tracker) throws IOException { if (this.rsServices != null && this.rsServices.isAborted()) { // Don't flush when server aborting, it's unsafe throw new IOException("Aborting flush because server is aborted..."); } final long startTime = EnvironmentEdgeManager.currentTime(); // If nothing to flush, return, but return with a valid unused sequenceId. - // Its needed by bulk upload IIRC. It flushes until no edits in memory so it can insert a - // bulk loaded file between memory and existing hfiles. It wants a good seqeunceId that belongs - // to no other that it can use to associate with the bulk load. Hence this little dance below + // Its needed by bulk upload IIRC. It flushes until no edits in memory so it can + // insert a + // bulk loaded file between memory and existing hfiles. It wants a good + // seqeunceId that belongs + // to no other that it can use to associate with the bulk load. Hence this + // little dance below // to go get one. if (this.memStoreSizing.getDataSize() <= 0) { // Take an update lock so no edits can come into memory just yet. @@ -2754,29 +2929,34 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, WriteEntry writeEntry = null; try { if (this.memStoreSizing.getDataSize() <= 0) { - // Presume that if there are still no edits in the memstore, then there are no edits for - // this region out in the WAL subsystem so no need to do any trickery clearing out - // edits in the WAL sub-system. Up the sequence number so the resulting flush id is for - // sure just beyond the last appended region edit and not associated with any edit + // Presume that if there are still no edits in the memstore, then there are no + // edits for + // this region out in the WAL subsystem so no need to do any trickery clearing + // out + // edits in the WAL sub-system. Up the sequence number so the resulting flush id + // is for + // sure just beyond the last appended region edit and not associated with any + // edit // (useful as marker when bulk loading, etc.). if (wal != null) { writeEntry = mvcc.begin(); long flushOpSeqId = writeEntry.getWriteNumber(); FlushResultImpl flushResult = new FlushResultImpl( - FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, flushOpSeqId, "Nothing to flush", - writeCanNotFlushMarkerToWAL(writeEntry, wal, writeFlushWalMarker)); + FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, flushOpSeqId, "Nothing to flush", + writeCanNotFlushMarkerToWAL(writeEntry, wal, writeFlushWalMarker)); mvcc.completeAndWait(writeEntry); // Set to null so we don't complete it again down in finally block. writeEntry = null; return new PrepareFlushResult(flushResult, myseqid); } else { return new PrepareFlushResult(new FlushResultImpl( - FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, "Nothing to flush", false), myseqid); + FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, "Nothing to flush", false), myseqid); } } } finally { if (writeEntry != null) { - // If writeEntry is non-null, this operation failed; the mvcc transaction failed... + // If writeEntry is non-null, this operation failed; the mvcc transaction + // failed... // but complete it anyways so it doesn't block the mvcc queue. mvcc.complete(writeEntry); } @@ -2784,12 +2964,16 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, } } logFatLineOnFlush(storesToFlush, myseqid); - // Stop updates while we snapshot the memstore of all of these regions' stores. We only have - // to do this for a moment. It is quick. We also set the memstore size to zero here before we - // allow updates again so its value will represent the size of the updates received + // Stop updates while we snapshot the memstore of all of these regions' stores. + // We only have + // to do this for a moment. It is quick. We also set the memstore size to zero + // here before we + // allow updates again so its value will represent the size of the updates + // received // during flush - // We have to take an update lock during snapshot, or else a write could end up in both snapshot + // We have to take an update lock during snapshot, or else a write could end up + // in both snapshot // and memstore (makes it difficult to do atomic rows then) status.setStatus("Obtaining lock to block concurrent updates"); // block waiting for the lock for internal flush @@ -2800,36 +2984,41 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, Map flushedFamilyNamesToSeq = new HashMap<>(); for (HStore store : storesToFlush) { flushedFamilyNamesToSeq.put(store.getColumnFamilyDescriptor().getName(), - store.preFlushSeqIDEstimation()); + store.preFlushSeqIDEstimation()); } TreeMap storeFlushCtxs = new TreeMap<>(Bytes.BYTES_COMPARATOR); TreeMap> committedFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR); TreeMap storeFlushableSize = new TreeMap<>(Bytes.BYTES_COMPARATOR); - // The sequence id of this flush operation which is used to log FlushMarker and pass to - // createFlushContext to use as the store file's sequence id. It can be in advance of edits - // still in the memstore, edits that are in other column families yet to be flushed. + // The sequence id of this flush operation which is used to log FlushMarker and + // pass to + // createFlushContext to use as the store file's sequence id. It can be in + // advance of edits + // still in the memstore, edits that are in other column families yet to be + // flushed. long flushOpSeqId = HConstants.NO_SEQNUM; - // The max flushed sequence id after this flush operation completes. All edits in memstore + // The max flushed sequence id after this flush operation completes. All edits + // in memstore // will be in advance of this sequence id. long flushedSeqId = HConstants.NO_SEQNUM; byte[] encodedRegionName = getRegionInfo().getEncodedNameAsBytes(); try { if (wal != null) { - Long earliestUnflushedSequenceIdForTheRegion = - wal.startCacheFlush(encodedRegionName, flushedFamilyNamesToSeq); + Long earliestUnflushedSequenceIdForTheRegion = wal.startCacheFlush(encodedRegionName, flushedFamilyNamesToSeq); if (earliestUnflushedSequenceIdForTheRegion == null) { - // This should never happen. This is how startCacheFlush signals flush cannot proceed. + // This should never happen. This is how startCacheFlush signals flush cannot + // proceed. String msg = this.getRegionInfo().getEncodedName() + " flush aborted; WAL closing."; status.setStatus(msg); return new PrepareFlushResult( - new FlushResultImpl(FlushResult.Result.CANNOT_FLUSH, msg, false), myseqid); + new FlushResultImpl(FlushResult.Result.CANNOT_FLUSH, msg, false), myseqid); } flushOpSeqId = getNextSequenceId(wal); - // Back up 1, minus 1 from oldest sequence id in memstore to get last 'flushed' edit + // Back up 1, minus 1 from oldest sequence id in memstore to get last 'flushed' + // edit flushedSeqId = earliestUnflushedSequenceIdForTheRegion.longValue() == HConstants.NO_SEQNUM - ? flushOpSeqId - : earliestUnflushedSequenceIdForTheRegion.longValue() - 1; + ? flushOpSeqId + : earliestUnflushedSequenceIdForTheRegion.longValue() - 1; } else { // use the provided sequence Id as WAL is not being used for this flush. flushedSeqId = flushOpSeqId = myseqid; @@ -2837,7 +3026,7 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, for (HStore s : storesToFlush) { storeFlushCtxs.put(s.getColumnFamilyDescriptor().getName(), - s.createFlushContext(flushOpSeqId, tracker)); + s.createFlushContext(flushOpSeqId, tracker)); // for writing stores to WAL committedFiles.put(s.getColumnFamilyDescriptor().getName(), null); } @@ -2845,10 +3034,11 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, // write the snapshot start to WAL if (wal != null && !writestate.readOnly) { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.START_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); - // No sync. Sync is below where no updates lock and we do FlushAction.COMMIT_FLUSH + getRegionInfo(), flushOpSeqId, committedFiles); + // No sync. Sync is below where no updates lock and we do + // FlushAction.COMMIT_FLUSH WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, false, - mvcc, regionReplicationSink.orElse(null)); + mvcc, regionReplicationSink.orElse(null)); } // Prepare flush (take a snapshot) @@ -2864,15 +3054,16 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, this.updatesLock.writeLock().unlock(); } String s = "Finished memstore snapshotting " + this + ", syncing WAL and waiting on mvcc, " - + "flushsize=" + totalSizeOfFlushableStores; + + "flushsize=" + totalSizeOfFlushableStores; status.setStatus(s); doSyncOfUnflushedWALChanges(wal, getRegionInfo()); return new PrepareFlushResult(storeFlushCtxs, committedFiles, storeFlushableSize, startTime, - flushOpSeqId, flushedSeqId, totalSizeOfFlushableStores); + flushOpSeqId, flushedSeqId, totalSizeOfFlushableStores); } /** - * Utility method broken out of internalPrepareFlushCache so that method is smaller. + * Utility method broken out of internalPrepareFlushCache so that method is + * smaller. */ private void logFatLineOnFlush(Collection storesToFlush, long sequenceId) { if (!LOG.isInfoEnabled()) { @@ -2893,23 +3084,24 @@ private void logFatLineOnFlush(Collection storesToFlush, long sequenceId } MemStoreSize mss = this.memStoreSizing.getMemStoreSize(); LOG.info("Flushing " + this.getRegionInfo().getEncodedName() + " " + storesToFlush.size() + "/" - + stores.size() + " column families," + " dataSize=" + StringUtils.byteDesc(mss.getDataSize()) - + " heapSize=" + StringUtils.byteDesc(mss.getHeapSize()) - + ((perCfExtras != null && perCfExtras.length() > 0) ? perCfExtras.toString() : "") - + ((wal != null) ? "" : "; WAL is null, using passed sequenceid=" + sequenceId)); + + stores.size() + " column families," + " dataSize=" + StringUtils.byteDesc(mss.getDataSize()) + + " heapSize=" + StringUtils.byteDesc(mss.getHeapSize()) + + ((perCfExtras != null && perCfExtras.length() > 0) ? perCfExtras.toString() : "") + + ((wal != null) ? "" : "; WAL is null, using passed sequenceid=" + sequenceId)); } private void doAbortFlushToWAL(final WAL wal, final long flushOpSeqId, - final Map> committedFiles) { - if (wal == null) return; + final Map> committedFiles) { + if (wal == null) + return; try { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.ABORT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, false, mvcc, - null); + null); } catch (Throwable t) { LOG.warn("Received unexpected exception trying to write ABORT_FLUSH marker to WAL: {} in " - + " region {}", StringUtils.stringifyException(t), this); + + " region {}", StringUtils.stringifyException(t), this); // ignore this since we will be aborting the RS with DSE. } // we have called wal.startCacheFlush(), now we have to abort it @@ -2920,7 +3112,7 @@ private void doAbortFlushToWAL(final WAL wal, final long flushOpSeqId, * Sync unflushed WAL changes. See HBASE-8208 for details */ private static void doSyncOfUnflushedWALChanges(final WAL wal, final RegionInfo hri) - throws IOException { + throws IOException { if (wal == null) { return; } @@ -2938,22 +3130,27 @@ private boolean isAllFamilies(Collection families) { } /** - * This method is only used when we flush but the memstore is empty,if writeFlushWalMarker is - * true,we write the {@link FlushAction#CANNOT_FLUSH} flush marker to WAL when the memstore is + * This method is only used when we flush but the memstore is empty,if + * writeFlushWalMarker is + * true,we write the {@link FlushAction#CANNOT_FLUSH} flush marker to WAL when + * the memstore is * empty. Ignores exceptions from WAL. Returns whether the write succeeded. + * * @return whether WAL write was successful */ private boolean writeCanNotFlushMarkerToWAL(WriteEntry flushOpSeqIdMVCCEntry, WAL wal, - boolean writeFlushWalMarker) { + boolean writeFlushWalMarker) { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.CANNOT_FLUSH, getRegionInfo(), - -1, new TreeMap<>(Bytes.BYTES_COMPARATOR)); + -1, new TreeMap<>(Bytes.BYTES_COMPARATOR)); RegionReplicationSink sink = regionReplicationSink.orElse(null); if (sink != null && !writeFlushWalMarker) { /** - * Here for replication to secondary region replica could use {@link FlushAction#CANNOT_FLUSH} + * Here for replication to secondary region replica could use + * {@link FlushAction#CANNOT_FLUSH} * to recover when writeFlushWalMarker is false, we create {@link WALEdit} for - * {@link FlushDescriptor} and attach the {@link RegionReplicationSink#add} to the + * {@link FlushDescriptor} and attach the {@link RegionReplicationSink#add} to + * the * flushOpSeqIdMVCCEntry,see HBASE-26960 for more details. */ this.attachRegionReplicationToFlushOpSeqIdMVCCEntry(flushOpSeqIdMVCCEntry, desc, sink); @@ -2963,38 +3160,38 @@ private boolean writeCanNotFlushMarkerToWAL(WriteEntry flushOpSeqIdMVCCEntry, WA if (writeFlushWalMarker && wal != null && !writestate.readOnly) { try { WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, true, mvcc, - sink); + sink); return true; } catch (IOException e) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received exception while trying to write the flush request to wal", e); + + "Received exception while trying to write the flush request to wal", e); } } return false; } /** - * Create {@link WALEdit} for {@link FlushDescriptor} and attach {@link RegionReplicationSink#add} + * Create {@link WALEdit} for {@link FlushDescriptor} and attach + * {@link RegionReplicationSink#add} * to the flushOpSeqIdMVCCEntry. */ private void attachRegionReplicationToFlushOpSeqIdMVCCEntry(WriteEntry flushOpSeqIdMVCCEntry, - FlushDescriptor desc, RegionReplicationSink sink) { + FlushDescriptor desc, RegionReplicationSink sink) { assert !flushOpSeqIdMVCCEntry.getCompletionAction().isPresent(); WALEdit flushMarkerWALEdit = WALEdit.createFlushWALEdit(getRegionInfo(), desc); - WALKeyImpl walKey = - WALUtil.createWALKey(getRegionInfo(), mvcc, this.getReplicationScope(), null); + WALKeyImpl walKey = WALUtil.createWALKey(getRegionInfo(), mvcc, this.getReplicationScope(), null); walKey.setWriteEntry(flushOpSeqIdMVCCEntry); /** - * Here the {@link ServerCall} is null for {@link RegionReplicationSink#add} because the + * Here the {@link ServerCall} is null for {@link RegionReplicationSink#add} + * because the * flushMarkerWALEdit is created by ourselves, not from rpc. */ flushOpSeqIdMVCCEntry.attachCompletionAction(() -> sink.add(walKey, flushMarkerWALEdit, null)); } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", - justification = "Intentional; notify is about completed flush") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; notify is about completed flush") FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, - PrepareFlushResult prepareResult, Collection storesToFlush) throws IOException { + PrepareFlushResult prepareResult, Collection storesToFlush) throws IOException { // prepare flush context is carried via PrepareFlushResult TreeMap storeFlushCtxs = prepareResult.storeFlushCtxs; TreeMap> committedFiles = prepareResult.committedFiles; @@ -3004,7 +3201,8 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, String s = "Flushing stores of " + this; status.setStatus(s); - if (LOG.isTraceEnabled()) LOG.trace(s); + if (LOG.isTraceEnabled()) + LOG.trace(s); // Any failure from here on out will be catastrophic requiring server // restart so wal content can be replayed and put back into the memstore. @@ -3046,22 +3244,23 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, MemStoreSize mss = prepareResult.totalFlushableSize.getMemStoreSize(); this.decrMemStoreSize(mss); - // Increase the size of this Region for the purposes of quota. Noop if quotas are disabled. + // Increase the size of this Region for the purposes of quota. Noop if quotas + // are disabled. // During startup, quota manager may not be initialized yet. if (rsServices != null) { RegionServerSpaceQuotaManager quotaManager = rsServices.getRegionServerSpaceQuotaManager(); if (quotaManager != null) { quotaManager.getRegionSizeStore().incrementRegionSize(this.getRegionInfo(), - flushedOutputFileSize); + flushedOutputFileSize); } } if (wal != null) { // write flush marker to WAL. If fail, we should throw DroppedSnapshotException FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.COMMIT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, true, mvcc, - regionReplicationSink.orElse(null)); + regionReplicationSink.orElse(null)); } } catch (Throwable t) { // An exception here means that the snapshot was not persisted. @@ -3073,29 +3272,33 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, if (wal != null) { try { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.ABORT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.replicationScope, getRegionInfo(), desc, false, mvcc, - null); + null); } catch (Throwable ex) { LOG.warn( - getRegionInfo().getEncodedName() + " : " + "failed writing ABORT_FLUSH marker to WAL", - ex); + getRegionInfo().getEncodedName() + " : " + "failed writing ABORT_FLUSH marker to WAL", + ex); // ignore this since we will be aborting the RS with DSE. } wal.abortCacheFlush(this.getRegionInfo().getEncodedNameAsBytes()); } DroppedSnapshotException dse = new DroppedSnapshotException( - "region: " + Bytes.toStringBinary(getRegionInfo().getRegionName()), t); + "region: " + Bytes.toStringBinary(getRegionInfo().getRegionName()), t); status.abort("Flush failed: " + StringUtils.stringifyException(t)); - // Callers for flushcache() should catch DroppedSnapshotException and abort the region server. - // However, since we may have the region read lock, we cannot call close(true) here since - // we cannot promote to a write lock. Instead we are setting closing so that all other region + // Callers for flushcache() should catch DroppedSnapshotException and abort the + // region server. + // However, since we may have the region read lock, we cannot call close(true) + // here since + // we cannot promote to a write lock. Instead we are setting closing so that all + // other region // operations except for close will be rejected. this.closing.set(true); if (rsServices != null) { - // This is a safeguard against the case where the caller fails to explicitly handle aborting + // This is a safeguard against the case where the caller fails to explicitly + // handle aborting rsServices.abort("Replay of WAL required. Forcing server shutdown", dse); } @@ -3125,26 +3328,27 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, MemStoreSize mss = prepareResult.totalFlushableSize.getMemStoreSize(); long memstoresize = this.memStoreSizing.getMemStoreSize().getDataSize(); String msg = "Finished flush of" + " dataSize ~" + StringUtils.byteDesc(mss.getDataSize()) + "/" - + mss.getDataSize() + ", heapSize ~" + StringUtils.byteDesc(mss.getHeapSize()) + "/" - + mss.getHeapSize() + ", currentSize=" + StringUtils.byteDesc(memstoresize) + "/" - + memstoresize + " for " + this.getRegionInfo().getEncodedName() + " in " + time - + "ms, sequenceid=" + flushOpSeqId + ", compaction requested=" + compactionRequested - + ((wal == null) ? "; wal=null" : ""); + + mss.getDataSize() + ", heapSize ~" + StringUtils.byteDesc(mss.getHeapSize()) + "/" + + mss.getHeapSize() + ", currentSize=" + StringUtils.byteDesc(memstoresize) + "/" + + memstoresize + " for " + this.getRegionInfo().getEncodedName() + " in " + time + + "ms, sequenceid=" + flushOpSeqId + ", compaction requested=" + compactionRequested + + ((wal == null) ? "; wal=null" : ""); LOG.info(msg); status.setStatus(msg); if (rsServices != null && rsServices.getMetrics() != null) { rsServices.getMetrics().updateFlush(getTableDescriptor().getTableName().getNameAsString(), - time, mss.getDataSize(), flushedOutputFileSize); + time, mss.getDataSize(), flushedOutputFileSize); } return new FlushResultImpl(compactionRequested - ? FlushResult.Result.FLUSHED_COMPACTION_NEEDED - : FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, flushOpSeqId); + ? FlushResult.Result.FLUSHED_COMPACTION_NEEDED + : FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, flushOpSeqId); } /** * Method to safely get the next sequence number. + * * @return Next sequence number unassociated with any actual edit. */ protected long getNextSequenceId(final WAL wal) throws IOException { @@ -3164,12 +3368,12 @@ public RegionScannerImpl getScanner(Scan scan) throws IOException { @Override public RegionScannerImpl getScanner(Scan scan, List additionalScanners) - throws IOException { + throws IOException { return getScanner(scan, additionalScanners, HConstants.NO_NONCE, HConstants.NO_NONCE); } private RegionScannerImpl getScanner(Scan scan, List additionalScanners, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { return TraceUtil.trace(() -> { startRegionOperation(Operation.SCAN); try { @@ -3192,7 +3396,7 @@ private RegionScannerImpl getScanner(Scan scan, List additional } protected RegionScannerImpl instantiateRegionScanner(Scan scan, - List additionalScanners, long nonceGroup, long nonce) throws IOException { + List additionalScanners, long nonceGroup, long nonce) throws IOException { if (scan.isReversed()) { if (scan.getFilter() != null) { scan.getFilter().setReversed(true); @@ -3204,6 +3408,7 @@ protected RegionScannerImpl instantiateRegionScanner(Scan scan, /** * Prepare a delete for a row mutation processor + * * @param delete The passed delete is modified by this method. WARNING! */ private void prepareDelete(Delete delete) throws IOException { @@ -3230,7 +3435,8 @@ public void delete(Delete delete) throws IOException { checkResources(); startRegionOperation(Operation.DELETE); try { - // All edits for the given row (across all column families) must happen atomically. + // All edits for the given row (across all column families) must happen + // atomically. return mutate(delete); } finally { closeRegionOperation(Operation.DELETE); @@ -3244,7 +3450,7 @@ public void delete(Delete delete) throws IOException { * Caller should have the row and region locks. */ private void prepareDeleteTimestamps(Mutation mutation, Map> familyMap, - byte[] byteNow) throws IOException { + byte[] byteNow) throws IOException { for (Map.Entry> e : familyMap.entrySet()) { byte[] family = e.getKey(); @@ -3257,9 +3463,7 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> Cell cell = cells.get(i); // Check if time is LATEST, change to time of most recent addition if so // This is expensive. - if ( - cell.getTimestamp() == HConstants.LATEST_TIMESTAMP && PrivateCellUtil.isDeleteType(cell) - ) { + if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP && PrivateCellUtil.isDeleteType(cell)) { byte[] qual = CellUtil.cloneQualifier(cell); Integer count = kvCount.get(qual); @@ -3274,9 +3478,7 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> get.readVersions(count); get.addColumn(family, qual); if (coprocessorHost != null) { - if ( - !coprocessorHost.prePrepareTimeStampForDeleteVersion(mutation, cell, byteNow, get) - ) { + if (!coprocessorHost.prePrepareTimeStampForDeleteVersion(mutation, cell, byteNow, get)) { updateDeleteLatestVersionTimestamp(cell, get, count, byteNow); } } else { @@ -3290,7 +3492,7 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> } private void updateDeleteLatestVersionTimestamp(Cell cell, Get get, int count, byte[] byteNow) - throws IOException { + throws IOException { try (RegionScanner scanner = getScanner(new Scan(get))) { // NOTE: Please don't use HRegion.get() instead, // because it will copy cells to heap. See HBASE-26036 @@ -3322,7 +3524,8 @@ public void put(Put put) throws IOException { checkResources(); startRegionOperation(Operation.PUT); try { - // All edits for the given row (across all column families) must happen atomically. + // All edits for the given row (across all column families) must happen + // atomically. return mutate(put); } finally { closeRegionOperation(Operation.PUT); @@ -3331,15 +3534,18 @@ public void put(Put put) throws IOException { } /** - * Class that tracks the progress of a batch operations, accumulating status codes and tracking - * the index at which processing is proceeding. These batch operations may get split into + * Class that tracks the progress of a batch operations, accumulating status + * codes and tracking + * the index at which processing is proceeding. These batch operations may get + * split into * mini-batches for processing. */ private abstract static class BatchOperation { protected final T[] operations; protected final OperationStatus[] retCodeDetails; protected final WALEdit[] walEditsFromCoprocessors; - // reference family cell maps directly so coprocessors can mutate them if desired + // reference family cell maps directly so coprocessors can mutate them if + // desired protected final Map>[] familyCellMaps; // For Increment/Append operations protected final Result[] results; @@ -3380,7 +3586,7 @@ interface Visitor { * Helper method for visiting pending/ all batch operations */ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Visitor visitor) - throws IOException { + throws IOException { assert lastIndexExclusive <= this.size(); for (int i = nextIndexToProcess; i < lastIndexExclusive; i++) { if (!pendingOnly || isOperationPending(i)) { @@ -3398,7 +3604,8 @@ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Vi public abstract long getNonce(int index); /** - * This method is potentially expensive and useful mostly for non-replay CP path. + * This method is potentially expensive and useful mostly for non-replay CP + * path. */ public abstract Mutation[] getMutationsForCoprocs(); @@ -3411,42 +3618,48 @@ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Vi public abstract void closeRegionOperation() throws IOException; /** - * Validates each mutation and prepares a batch for write. If necessary (non-replay case), runs - * CP prePut()/preDelete()/preIncrement()/preAppend() hooks for all mutations in a batch. This - * is intended to operate on entire batch and will be called from outside of class to check and + * Validates each mutation and prepares a batch for write. If necessary + * (non-replay case), runs + * CP prePut()/preDelete()/preIncrement()/preAppend() hooks for all mutations in + * a batch. This + * is intended to operate on entire batch and will be called from outside of + * class to check and * prepare batch. This can be implemented by calling helper method * {@link #checkAndPrepareMutation(int, long)} in a 'for' loop over mutations. */ public abstract void checkAndPrepare() throws IOException; /** - * Implement any Put request specific check and prepare logic here. Please refer to + * Implement any Put request specific check and prepare logic here. Please refer + * to * {@link #checkAndPrepareMutation(Mutation, long)} for how its used. */ protected abstract void checkAndPreparePut(final Put p) throws IOException; /** - * If necessary, calls preBatchMutate() CP hook for a mini-batch and updates metrics, cell + * If necessary, calls preBatchMutate() CP hook for a mini-batch and updates + * metrics, cell * count, tags and timestamp for all cells of all operations in a mini-batch. */ public abstract void prepareMiniBatchOperations( - MiniBatchOperationInProgress miniBatchOp, long timestamp, - final List acquiredRowLocks) throws IOException; + MiniBatchOperationInProgress miniBatchOp, long timestamp, + final List acquiredRowLocks) throws IOException; /** * Write mini-batch operations to MemStore */ public abstract WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, - long now) throws IOException; + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, + long now) throws IOException; protected void writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final long writeNumber) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final long writeNumber) + throws IOException { MemStoreSizing memStoreAccounting = new NonThreadSafeMemStoreSizing(); visitBatchOperations(true, miniBatchOp.getLastIndexExclusive(), (int index) -> { // We need to update the sequence id for following reasons. - // 1) If the op is in replay mode, FSWALEntry#stampRegionSequenceId won't stamp sequence id. + // 1) If the op is in replay mode, FSWALEntry#stampRegionSequenceId won't stamp + // sequence id. // 2) If no WAL, FSWALEntry won't be used // we use durability of the original mutation for the mutation passed by CP. if (isInReplay() || getMutation(index).getDurability() == Durability.SKIP_WAL) { @@ -3457,7 +3670,7 @@ protected void writeMiniBatchOperationsToMemStore( }); // update memStore size region.incMemStoreSize(memStoreAccounting.getDataSize(), memStoreAccounting.getHeapSize(), - memStoreAccounting.getOffHeapSize(), memStoreAccounting.getCellsCount()); + memStoreAccounting.getOffHeapSize(), memStoreAccounting.getCellsCount()); } public boolean isDone() { @@ -3482,14 +3695,17 @@ boolean isAtomic() { } /** - * Helper method that checks and prepares only one mutation. This can be used to implement + * Helper method that checks and prepares only one mutation. This can be used to + * implement * {@link #checkAndPrepare()} for entire Batch. NOTE: As CP - * prePut()/preDelete()/preIncrement()/preAppend() hooks may modify mutations, this method - * should be called after prePut()/preDelete()/preIncrement()/preAppend() CP hooks are run for + * prePut()/preDelete()/preIncrement()/preAppend() hooks may modify mutations, + * this method + * should be called after prePut()/preDelete()/preIncrement()/preAppend() CP + * hooks are run for * the mutation */ protected void checkAndPrepareMutation(Mutation mutation, final long timestamp) - throws IOException { + throws IOException { region.checkRow(mutation.getRow(), "batchMutate"); if (mutation instanceof Put) { // Check the families in the put. If bad, skip this one. @@ -3512,7 +3728,8 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep familyCellMaps[index] = mutation.getFamilyCellMap(); } - // store durability for the batch (highest durability of all operations in the batch) + // store durability for the batch (highest durability of all operations in the + // batch) Durability tmpDur = region.getEffectiveDurability(mutation.getDurability()); if (tmpDur.ordinal() > durability.ordinal()) { durability = tmpDur; @@ -3525,8 +3742,7 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, nscfe); observedExceptions.sawNoSuchFamily(); } - retCodeDetails[index] = - new OperationStatus(OperationStatusCode.BAD_FAMILY, nscfe.getMessage()); + retCodeDetails[index] = new OperationStatus(OperationStatusCode.BAD_FAMILY, nscfe.getMessage()); if (isAtomic()) { // fail, atomic means all or none throw nscfe; } @@ -3538,8 +3754,7 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, fsce); observedExceptions.sawFailedSanityCheck(); } - retCodeDetails[index] = - new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, fsce.getMessage()); + retCodeDetails[index] = new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, fsce.getMessage()); if (isAtomic()) { throw fsce; } @@ -3551,8 +3766,7 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, we); observedExceptions.sawWrongRegion(); } - retCodeDetails[index] = - new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, we.getMessage()); + retCodeDetails[index] = new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, we.getMessage()); if (isAtomic()) { throw we; } @@ -3560,14 +3774,18 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep } /** - * Creates Mini-batch of all operations [nextIndexToProcess, lastIndexExclusive) for which a row - * lock can be acquired. All mutations with locked rows are considered to be In-progress - * operations and hence the name {@link MiniBatchOperationInProgress}. Mini batch is window over + * Creates Mini-batch of all operations [nextIndexToProcess, lastIndexExclusive) + * for which a row + * lock can be acquired. All mutations with locked rows are considered to be + * In-progress + * operations and hence the name {@link MiniBatchOperationInProgress}. Mini + * batch is window over * {@link BatchOperation} and contains contiguous pending operations. + * * @param acquiredRowLocks keeps track of rowLocks acquired. */ - public MiniBatchOperationInProgress - lockRowsAndBuildMiniBatch(List acquiredRowLocks) throws IOException { + public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List acquiredRowLocks) + throws IOException { int readyToWriteCount = 0; int lastIndexExclusive = 0; RowLock prevRowLock = null; @@ -3582,14 +3800,16 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep continue; } - // HBASE-19389 Limit concurrency of put with dense (hundreds) columns to avoid exhausting + // HBASE-19389 Limit concurrency of put with dense (hundreds) columns to avoid + // exhausting // RS handlers, covering both MutationBatchOperation and ReplayBatchOperation - // The BAD_FAMILY/SANITY_CHECK_FAILURE cases are handled in checkAndPrepare phase and won't + // The BAD_FAMILY/SANITY_CHECK_FAILURE cases are handled in checkAndPrepare + // phase and won't // pass the isOperationPending check - Map> curFamilyCellMap = - getMutation(lastIndexExclusive).getFamilyCellMap(); + Map> curFamilyCellMap = getMutation(lastIndexExclusive).getFamilyCellMap(); try { - // start the protector before acquiring row lock considering performance, and will finish + // start the protector before acquiring row lock considering performance, and + // will finish // it when encountering exception region.storeHotnessProtector.start(curFamilyCellMap); } catch (RegionTooBusyException rtbe) { @@ -3597,8 +3817,8 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep if (isAtomic()) { throw rtbe; } - retCodeDetails[lastIndexExclusive] = - new OperationStatus(OperationStatusCode.STORE_TOO_BUSY, rtbe.getMessage()); + retCodeDetails[lastIndexExclusive] = new OperationStatus(OperationStatusCode.STORE_TOO_BUSY, + rtbe.getMessage()); continue; } @@ -3617,7 +3837,7 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep throw e; } catch (IOException ioe) { LOG.warn("Failed getting lock, row={}, in region {}", - Bytes.toStringBinary(mutation.getRow()), this, ioe); + Bytes.toStringBinary(mutation.getRow()), this, ioe); if (isAtomic()) { // fail, atomic means all or none throwException = true; throw ioe; @@ -3652,9 +3872,9 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep } protected MiniBatchOperationInProgress createMiniBatch(final int lastIndexExclusive, - final int readyToWriteCount) { + final int readyToWriteCount) { return new MiniBatchOperationInProgress<>(getMutationsForCoprocs(), retCodeDetails, - walEditsFromCoprocessors, nextIndexToProcess, lastIndexExclusive, readyToWriteCount); + walEditsFromCoprocessors, nextIndexToProcess, lastIndexExclusive, readyToWriteCount); } protected WALEdit createWALEdit(final MiniBatchOperationInProgress miniBatchOp) { @@ -3662,11 +3882,12 @@ protected WALEdit createWALEdit(final MiniBatchOperationInProgress min } /** - * Builds separate WALEdit per nonce by applying input mutations. If WALEdits from CP are + * Builds separate WALEdit per nonce by applying input mutations. If WALEdits + * from CP are * present, they are merged to result WALEdit. */ - public List> - buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) throws IOException { + public List> buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) + throws IOException { List> walEdits = new ArrayList<>(); visitBatchOperations(true, nextIndexToProcess + miniBatchOp.size(), new Visitor() { @@ -3679,7 +3900,8 @@ public boolean visit(int index) throws IOException { if (region.getEffectiveDurability(m.getDurability()) == Durability.SKIP_WAL) { region.recordMutationWithoutWal(m.getFamilyCellMap()); /** - * Here is for HBASE-26993,in order to make the new framework for region replication + * Here is for HBASE-26993,in order to make the new framework for region + * replication * could work for SKIP_WAL, we save the {@link Mutation} which * {@link Mutation#getDurability} is {@link Durability#SKIP_WAL} in miniBatchOp. */ @@ -3687,18 +3909,17 @@ public boolean visit(int index) throws IOException { return true; } - // the batch may contain multiple nonce keys (replay case). If so, write WALEdit for each. + // the batch may contain multiple nonce keys (replay case). If so, write WALEdit + // for each. // Given how nonce keys are originally written, these should be contiguous. - // They don't have to be, it will still work, just write more WALEdits than needed. + // They don't have to be, it will still work, just write more WALEdits than + // needed. long nonceGroup = getNonceGroup(index); long nonce = getNonce(index); - if ( - curWALEditForNonce == null + if (curWALEditForNonce == null || curWALEditForNonce.getFirst().getNonceGroup() != nonceGroup - || curWALEditForNonce.getFirst().getNonce() != nonce - ) { - curWALEditForNonce = - new Pair<>(new NonceKey(nonceGroup, nonce), createWALEdit(miniBatchOp)); + || curWALEditForNonce.getFirst().getNonce() != nonce) { + curWALEditForNonce = new Pair<>(new NonceKey(nonceGroup, nonce), createWALEdit(miniBatchOp)); walEdits.add(curWALEditForNonce); } WALEdit walEdit = curWALEditForNonce.getSecond(); @@ -3714,46 +3935,47 @@ public boolean visit(int index) throws IOException { } protected void addNonSkipWALMutationsToWALEdit( - final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, - List cellsFromCP, Map> familyCellMap) { + final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, + List cellsFromCP, Map> familyCellMap) { doAddCellsToWALEdit(walEdit, cellsFromCP, familyCellMap); } protected static void doAddCellsToWALEdit(WALEdit walEdit, List cellsFromCP, - Map> familyCellMap) { + Map> familyCellMap) { walEdit.add(cellsFromCP); walEdit.add(familyCellMap); } protected abstract void cacheSkipWALMutationForRegionReplication( - final MiniBatchOperationInProgress miniBatchOp, - List> walEdits, Map> familyCellMap); + final MiniBatchOperationInProgress miniBatchOp, + List> walEdits, Map> familyCellMap); /** - * This method completes mini-batch operations by calling postBatchMutate() CP hook (if + * This method completes mini-batch operations by calling postBatchMutate() CP + * hook (if * required) and completing mvcc. */ public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { if (writeEntry != null) { region.mvcc.completeAndWait(writeEntry); } } public void doPostOpCleanupForMiniBatch( - final MiniBatchOperationInProgress miniBatchOp, final WALEdit walEdit, - boolean success) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WALEdit walEdit, + boolean success) throws IOException { doFinishHotnessProtector(miniBatchOp); } - private void - doFinishHotnessProtector(final MiniBatchOperationInProgress miniBatchOp) { + private void doFinishHotnessProtector(final MiniBatchOperationInProgress miniBatchOp) { // check and return if the protector is not enabled if (!region.storeHotnessProtector.isEnable()) { return; } - // miniBatchOp is null, if and only if lockRowsAndBuildMiniBatch throwing exception. + // miniBatchOp is null, if and only if lockRowsAndBuildMiniBatch throwing + // exception. // This case was handled. if (miniBatchOp == null) { return; @@ -3769,7 +3991,8 @@ public void doPostOpCleanupForMiniBatch( break; default: // do nothing - // We won't start the protector for NOT_RUN/BAD_FAMILY/SANITY_CHECK_FAILURE and the + // We won't start the protector for NOT_RUN/BAD_FAMILY/SANITY_CHECK_FAILURE and + // the // STORE_TOO_BUSY case is handled in StoreHotnessProtector#start break; } @@ -3777,13 +4000,16 @@ public void doPostOpCleanupForMiniBatch( } /** - * Atomically apply the given map of family->edits to the memstore. This handles the consistency - * control on its own, but the caller should already have locked updatesLock.readLock(). This + * Atomically apply the given map of family->edits to the memstore. This handles + * the consistency + * control on its own, but the caller should already have locked + * updatesLock.readLock(). This * also does not check the families for validity. + * * @param familyMap Map of Cells by family */ protected void applyFamilyMapToMemStore(Map> familyMap, - MemStoreSizing memstoreAccounting) { + MemStoreSizing memstoreAccounting) { for (Map.Entry> e : familyMap.entrySet()) { byte[] family = e.getKey(); List cells = e.getValue(); @@ -3794,7 +4020,8 @@ protected void applyFamilyMapToMemStore(Map> familyMap, } /** - * Batch of mutation operations. Base class is shared with {@link ReplayBatchOperation} as most of + * Batch of mutation operations. Base class is shared with + * {@link ReplayBatchOperation} as most of * the logic is same. */ private static class MutationBatchOperation extends BatchOperation { @@ -3806,7 +4033,7 @@ private static class MutationBatchOperation extends BatchOperation { private boolean regionReplicateEnable; public MutationBatchOperation(final HRegion region, Mutation[] operations, boolean atomic, - long nonceGroup, long nonce) { + long nonceGroup, long nonce) { super(region, operations); this.atomic = atomic; this.nonceGroup = nonceGroup; @@ -3882,8 +4109,10 @@ public boolean visit(int index) throws IOException { } } if (isOperationPending(index)) { - // TODO: Currently validation is done with current time before acquiring locks and - // updates are done with different timestamps after acquiring locks. This behavior is + // TODO: Currently validation is done with current time before acquiring locks + // and + // updates are done with different timestamps after acquiring locks. This + // behavior is // inherited from the code prior to this change. Can this be changed? checkAndPrepareMutation(index, now); } @@ -3891,9 +4120,11 @@ public boolean visit(int index) throws IOException { } }); - // FIXME: we may update metrics twice! here for all operations bypassed by CP and later in + // FIXME: we may update metrics twice! here for all operations bypassed by CP + // and later in // normal processing. - // Update metrics in same way as it is done when we go the normal processing route (we now + // Update metrics in same way as it is done when we go the normal processing + // route (we now // update general metrics though a Coprocessor did the work). if (region.metricsRegion != null) { if (metrics[0] > 0) { @@ -3917,7 +4148,7 @@ public boolean visit(int index) throws IOException { @Override public void prepareMiniBatchOperations(MiniBatchOperationInProgress miniBatchOp, - long timestamp, final List acquiredRowLocks) throws IOException { + long timestamp, final List acquiredRowLocks) throws IOException { // For nonce operations canProceed = startNonceOperation(); @@ -3961,7 +4192,7 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi } if (result != null) { retCodeDetails[index] = new OperationStatus(OperationStatusCode.SUCCESS, - returnResults ? result : Result.EMPTY_RESULT); + returnResults ? result : Result.EMPTY_RESULT); return true; } @@ -4000,19 +4231,17 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi /** * Starts the nonce operation for a mutation, if needed. + * * @return whether to proceed this mutation. */ private boolean startNonceOperation() throws IOException { - if ( - region.rsServices == null || region.rsServices.getNonceManager() == null - || nonce == HConstants.NO_NONCE - ) { + if (region.rsServices == null || region.rsServices.getNonceManager() == null + || nonce == HConstants.NO_NONCE) { return true; } boolean canProceed; try { - canProceed = - region.rsServices.getNonceManager().startOperation(nonceGroup, nonce, region.rsServices); + canProceed = region.rsServices.getNonceManager().startOperation(nonceGroup, nonce, region.rsServices); } catch (InterruptedException ex) { throw new InterruptedIOException("Nonce start operation interrupted"); } @@ -4021,13 +4250,12 @@ private boolean startNonceOperation() throws IOException { /** * Ends nonce operation for a mutation, if needed. + * * @param success Whether the operation for this nonce has succeeded. */ private void endNonceOperation(boolean success) { - if ( - region.rsServices != null && region.rsServices.getNonceManager() != null - && nonce != HConstants.NO_NONCE - ) { + if (region.rsServices != null && region.rsServices.getNonceManager() != null + && nonce != HConstants.NO_NONCE) { region.rsServices.getNonceManager().endOperation(nonceGroup, nonce, success); } } @@ -4041,8 +4269,6 @@ private static Get toGet(final Mutation mutation) throws IOException { get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } if (mutation instanceof Increment) { - Cell cell = cellScanner.current(); - get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); // Increment Increment increment = (Increment) mutation; get.setTimeRange(increment.getTimeRange().getMin(), increment.getTimeRange().getMax()); @@ -4058,7 +4284,7 @@ private static Get toGet(final Mutation mutation) throws IOException { } private Map> reckonDeltas(Mutation mutation, List results, long now) - throws IOException { + throws IOException { assert mutation instanceof Increment || mutation instanceof Append; Map> ret = new TreeMap<>(Bytes.BYTES_COMPARATOR); // Process a Store/family at a time. @@ -4066,8 +4292,7 @@ private Map> reckonDeltas(Mutation mutation, List resul final byte[] columnFamilyName = entry.getKey(); List deltas = entry.getValue(); // Reckon for the Store what to apply to WAL and MemStore. - List toApply = - reckonDeltasByStore(region.stores.get(columnFamilyName), mutation, now, deltas, results); + List toApply = reckonDeltasByStore(region.stores.get(columnFamilyName), mutation, now, deltas, results); if (!toApply.isEmpty()) { for (Cell cell : toApply) { HStore store = region.getStore(cell); @@ -4075,7 +4300,7 @@ private Map> reckonDeltas(Mutation mutation, List resul region.checkFamily(CellUtil.cloneFamily(cell)); } else { ret.computeIfAbsent(store.getColumnFamilyDescriptor().getName(), - key -> new ArrayList<>()).add(cell); + key -> new ArrayList<>()).add(cell); } } } @@ -4084,24 +4309,32 @@ private Map> reckonDeltas(Mutation mutation, List resul } /** - * Reckon the Cells to apply to WAL, memstore, and to return to the Client in passed column - * family/Store. Does Get of current value and then adds passed in deltas for this Store + * Reckon the Cells to apply to WAL, memstore, and to return to the Client in + * passed column + * family/Store. Does Get of current value and then adds passed in deltas for + * this Store * returning the result. + * * @param mutation The encompassing Mutation object - * @param deltas Changes to apply to this Store; either increment amount or data to append - * @param results In here we accumulate all the Cells we are to return to the client. If null, + * @param deltas Changes to apply to this Store; either increment amount or + * data to append + * @param results In here we accumulate all the Cells we are to return to the + * client. If null, * client doesn't want results returned. - * @return Resulting Cells after deltas have been applied to current values. Side + * @return Resulting Cells after deltas have been applied to + * current values. Side * effect is our filling out of the results List. */ private List reckonDeltasByStore(HStore store, Mutation mutation, long now, - List deltas, List results) throws IOException { + List deltas, List results) throws IOException { assert mutation instanceof Increment || mutation instanceof Append; byte[] columnFamily = store.getColumnFamilyDescriptor().getName(); List> cellPairs = new ArrayList<>(deltas.size()); - // Sort the cells so that they match the order that they appear in the Get results. - // Otherwise, we won't be able to find the existing values if the cells are not specified + // Sort the cells so that they match the order that they appear in the Get + // results. + // Otherwise, we won't be able to find the existing values if the cells are not + // specified // in order by the client since cells are in an array list. deltas.sort(store.getComparator()); @@ -4126,66 +4359,67 @@ private List reckonDeltasByStore(HStore store, Mutation mutation, long now // because it will copy cells to heap. See HBASE-26036 List currentValues = new ArrayList<>(); scanner.next(currentValues); - // Iterate the input columns and update existing values if they were found, otherwise + // Iterate the input columns and update existing values if they were found, + // otherwise // add new column initialized to the delta amount int currentValuesIndex = 0; for (int i = 0; i < deltas.size(); i++) { Cell delta = deltas.get(i); Cell currentValue = null; - if ( - currentValuesIndex < currentValues.size() - && CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta) - ) { + if (currentValuesIndex < currentValues.size() + && CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta)) { currentValue = currentValues.get(currentValuesIndex); if (i < (deltas.size() - 1) && !CellUtil.matchingQualifier(delta, deltas.get(i + 1))) { currentValuesIndex++; } } - // Switch on whether this an increment or an append building the new Cell to apply. + // Switch on whether this an increment or an append building the new Cell to + // apply. Cell newCell; if (mutation instanceof Increment) { long deltaAmount = getLongValue(delta); - final long newValue = - currentValue == null ? deltaAmount : getLongValue(currentValue) + deltaAmount; + final long newValue = currentValue == null ? deltaAmount : getLongValue(currentValue) + deltaAmount; newCell = reckonDelta(delta, currentValue, columnFamily, now, mutation, - (oldCell) -> Bytes.toBytes(newValue)); + (oldCell) -> Bytes.toBytes(newValue)); } else { newCell = reckonDelta(delta, currentValue, columnFamily, now, mutation, - (oldCell) -> ByteBuffer - .wrap(new byte[delta.getValueLength() + oldCell.getValueLength()]) - .put(oldCell.getValueArray(), oldCell.getValueOffset(), oldCell.getValueLength()) - .put(delta.getValueArray(), delta.getValueOffset(), delta.getValueLength()) - .array()); + (oldCell) -> ByteBuffer + .wrap(new byte[delta.getValueLength() + oldCell.getValueLength()]) + .put(oldCell.getValueArray(), oldCell.getValueOffset(), oldCell.getValueLength()) + .put(delta.getValueArray(), delta.getValueOffset(), delta.getValueLength()) + .array()); } if (region.maxCellSize > 0) { int newCellSize = PrivateCellUtil.estimatedSerializedSizeOf(newCell); if (newCellSize > region.maxCellSize) { String msg = "Cell with size " + newCellSize + " exceeds limit of " - + region.maxCellSize + " bytes in region " + this; + + region.maxCellSize + " bytes in region " + this; LOG.debug(msg); throw new DoNotRetryIOException(msg); } } cellPairs.add(new Pair<>(currentValue, newCell)); - // Add to results to get returned to the Client. If null, cilent does not want results. + // Add to results to get returned to the Client. If null, cilent does not want + // results. if (results != null) { results.add(newCell); } } - // Give coprocessors a chance to update the new cells before apply to WAL or memstore + // Give coprocessors a chance to update the new cells before apply to WAL or + // memstore if (region.coprocessorHost != null) { // Here the operation must be increment or append. cellPairs = mutation instanceof Increment - ? region.coprocessorHost.postIncrementBeforeWAL(mutation, cellPairs) - : region.coprocessorHost.postAppendBeforeWAL(mutation, cellPairs); + ? region.coprocessorHost.postIncrementBeforeWAL(mutation, cellPairs) + : region.coprocessorHost.postAppendBeforeWAL(mutation, cellPairs); } } return cellPairs.stream().map(Pair::getSecond).collect(Collectors.toList()); } private static Cell reckonDelta(final Cell delta, final Cell currentCell, - final byte[] columnFamily, final long now, Mutation mutation, Function supplier) - throws IOException { + final byte[] columnFamily, final long now, Mutation mutation, Function supplier) + throws IOException { // Forward any tags found on the delta. List tags = TagUtil.carryForwardTags(delta); if (currentCell != null) { @@ -4193,13 +4427,13 @@ private static Cell reckonDelta(final Cell delta, final Cell currentCell, tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); byte[] newValue = supplier.apply(currentCell); return ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) - .setRow(mutation.getRow(), 0, mutation.getRow().length) - .setFamily(columnFamily, 0, columnFamily.length) - // copy the qualifier if the cell is located in shared memory. - .setQualifier(CellUtil.cloneQualifier(delta)) - .setTimestamp(Math.max(currentCell.getTimestamp() + 1, now)) - .setType(KeyValue.Type.Put.getCode()).setValue(newValue, 0, newValue.length) - .setTags(TagUtil.fromList(tags)).build(); + .setRow(mutation.getRow(), 0, mutation.getRow().length) + .setFamily(columnFamily, 0, columnFamily.length) + // copy the qualifier if the cell is located in shared memory. + .setQualifier(CellUtil.cloneQualifier(delta)) + .setTimestamp(Math.max(currentCell.getTimestamp() + 1, now)) + .setType(KeyValue.Type.Put.getCode()).setValue(newValue, 0, newValue.length) + .setTags(TagUtil.fromList(tags)).build(); } else { tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); PrivateCellUtil.updateLatestStamp(delta, now); @@ -4218,8 +4452,8 @@ private static long getLongValue(final Cell cell) throws DoNotRetryIOException { } @Override - public List> - buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) throws IOException { + public List> buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) + throws IOException { List> walEdits = super.buildWALEdits(miniBatchOp); // for MutationBatchOperation, more than one nonce is not allowed if (walEdits.size() > 1) { @@ -4229,28 +4463,30 @@ private static long getLongValue(final Cell cell) throws DoNotRetryIOException { } /** - * Here is for HBASE-26993,in order to make the new framework for region replication could work - * for SKIP_WAL, we save the {@link Mutation} which {@link Mutation#getDurability} is + * Here is for HBASE-26993,in order to make the new framework for region + * replication could work + * for SKIP_WAL, we save the {@link Mutation} which + * {@link Mutation#getDurability} is * {@link Durability#SKIP_WAL} in miniBatchOp. */ @Override protected void cacheSkipWALMutationForRegionReplication( - MiniBatchOperationInProgress miniBatchOp, - List> nonceKeyAndWALEdits, Map> familyCellMap) { + MiniBatchOperationInProgress miniBatchOp, + List> nonceKeyAndWALEdits, Map> familyCellMap) { if (!this.regionReplicateEnable) { return; } - WALEdit walEditForReplicateIfExistsSkipWAL = - miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); + WALEdit walEditForReplicateIfExistsSkipWAL = miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); /** - * When there is a SKIP_WAL {@link Mutation},we create a new {@link WALEdit} for replicating - * to region replica,first we fill the existing {@link WALEdit} to it and then add the + * When there is a SKIP_WAL {@link Mutation},we create a new {@link WALEdit} for + * replicating + * to region replica,first we fill the existing {@link WALEdit} to it and then + * add the * {@link Mutation} which is SKIP_WAL to it. */ if (walEditForReplicateIfExistsSkipWAL == null) { - walEditForReplicateIfExistsSkipWAL = - this.createWALEditForReplicateSkipWAL(miniBatchOp, nonceKeyAndWALEdits); + walEditForReplicateIfExistsSkipWAL = this.createWALEditForReplicateSkipWAL(miniBatchOp, nonceKeyAndWALEdits); miniBatchOp.setWalEditForReplicateIfExistsSkipWAL(walEditForReplicateIfExistsSkipWAL); } walEditForReplicateIfExistsSkipWAL.add(familyCellMap); @@ -4258,8 +4494,8 @@ protected void cacheSkipWALMutationForRegionReplication( } private WALEdit createWALEditForReplicateSkipWAL( - MiniBatchOperationInProgress miniBatchOp, - List> nonceKeyAndWALEdits) { + MiniBatchOperationInProgress miniBatchOp, + List> nonceKeyAndWALEdits) { if (nonceKeyAndWALEdits.isEmpty()) { return this.createWALEdit(miniBatchOp); } @@ -4271,20 +4507,22 @@ private WALEdit createWALEditForReplicateSkipWAL( @Override protected void addNonSkipWALMutationsToWALEdit( - final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, - List cellsFromCP, Map> familyCellMap) { + final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, + List cellsFromCP, Map> familyCellMap) { super.addNonSkipWALMutationsToWALEdit(miniBatchOp, walEdit, cellsFromCP, familyCellMap); - WALEdit walEditForReplicateIfExistsSkipWAL = - miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); + WALEdit walEditForReplicateIfExistsSkipWAL = miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); if (walEditForReplicateIfExistsSkipWAL == null) { return; } /** - * When walEditForReplicateIfExistsSkipWAL is not null,it means there exists SKIP_WAL + * When walEditForReplicateIfExistsSkipWAL is not null,it means there exists + * SKIP_WAL * {@link Mutation} and we create a new {@link WALEdit} in - * {@link MutationBatchOperation#cacheSkipWALMutationForReplicateRegionReplica} for - * replicating to region replica, so here we also add non SKIP_WAL{@link Mutation}s to + * {@link MutationBatchOperation#cacheSkipWALMutationForReplicateRegionReplica} + * for + * replicating to region replica, so here we also add non + * SKIP_WAL{@link Mutation}s to * walEditForReplicateIfExistsSkipWAL. */ doAddCellsToWALEdit(walEditForReplicateIfExistsSkipWAL, cellsFromCP, familyCellMap); @@ -4292,8 +4530,8 @@ protected void addNonSkipWALMutationsToWALEdit( @Override public WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, @Nullable WriteEntry writeEntry, - long now) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, @Nullable WriteEntry writeEntry, + long now) throws IOException { boolean newWriteEntry = false; if (writeEntry == null) { writeEntry = region.mvcc.begin(); @@ -4302,11 +4540,15 @@ public WriteEntry writeMiniBatchOperationsToMemStore( super.writeMiniBatchOperationsToMemStore(miniBatchOp, writeEntry.getWriteNumber()); if (newWriteEntry) { /** - * Here is for HBASE-26993 case 2,all {@link Mutation}s are {@link Durability#SKIP_WAL}. In - * order to make the new framework for region replication could work for SKIP_WAL,because - * there is no {@link RegionReplicationSink#add} attached in {@link HRegion#doWALAppend},so + * Here is for HBASE-26993 case 2,all {@link Mutation}s are + * {@link Durability#SKIP_WAL}. In + * order to make the new framework for region replication could work for + * SKIP_WAL,because + * there is no {@link RegionReplicationSink#add} attached in + * {@link HRegion#doWALAppend},so * here we get {@link WALEdit} from - * {@link MiniBatchOperationInProgress#getWalEditForReplicateIfExistsSkipWAL} and attach + * {@link MiniBatchOperationInProgress#getWalEditForReplicateIfExistsSkipWAL} + * and attach * {@link RegionReplicationSink#add} to the new mvcc writeEntry. */ attachRegionReplicationToMVCCEntry(miniBatchOp, writeEntry, now); @@ -4324,8 +4566,8 @@ private WALKeyImpl createWALKey(long now) { * {@link RegionReplicationSink#add} to the mvccWriteEntry. */ private void attachRegionReplicationToMVCCEntry( - final MiniBatchOperationInProgress miniBatchOp, WriteEntry mvccWriteEntry, long now) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, WriteEntry mvccWriteEntry, long now) + throws IOException { if (!this.regionReplicateEnable) { return; } @@ -4334,13 +4576,13 @@ private void attachRegionReplicationToMVCCEntry( final WALKeyImpl walKey = this.createWALKey(now); walKey.setWriteEntry(mvccWriteEntry); region.doAttachReplicateRegionReplicaAction(walKey, - miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(), mvccWriteEntry); + miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(), mvccWriteEntry); } @Override public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { // TODO: can it be done after completing mvcc? // calling the post CP hook for batch mutation if (region.coprocessorHost != null) { @@ -4351,14 +4593,14 @@ public void completeMiniBatchOperations( if (nonce != HConstants.NO_NONCE) { if (region.rsServices != null && region.rsServices.getNonceManager() != null) { region.rsServices.getNonceManager().addMvccToOperationContext(nonceGroup, nonce, - writeEntry.getWriteNumber()); + writeEntry.getWriteNumber()); } } } @Override public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress miniBatchOp, - final WALEdit walEdit, boolean success) throws IOException { + final WALEdit walEdit, boolean success) throws IOException { super.doPostOpCleanupForMiniBatch(miniBatchOp, walEdit, success); if (miniBatchOp != null) { @@ -4373,18 +4615,14 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m } else if (m instanceof Delete) { region.coprocessorHost.postDelete((Delete) m, walEdit); } else if (m instanceof Increment) { - Result result = - region.getCoprocessorHost().postIncrement((Increment) m, results[i], walEdit); + Result result = region.getCoprocessorHost().postIncrement((Increment) m, results[i], walEdit); if (result != results[i]) { - retCodeDetails[i] = - new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); + retCodeDetails[i] = new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); } } else if (m instanceof Append) { - Result result = - region.getCoprocessorHost().postAppend((Append) m, results[i], walEdit); + Result result = region.getCoprocessorHost().postAppend((Append) m, results[i], walEdit); if (result != results[i]) { - retCodeDetails[i] = - new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); + retCodeDetails[i] = new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); } } } @@ -4412,7 +4650,8 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m // if they were then keep them. If they were not then pass a null. // null will be treated as unknown. // Total time taken might be involving Puts, Deletes, Increments and Appends. - // Split the time for puts and deletes based on the total number of Puts, Deletes, + // Split the time for puts and deletes based on the total number of Puts, + // Deletes, // Increments and Appends. if (region.metricsRegion != null) { if (miniBatchOp.getNumOfPuts() > 0) { @@ -4437,17 +4676,20 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m if (region.coprocessorHost != null) { // call the coprocessor hook to do any finalization steps after the put is done region.coprocessorHost.postBatchMutateIndispensably( - miniBatchOp != null ? miniBatchOp : createMiniBatch(size(), 0), success); + miniBatchOp != null ? miniBatchOp : createMiniBatch(size(), 0), success); } } /** - * Runs prePut/preDelete/preIncrement/preAppend coprocessor hook for input mutation in a batch - * @param metrics Array of 2 ints. index 0: count of puts, index 1: count of deletes, index 2: + * Runs prePut/preDelete/preIncrement/preAppend coprocessor hook for input + * mutation in a batch + * + * @param metrics Array of 2 ints. index 0: count of puts, index 1: count of + * deletes, index 2: * count of increments and 3: count of appends */ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] metrics) - throws IOException { + throws IOException { Mutation m = getMutation(index); if (m instanceof Put) { if (region.coprocessorHost.prePut((Put) m, walEdit)) { @@ -4460,7 +4702,8 @@ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] m Delete curDel = (Delete) m; if (curDel.getFamilyCellMap().isEmpty()) { // handle deleting a row case - // TODO: prepareDelete() has been called twice, before and after preDelete() CP hook. + // TODO: prepareDelete() has been called twice, before and after preDelete() CP + // hook. // Can this be avoided? region.prepareDelete(curDel); } @@ -4499,14 +4742,15 @@ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] m // TODO Support Increment/Append operations private void checkAndMergeCPMutations(final MiniBatchOperationInProgress miniBatchOp, - final List acquiredRowLocks, final long timestamp) throws IOException { + final List acquiredRowLocks, final long timestamp) throws IOException { visitBatchOperations(true, nextIndexToProcess + miniBatchOp.size(), (int i) -> { // we pass (i - firstIndex) below since the call expects a relative index Mutation[] cpMutations = miniBatchOp.getOperationsFromCoprocessors(i - nextIndexToProcess); if (cpMutations == null) { return true; } - // Else Coprocessor added more Mutations corresponding to the Mutation at this index. + // Else Coprocessor added more Mutations corresponding to the Mutation at this + // index. Mutation mutation = getMutation(i); for (Mutation cpMutation : cpMutations) { this.checkAndPrepareMutation(cpMutation, timestamp); @@ -4514,14 +4758,17 @@ private void checkAndMergeCPMutations(final MiniBatchOperationInProgress> cpFamilyMap = cpMutation.getFamilyCellMap(); region.rewriteCellTags(cpFamilyMap, mutation); // will get added to the memStore later mergeFamilyMaps(familyCellMaps[i], cpFamilyMap); - // The durability of returned mutation is replaced by the corresponding mutation. + // The durability of returned mutation is replaced by the corresponding + // mutation. // If the corresponding mutation contains the SKIP_WAL, we shouldn't count the // cells of returned mutation. if (region.getEffectiveDurability(mutation.getDurability()) != Durability.SKIP_WAL) { @@ -4535,7 +4782,7 @@ private void checkAndMergeCPMutations(final MiniBatchOperationInProgress> familyMap, - Map> toBeMerged) { + Map> toBeMerged) { for (Map.Entry> entry : toBeMerged.entrySet()) { List cells = familyMap.get(entry.getKey()); if (cells == null) { @@ -4548,9 +4795,12 @@ private void mergeFamilyMaps(Map> familyMap, } /** - * Batch of mutations for replay. Base class is shared with {@link MutationBatchOperation} as most + * Batch of mutations for replay. Base class is shared with + * {@link MutationBatchOperation} as most * of the logic is same. - * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we will not use this operation to apply + * + * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we will not use this + * operation to apply * edits at secondary replica side. */ @Deprecated @@ -4559,7 +4809,7 @@ private static final class ReplayBatchOperation extends BatchOperation miniBatchOp, - long timestamp, final List acquiredRowLocks) throws IOException { + long timestamp, final List acquiredRowLocks) throws IOException { visitBatchOperations(true, miniBatchOp.getLastIndexExclusive(), (int index) -> { // update cell count for (List cells : getMutation(index).getFamilyCellMap().values()) { @@ -4652,70 +4903,71 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi @Override public WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, - long now) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, + long now) throws IOException { super.writeMiniBatchOperationsToMemStore(miniBatchOp, getOrigLogSeqNum()); return writeEntry; } @Override public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { super.completeMiniBatchOperations(miniBatchOp, writeEntry); region.mvcc.advanceTo(getOrigLogSeqNum()); } @Override protected void cacheSkipWALMutationForRegionReplication( - MiniBatchOperationInProgress miniBatchOp, List> walEdits, - Map> familyCellMap) { + MiniBatchOperationInProgress miniBatchOp, List> walEdits, + Map> familyCellMap) { // There is no action to do if current region is secondary replica } } public OperationStatus[] batchMutate(Mutation[] mutations, boolean atomic, long nonceGroup, - long nonce) throws IOException { + long nonce) throws IOException { // As it stands, this is used for 3 things - // * batchMutate with single mutation - put/delete/increment/append, separate or from + // * batchMutate with single mutation - put/delete/increment/append, separate or + // from // checkAndMutate. // * coprocessor calls (see ex. BulkDeleteEndpoint). - // So nonces are not really ever used by HBase. They could be by coprocs, and checkAnd... + // So nonces are not really ever used by HBase. They could be by coprocs, and + // checkAnd... return batchMutate(new MutationBatchOperation(this, mutations, atomic, nonceGroup, nonce)); } @Override public OperationStatus[] batchMutate(Mutation[] mutations) throws IOException { - // If the mutations has any Increment/Append operations, we need to do batchMutate atomically - boolean atomic = - Arrays.stream(mutations).anyMatch(m -> m instanceof Increment || m instanceof Append); + // If the mutations has any Increment/Append operations, we need to do + // batchMutate atomically + boolean atomic = Arrays.stream(mutations).anyMatch(m -> m instanceof Increment || m instanceof Append); return batchMutate(mutations, atomic); } OperationStatus[] batchMutate(Mutation[] mutations, boolean atomic) throws IOException { return TraceUtil.trace( - () -> batchMutate(mutations, atomic, HConstants.NO_NONCE, HConstants.NO_NONCE), - () -> createRegionSpan("Region.batchMutate")); + () -> batchMutate(mutations, atomic, HConstants.NO_NONCE, HConstants.NO_NONCE), + () -> createRegionSpan("Region.batchMutate")); } /** * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we use - * {@link #replayWALEntry(WALEntry, CellScanner)} for replaying edits at secondary + * {@link #replayWALEntry(WALEntry, CellScanner)} for replaying + * edits at secondary * replica side. */ @Deprecated OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) throws IOException { - if ( - !RegionReplicaUtil.isDefaultReplica(getRegionInfo()) - && replaySeqId < lastReplayedOpenRegionSeqId - ) { + if (!RegionReplicaUtil.isDefaultReplica(getRegionInfo()) + && replaySeqId < lastReplayedOpenRegionSeqId) { // if it is a secondary replica we should ignore these entries silently // since they are coming out of order if (LOG.isTraceEnabled()) { LOG.trace(getRegionInfo().getEncodedName() + " : " + "Skipping " + mutations.length - + " mutations with replaySeqId=" + replaySeqId - + " which is < than lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); + + " mutations with replaySeqId=" + replaySeqId + + " which is < than lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); for (MutationReplay mut : mutations) { LOG.trace(getRegionInfo().getEncodedName() + " : Skipping : " + mut.mutation); } @@ -4733,18 +4985,26 @@ OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) thro /** * Perform a batch of mutations. *

    - * Operations in a batch are stored with highest durability specified of for all operations in a + * Operations in a batch are stored with highest durability specified of for all + * operations in a * batch, except for {@link Durability#SKIP_WAL}. *

    - * This function is called from {@link #batchReplay(WALSplitUtil.MutationReplay[], long)} with - * {@link ReplayBatchOperation} instance and {@link #batchMutate(Mutation[])} with - * {@link MutationBatchOperation} instance as an argument. As the processing of replay batch and - * mutation batch is very similar, lot of code is shared by providing generic methods in base + * This function is called from + * {@link #batchReplay(WALSplitUtil.MutationReplay[], long)} with + * {@link ReplayBatchOperation} instance and {@link #batchMutate(Mutation[])} + * with + * {@link MutationBatchOperation} instance as an argument. As the processing of + * replay batch and + * mutation batch is very similar, lot of code is shared by providing generic + * methods in base * class {@link BatchOperation}. The logic for this method and - * {@link #doMiniBatchMutate(BatchOperation)} is implemented using methods in base class which are + * {@link #doMiniBatchMutate(BatchOperation)} is implemented using methods in + * base class which are * overridden by derived classes to implement special behavior. + * * @param batchOp contains the list of mutations - * @return an array of OperationStatus which internally contains the OperationStatusCode and the + * @return an array of OperationStatus which internally contains the + * OperationStatusCode and the * exceptionMessage if any. * @throws IOException if an IO problem is encountered */ @@ -4760,7 +5020,8 @@ private OperationStatus[] batchMutate(BatchOperation batchOp) throws IOExcept if (!initialized) { this.writeRequestsCount.add(batchOp.size()); - // validate and prepare batch for write, for MutationBatchOperation it also calls CP + // validate and prepare batch for write, for MutationBatchOperation it also + // calls CP // prePut()/preDelete()/preIncrement()/preAppend() hooks batchOp.checkAndPrepare(); initialized = true; @@ -4778,8 +5039,10 @@ private OperationStatus[] batchMutate(BatchOperation batchOp) throws IOExcept } /** - * Called to do a piece of the batch that came in to {@link #batchMutate(Mutation[])} In here we - * also handle replay of edits on region recover. Also gets change in size brought about by + * Called to do a piece of the batch that came in to + * {@link #batchMutate(Mutation[])} In here we + * also handle replay of edits on region recover. Also gets change in size + * brought about by * applying {@code batchOp}. */ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { @@ -4787,7 +5050,8 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { WALEdit walEdit = null; WriteEntry writeEntry = null; boolean locked = false; - // We try to set up a batch in the range [batchOp.nextIndexToProcess,lastIndexExclusive) + // We try to set up a batch in the range + // [batchOp.nextIndexToProcess,lastIndexExclusive) MiniBatchOperationInProgress miniBatchOp = null; /** Keep track of the locks we hold so we can release them in finally clause */ List acquiredRowLocks = Lists.newArrayListWithCapacity(batchOp.size()); @@ -4797,7 +5061,8 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { checkInterrupt(); try { - // STEP 1. Try to acquire as many locks as we can and build mini-batch of operations with + // STEP 1. Try to acquire as many locks as we can and build mini-batch of + // operations with // locked rows miniBatchOp = batchOp.lockRowsAndBuildMiniBatch(acquiredRowLocks); @@ -4810,19 +5075,23 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { } // Check for thread interrupt status in case we have been signaled from - // #interruptRegionOperation. Do it before we take the lock and disable interrupts for + // #interruptRegionOperation. Do it before we take the lock and disable + // interrupts for // the WAL append. checkInterrupt(); lock(this.updatesLock.readLock(), miniBatchOp.getReadyToWriteCount()); locked = true; - // From this point until memstore update this operation should not be interrupted. + // From this point until memstore update this operation should not be + // interrupted. disableInterrupts(); - // STEP 2. Update mini batch of all operations in progress with LATEST_TIMESTAMP timestamp + // STEP 2. Update mini batch of all operations in progress with LATEST_TIMESTAMP + // timestamp // We should record the timestamp only after we have acquired the rowLock, - // otherwise, newer puts/deletes/increment/append are not guaranteed to have a newer + // otherwise, newer puts/deletes/increment/append are not guaranteed to have a + // newer // timestamp long now = EnvironmentEdgeManager.currentTime(); @@ -4854,14 +5123,17 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { // NOTE: writeEntry can be null here writeEntry = batchOp.writeMiniBatchOperationsToMemStore(miniBatchOp, writeEntry, now); - // STEP 6. Complete MiniBatchOperations: If required calls postBatchMutate() CP hook and + // STEP 6. Complete MiniBatchOperations: If required calls postBatchMutate() CP + // hook and // complete mvcc for last writeEntry batchOp.completeMiniBatchOperations(miniBatchOp, writeEntry); writeEntry = null; success = true; } finally { - // Call complete rather than completeAndWait because we probably had error if walKey != null - if (writeEntry != null) mvcc.complete(writeEntry); + // Call complete rather than completeAndWait because we probably had error if + // walKey != null + if (writeEntry != null) + mvcc.complete(writeEntry); if (locked) { this.updatesLock.readLock().unlock(); @@ -4870,21 +5142,18 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { enableInterrupts(); - final int finalLastIndexExclusive = - miniBatchOp != null ? miniBatchOp.getLastIndexExclusive() : batchOp.size(); + final int finalLastIndexExclusive = miniBatchOp != null ? miniBatchOp.getLastIndexExclusive() : batchOp.size(); final boolean finalSuccess = success; batchOp.visitBatchOperations(true, finalLastIndexExclusive, (int i) -> { Mutation mutation = batchOp.getMutation(i); if (mutation instanceof Increment || mutation instanceof Append) { if (finalSuccess) { - batchOp.retCodeDetails[i] = - new OperationStatus(OperationStatusCode.SUCCESS, batchOp.results[i]); + batchOp.retCodeDetails[i] = new OperationStatus(OperationStatusCode.SUCCESS, batchOp.results[i]); } else { batchOp.retCodeDetails[i] = OperationStatus.FAILURE; } } else { - batchOp.retCodeDetails[i] = - finalSuccess ? OperationStatus.SUCCESS : OperationStatus.FAILURE; + batchOp.retCodeDetails[i] = finalSuccess ? OperationStatus.SUCCESS : OperationStatus.FAILURE; } return true; }); @@ -4896,7 +5165,8 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { } /** - * Returns effective durability from the passed durability and the table descriptor. + * Returns effective durability from the passed durability and the table + * descriptor. */ private Durability getEffectiveDurability(Durability d) { return d == Durability.USE_DEFAULT ? this.regionDurability : d; @@ -4905,18 +5175,18 @@ private Durability getEffectiveDurability(Durability d) { @Override @Deprecated public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator op, - ByteArrayComparable comparator, TimeRange timeRange, Mutation mutation) throws IOException { + ByteArrayComparable comparator, TimeRange timeRange, Mutation mutation) throws IOException { CheckAndMutate checkAndMutate; try { CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row) - .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange); + .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange); if (mutation instanceof Put) { checkAndMutate = builder.build((Put) mutation); } else if (mutation instanceof Delete) { checkAndMutate = builder.build((Delete) mutation); } else { throw new DoNotRetryIOException( - "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); + "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); } } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); @@ -4927,18 +5197,17 @@ public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, Compa @Override @Deprecated public boolean checkAndMutate(byte[] row, Filter filter, TimeRange timeRange, Mutation mutation) - throws IOException { + throws IOException { CheckAndMutate checkAndMutate; try { - CheckAndMutate.Builder builder = - CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange); + CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange); if (mutation instanceof Put) { checkAndMutate = builder.build((Put) mutation); } else if (mutation instanceof Delete) { checkAndMutate = builder.build((Delete) mutation); } else { throw new DoNotRetryIOException( - "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); + "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); } } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); @@ -4949,11 +5218,11 @@ public boolean checkAndMutate(byte[] row, Filter filter, TimeRange timeRange, Mu @Override @Deprecated public boolean checkAndRowMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator op, - ByteArrayComparable comparator, TimeRange timeRange, RowMutations rm) throws IOException { + ByteArrayComparable comparator, TimeRange timeRange, RowMutations rm) throws IOException { CheckAndMutate checkAndMutate; try { checkAndMutate = CheckAndMutate.newBuilder(row) - .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange).build(rm); + .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange).build(rm); } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); } @@ -4963,11 +5232,10 @@ public boolean checkAndRowMutate(byte[] row, byte[] family, byte[] qualifier, Co @Override @Deprecated public boolean checkAndRowMutate(byte[] row, Filter filter, TimeRange timeRange, RowMutations rm) - throws IOException { + throws IOException { CheckAndMutate checkAndMutate; try { - checkAndMutate = - CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange).build(rm); + checkAndMutate = CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange).build(rm); } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); } @@ -4980,13 +5248,13 @@ public CheckAndMutateResult checkAndMutate(CheckAndMutate checkAndMutate) throws } public CheckAndMutateResult checkAndMutate(CheckAndMutate checkAndMutate, long nonceGroup, - long nonce) throws IOException { + long nonce) throws IOException { return TraceUtil.trace(() -> checkAndMutateInternal(checkAndMutate, nonceGroup, nonce), - () -> createRegionSpan("Region.checkAndMutate")); + () -> createRegionSpan("Region.checkAndMutate")); } private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutate, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { byte[] row = checkAndMutate.getRow(); Filter filter = null; byte[] family = null; @@ -5038,15 +5306,15 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat RowLock rowLock = getRowLock(get.getRow(), false, null); try { if (this.getCoprocessorHost() != null) { - CheckAndMutateResult result = - getCoprocessorHost().preCheckAndMutateAfterRowLock(checkAndMutate); + CheckAndMutateResult result = getCoprocessorHost().preCheckAndMutateAfterRowLock(checkAndMutate); if (result != null) { return result; } } // NOTE: We used to wait here until mvcc caught up: mvcc.await(); - // Supposition is that now all changes are done under row locks, then when we go to read, + // Supposition is that now all changes are done under row locks, then when we go + // to read, // we'll get the latest on this row. boolean matches = false; long cellTs = 0; @@ -5061,8 +5329,7 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat cellTs = result.get(0).getTimestamp(); } } else { - boolean valueIsNull = - comparator.getValue() == null || comparator.getValue().length == 0; + boolean valueIsNull = comparator.getValue() == null || comparator.getValue().length == 0; if (result.isEmpty() && valueIsNull) { matches = op != CompareOperator.NOT_EQUAL; } else if (result.size() > 0 && valueIsNull) { @@ -5079,9 +5346,11 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat // If matches, perform the mutation or the rowMutations if (matches) { - // We have acquired the row lock already. If the system clock is NOT monotonically + // We have acquired the row lock already. If the system clock is NOT + // monotonically // non-decreasing (see HBASE-14070) we should make sure that the mutation has a - // larger timestamp than what was observed via Get. doBatchMutate already does this, but + // larger timestamp than what was observed via Get. doBatchMutate already does + // this, but // there is no way to pass the cellTs. See HBASE-14054. long now = EnvironmentEdgeManager.currentTime(); long ts = Math.max(now, cellTs); // ensure write is not eclipsed @@ -5090,7 +5359,8 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat if (mutation instanceof Put) { updateCellTimestamps(mutation.getFamilyCellMap().values(), byteTs); } - // And else 'delete' is not needed since it already does a second get, and sets the + // And else 'delete' is not needed since it already does a second get, and sets + // the // timestamp from get (see prepareDeleteTimestamps). } else { for (Mutation m : rowMutations.getMutations()) { @@ -5098,10 +5368,12 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat updateCellTimestamps(m.getFamilyCellMap().values(), byteTs); } } - // And else 'delete' is not needed since it already does a second get, and sets the + // And else 'delete' is not needed since it already does a second get, and sets + // the // timestamp from get (see prepareDeleteTimestamps). } - // All edits for the given row (across all column families) must happen atomically. + // All edits for the given row (across all column families) must happen + // atomically. Result r; if (mutation != null) { r = mutate(mutation, true, nonceGroup, nonce).getResult(); @@ -5122,12 +5394,10 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat } private void checkMutationType(final Mutation mutation) throws DoNotRetryIOException { - if ( - !(mutation instanceof Put) && !(mutation instanceof Delete) - && !(mutation instanceof Increment) && !(mutation instanceof Append) - ) { + if (!(mutation instanceof Put) && !(mutation instanceof Delete) + && !(mutation instanceof Increment) && !(mutation instanceof Append)) { throw new org.apache.hadoop.hbase.DoNotRetryIOException( - "Action must be Put or Delete or Increment or Delete"); + "Action must be Put or Delete or Increment or Delete"); } } @@ -5173,9 +5443,8 @@ private OperationStatus mutate(Mutation mutation, boolean atomic) throws IOExcep } private OperationStatus mutate(Mutation mutation, boolean atomic, long nonceGroup, long nonce) - throws IOException { - OperationStatus[] status = - this.batchMutate(new Mutation[] { mutation }, atomic, nonceGroup, nonce); + throws IOException { + OperationStatus[] status = this.batchMutate(new Mutation[] { mutation }, atomic, nonceGroup, nonce); if (status[0].getOperationStatusCode().equals(OperationStatusCode.SANITY_CHECK_FAILURE)) { throw new FailedSanityCheckException(status[0].getExceptionMsg()); } else if (status[0].getOperationStatusCode().equals(OperationStatusCode.BAD_FAMILY)) { @@ -5187,29 +5456,37 @@ private OperationStatus mutate(Mutation mutation, boolean atomic, long nonceGrou } /** - * Complete taking the snapshot on the region. Writes the region info and adds references to the - * working snapshot directory. TODO for api consistency, consider adding another version with no - * {@link ForeignExceptionSnare} arg. (In the future other cancellable HRegion methods could - * eventually add a {@link ForeignExceptionSnare}, or we could do something fancier). + * Complete taking the snapshot on the region. Writes the region info and adds + * references to the + * working snapshot directory. TODO for api consistency, consider adding another + * version with no + * {@link ForeignExceptionSnare} arg. (In the future other cancellable HRegion + * methods could + * eventually add a {@link ForeignExceptionSnare}, or we could do something + * fancier). + * * @param desc snapshot description object - * @param exnSnare ForeignExceptionSnare that captures external exceptions in case we need to bail - * out. This is allowed to be null and will just be ignored in that case. - * @throws IOException if there is an external or internal error causing the snapshot to fail + * @param exnSnare ForeignExceptionSnare that captures external exceptions in + * case we need to bail + * out. This is allowed to be null and will just be ignored in + * that case. + * @throws IOException if there is an external or internal error causing the + * snapshot to fail */ public void addRegionToSnapshot(SnapshotDescription desc, ForeignExceptionSnare exnSnare) - throws IOException { + throws IOException { Path rootDir = CommonFSUtils.getRootDir(conf); Path snapshotDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir, conf); - SnapshotManifest manifest = - SnapshotManifest.create(conf, getFilesystem(), snapshotDir, desc, exnSnare); + SnapshotManifest manifest = SnapshotManifest.create(conf, getFilesystem(), snapshotDir, desc, exnSnare); manifest.addRegion(this); } private void updateSequenceId(final Iterable> cellItr, final long sequenceId) - throws IOException { + throws IOException { for (List cells : cellItr) { - if (cells == null) return; + if (cells == null) + return; for (Cell cell : cells) { PrivateCellUtil.setSequenceId(cell, sequenceId); } @@ -5217,15 +5494,18 @@ private void updateSequenceId(final Iterable> cellItr, final long seq } /** - * Replace any cell timestamps set to {@link org.apache.hadoop.hbase.HConstants#LATEST_TIMESTAMP} + * Replace any cell timestamps set to + * {@link org.apache.hadoop.hbase.HConstants#LATEST_TIMESTAMP} * provided current timestamp. */ private static void updateCellTimestamps(final Iterable> cellItr, final byte[] now) - throws IOException { + throws IOException { for (List cells : cellItr) { - if (cells == null) continue; + if (cells == null) + continue; // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator + // objects assert cells instanceof RandomAccess; int listSize = cells.size(); for (int i = 0; i < listSize; i++) { @@ -5262,7 +5542,8 @@ private void rewriteCellTags(Map> familyMap, final Mutation m /** * Check if resources to support an update. *

    - * We throw RegionTooBusyException if above memstore limit and expect client to retry using some + * We throw RegionTooBusyException if above memstore limit and expect client to + * retry using some * kind of backoff */ private void checkResources() throws RegionTooBusyException { @@ -5275,18 +5556,18 @@ private void checkResources() throws RegionTooBusyException { if (mss.getHeapSize() + mss.getOffHeapSize() > this.blockingMemStoreSize) { blockedRequestsCount.increment(); requestFlush(); - // Don't print current limit because it will vary too much. The message is used as a key + // Don't print current limit because it will vary too much. The message is used + // as a key // over in RetriesExhaustedWithDetailsException processing. - final String regionName = - this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getEncodedName(); + final String regionName = this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getEncodedName(); final String serverName = this.getRegionServerServices() == null - ? "unknown" - : (this.getRegionServerServices().getServerName() == null ? "unknown" - : this.getRegionServerServices().getServerName().toString()); + : (this.getRegionServerServices().getServerName() == null + ? "unknown" + : this.getRegionServerServices().getServerName().toString()); RegionTooBusyException rtbe = new RegionTooBusyException("Over memstore limit=" - + org.apache.hadoop.hbase.procedure2.util.StringUtils.humanSize(this.blockingMemStoreSize) - + ", regionName=" + regionName + ", server=" + serverName); + + org.apache.hadoop.hbase.procedure2.util.StringUtils.humanSize(this.blockingMemStoreSize) + + ", regionName=" + regionName + ", server=" + serverName); LOG.warn("Region is too busy due to exceeding memstore size limit.", rtbe); throw rtbe; } @@ -5304,7 +5585,7 @@ private void checkReadOnly() throws IOException { private void checkReadsEnabled() throws IOException { if (!this.writestate.readsEnabled) { throw new IOException(getRegionInfo().getEncodedName() - + ": The region's reads are disabled. Cannot serve the request"); + + ": The region's reads are disabled. Cannot serve the request"); } } @@ -5316,13 +5597,16 @@ public void setReadsEnabled(boolean readsEnabled) { } /** - * @param delta If we are doing delta changes -- e.g. increment/append -- then this flag will be - * set; when set we will run operations that make sense in the increment/append + * @param delta If we are doing delta changes -- e.g. increment/append -- then + * this flag will be + * set; when set we will run operations that make sense in the + * increment/append * scenario but that do not make sense otherwise. */ private void applyToMemStore(HStore store, List cells, boolean delta, - MemStoreSizing memstoreAccounting) { - // Any change in how we update Store/MemStore needs to also be done in other applyToMemStore!!!! + MemStoreSizing memstoreAccounting) { + // Any change in how we update Store/MemStore needs to also be done in other + // applyToMemStore!!!! boolean upsert = delta && store.getColumnFamilyDescriptor().getMaxVersions() == 1; if (upsert) { store.upsert(cells, getSmallestReadPoint(), memstoreAccounting); @@ -5332,45 +5616,45 @@ private void applyToMemStore(HStore store, List cells, boolean delta, } private void checkFamilies(Collection families, Durability durability) - throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { + throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { for (byte[] family : families) { checkFamily(family, durability); } } private void checkFamily(final byte[] family, Durability durability) - throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { + throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { checkFamily(family); - if ( - durability.equals(Durability.SKIP_WAL) - && htableDescriptor.getColumnFamily(family).getScope() != HConstants.REPLICATION_SCOPE_LOCAL - ) { + if (durability.equals(Durability.SKIP_WAL) + && htableDescriptor.getColumnFamily(family).getScope() != HConstants.REPLICATION_SCOPE_LOCAL) { throw new InvalidMutationDurabilityException( - "Mutation's durability is SKIP_WAL but table's column family " + Bytes.toString(family) - + " need replication"); + "Mutation's durability is SKIP_WAL but table's column family " + Bytes.toString(family) + + " need replication"); } } private void checkFamily(final byte[] family) throws NoSuchColumnFamilyException { if (!this.htableDescriptor.hasColumnFamily(family)) { throw new NoSuchColumnFamilyException("Column family " + Bytes.toString(family) - + " does not exist in region " + this + " in table " + this.htableDescriptor); + + " does not exist in region " + this + " in table " + this.htableDescriptor); } } /** * Check the collection of families for valid timestamps + * * @param now current timestamp */ public void checkTimestamps(final Map> familyMap, long now) - throws FailedSanityCheckException { + throws FailedSanityCheckException { if (timestampSlop == HConstants.LATEST_TIMESTAMP) { return; } long maxTs = now + timestampSlop; for (List kvs : familyMap.values()) { // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator + // objects assert kvs instanceof RandomAccess; int listSize = kvs.size(); for (int i = 0; i < listSize; i++) { @@ -5379,7 +5663,7 @@ public void checkTimestamps(final Map> familyMap, long now) long ts = cell.getTimestamp(); if (ts != HConstants.LATEST_TIMESTAMP && ts > maxTs) { throw new FailedSanityCheckException( - "Timestamp for KV out of range " + cell + " (too.new=" + timestampSlop + ")"); + "Timestamp for KV out of range " + cell + " (too.new=" + timestampSlop + ")"); } } } @@ -5403,34 +5687,51 @@ private void deleteRecoveredEdits(FileSystem fs, Iterable files) throws IO } /** - * Read the edits put under this region by wal splitting process. Put the recovered edits back up + * Read the edits put under this region by wal splitting process. Put the + * recovered edits back up * into this region. *

    - * We can ignore any wal message that has a sequence ID that's equal to or lower than minSeqId. + * We can ignore any wal message that has a sequence ID that's equal to or lower + * than minSeqId. * (Because we know such messages are already reflected in the HFiles.) *

    - * While this is running we are putting pressure on memory yet we are outside of our usual - * accounting because we are not yet an onlined region (this stuff is being run as part of Region - * initialization). This means that if we're up against global memory limits, we'll not be flagged - * to flush because we are not online. We can't be flushed by usual mechanisms anyways; we're not - * yet online so our relative sequenceids are not yet aligned with WAL sequenceids -- not till we + * While this is running we are putting pressure on memory yet we are outside of + * our usual + * accounting because we are not yet an onlined region (this stuff is being run + * as part of Region + * initialization). This means that if we're up against global memory limits, + * we'll not be flagged + * to flush because we are not online. We can't be flushed by usual mechanisms + * anyways; we're not + * yet online so our relative sequenceids are not yet aligned with WAL + * sequenceids -- not till we * come up online, post processing of split edits. *

    - * But to help relieve memory pressure, at least manage our own heap size flushing if are in - * excess of per-region limits. Flushing, though, we have to be careful and avoid using the - * regionserver/wal sequenceid. Its running on a different line to whats going on in here in this - * region context so if we crashed replaying these edits, but in the midst had a flush that used - * the regionserver wal with a sequenceid in excess of whats going on in here in this region and - * with its split editlogs, then we could miss edits the next time we go to recover. So, we have - * to flush inline, using seqids that make sense in a this single region context only -- until we + * But to help relieve memory pressure, at least manage our own heap size + * flushing if are in + * excess of per-region limits. Flushing, though, we have to be careful and + * avoid using the + * regionserver/wal sequenceid. Its running on a different line to whats going + * on in here in this + * region context so if we crashed replaying these edits, but in the midst had a + * flush that used + * the regionserver wal with a sequenceid in excess of whats going on in here in + * this region and + * with its split editlogs, then we could miss edits the next time we go to + * recover. So, we have + * to flush inline, using seqids that make sense in a this single region context + * only -- until we * online. - * @param maxSeqIdInStores Any edit found in split editlogs needs to be in excess of the maxSeqId + * + * @param maxSeqIdInStores Any edit found in split editlogs needs to be in + * excess of the maxSeqId * for the store to be applied, else its skipped. - * @return the sequence id of the last edit added to this region out of the recovered edits log or + * @return the sequence id of the last edit added to this region out of the + * recovered edits log or * minSeqId if nothing added from editlogs. */ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, - final CancelableProgressable reporter, final MonitoredTask status) throws IOException { + final CancelableProgressable reporter, final MonitoredTask status) throws IOException { long minSeqIdForTheRegion = -1; for (Long maxSeqIdInStore : maxSeqIdInStores.values()) { if (maxSeqIdInStore < minSeqIdForTheRegion || minSeqIdForTheRegion == -1) { @@ -5443,38 +5744,39 @@ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, FileSystem walFS = getWalFileSystem(); FileSystem rootFS = getFilesystem(); Path wrongRegionWALDir = CommonFSUtils.getWrongWALRegionDir(conf, getRegionInfo().getTable(), - getRegionInfo().getEncodedName()); + getRegionInfo().getEncodedName()); Path regionWALDir = getWALRegionDir(); - Path regionDir = - FSUtils.getRegionDirFromRootDir(CommonFSUtils.getRootDir(conf), getRegionInfo()); + Path regionDir = FSUtils.getRegionDirFromRootDir(CommonFSUtils.getRootDir(conf), getRegionInfo()); // We made a mistake in HBASE-20734 so we need to do this dirty hack... - NavigableSet filesUnderWrongRegionWALDir = - WALSplitUtil.getSplitEditFilesSorted(walFS, wrongRegionWALDir); + NavigableSet filesUnderWrongRegionWALDir = WALSplitUtil.getSplitEditFilesSorted(walFS, wrongRegionWALDir); seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, - filesUnderWrongRegionWALDir, reporter, regionDir)); - // This is to ensure backwards compatability with HBASE-20723 where recovered edits can appear + filesUnderWrongRegionWALDir, reporter, regionDir)); + // This is to ensure backwards compatability with HBASE-20723 where recovered + // edits can appear // under the root dir even if walDir is set. NavigableSet filesUnderRootDir = Collections.emptyNavigableSet(); if (!regionWALDir.equals(regionDir)) { filesUnderRootDir = WALSplitUtil.getSplitEditFilesSorted(rootFS, regionDir); seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, rootFS, - filesUnderRootDir, reporter, regionDir)); + filesUnderRootDir, reporter, regionDir)); } NavigableSet files = WALSplitUtil.getSplitEditFilesSorted(walFS, regionWALDir); seqId = Math.max(seqId, - replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, files, reporter, regionWALDir)); + replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, files, reporter, regionWALDir)); if (seqId > minSeqIdForTheRegion) { // Then we added some edits to memory. Flush and cleanup split edit files. internalFlushcache(null, seqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } // Now delete the content of recovered edits. We're done w/ them. if (files.size() > 0 && this.conf.getBoolean("hbase.region.archive.recovered.edits", false)) { // For debugging data loss issues! - // If this flag is set, make use of the hfile archiving by making recovered.edits a fake - // column family. Have to fake out file type too by casting our recovered.edits as + // If this flag is set, make use of the hfile archiving by making + // recovered.edits a fake + // column family. Have to fake out file type too by casting our recovered.edits + // as // storefiles String fakeFamilyName = WALSplitUtil.getRegionDirRecoveredEditsDir(regionWALDir).getName(); Set fakeStoreFiles = new HashSet<>(files.size()); @@ -5491,37 +5793,37 @@ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, FileSystem fs = recoveredEditsDir.getFileSystem(conf); FileStatus[] files = fs.listStatus(recoveredEditsDir); LOG.debug("Found {} recovered edits file(s) under {}", files == null ? 0 : files.length, - recoveredEditsDir); + recoveredEditsDir); if (files != null) { for (FileStatus file : files) { - // it is safe to trust the zero-length in this case because we've been through rename and + // it is safe to trust the zero-length in this case because we've been through + // rename and // lease recovery in the above. if (isZeroLengthThenDelete(fs, file, file.getPath())) { continue; } - seqId = - Math.max(seqId, replayRecoveredEdits(file.getPath(), maxSeqIdInStores, reporter, fs)); + seqId = Math.max(seqId, replayRecoveredEdits(file.getPath(), maxSeqIdInStores, reporter, fs)); } } if (seqId > minSeqIdForTheRegion) { // Then we added some edits to memory. Flush and cleanup split edit files. internalFlushcache(null, seqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } deleteRecoveredEdits(fs, - Stream.of(files).map(FileStatus::getPath).collect(Collectors.toList())); + Stream.of(files).map(FileStatus::getPath).collect(Collectors.toList())); } return seqId; } private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem fs, - final NavigableSet files, final CancelableProgressable reporter, final Path regionDir) - throws IOException { + final NavigableSet files, final CancelableProgressable reporter, final Path regionDir) + throws IOException { long seqid = minSeqIdForTheRegion; if (LOG.isDebugEnabled()) { LOG.debug("Found " + (files == null ? 0 : files.size()) + " recovered edits file(s) under " - + regionDir); + + regionDir); } if (files == null || files.isEmpty()) { @@ -5543,8 +5845,8 @@ private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem if (maxSeqId <= minSeqIdForTheRegion) { if (LOG.isDebugEnabled()) { String msg = "Maximum sequenceid for this wal is " + maxSeqId - + " and minimum sequenceid for the region " + this + " is " + minSeqIdForTheRegion - + ", skipped the whole file, path=" + edits; + + " and minimum sequenceid for the region " + this + " is " + minSeqIdForTheRegion + + ", skipped the whole file, path=" + edits; LOG.debug(msg); } continue; @@ -5563,15 +5865,15 @@ private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem private void handleException(FileSystem fs, Path edits, IOException e) throws IOException { boolean skipErrors = conf.getBoolean(HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS, - conf.getBoolean("hbase.skip.errors", HConstants.DEFAULT_HREGION_EDITS_REPLAY_SKIP_ERRORS)); + conf.getBoolean("hbase.skip.errors", HConstants.DEFAULT_HREGION_EDITS_REPLAY_SKIP_ERRORS)); if (conf.get("hbase.skip.errors") != null) { LOG.warn("The property 'hbase.skip.errors' has been deprecated. Please use " - + HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + " instead."); + + HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + " instead."); } if (skipErrors) { Path p = WALSplitUtil.moveAsideBadEditsFile(fs, edits); LOG.error(HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + "=true so continuing. Renamed " - + edits + " as " + p, e); + + edits + " as " + p, e); } else { throw e; } @@ -5579,13 +5881,15 @@ private void handleException(FileSystem fs, Path edits, IOException e) throws IO /** * @param edits File of recovered edits. - * @param maxSeqIdInStores Maximum sequenceid found in each store. Edits in wal must be larger + * @param maxSeqIdInStores Maximum sequenceid found in each store. Edits in wal + * must be larger * than this to be replayed for each store. - * @return the sequence id of the last edit added to this region out of the recovered edits log or + * @return the sequence id of the last edit added to this region out of the + * recovered edits log or * minSeqId if nothing added from editlogs. */ private long replayRecoveredEdits(final Path edits, Map maxSeqIdInStores, - final CancelableProgressable reporter, FileSystem fs) throws IOException { + final CancelableProgressable reporter, FileSystem fs) throws IOException { String msg = "Replaying edits from " + edits; LOG.info(msg); MonitoredTask status = TaskMonitor.get().createStatus(msg); @@ -5630,7 +5934,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn long cur = EnvironmentEdgeManager.currentTime(); if (lastReport + period <= cur) { status.setStatus( - "Replaying edits..." + " skipped=" + skippedEdits + " edits=" + editsCount); + "Replaying edits..." + " skipped=" + skippedEdits + " edits=" + editsCount); // Timeout reached if (!reporter.progress()) { msg = "Progressable reporter failed, stopping replay for region " + this; @@ -5648,21 +5952,19 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn firstSeqIdInLog = key.getSequenceId(); } if (currentEditSeqId > key.getSequenceId()) { - // when this condition is true, it means we have a serious defect because we need to + // when this condition is true, it means we have a serious defect because we + // need to // maintain increasing SeqId for WAL edits per region LOG.error(getRegionInfo().getEncodedName() + " : " + "Found decreasing SeqId. PreId=" - + currentEditSeqId + " key=" + key + "; edit=" + val); + + currentEditSeqId + " key=" + key + "; edit=" + val); } else { currentEditSeqId = key.getSequenceId(); } - currentReplaySeqId = - (key.getOrigLogSeqNum() > 0) ? key.getOrigLogSeqNum() : currentEditSeqId; + currentReplaySeqId = (key.getOrigLogSeqNum() > 0) ? key.getOrigLogSeqNum() : currentEditSeqId; boolean checkRowWithinBoundary = false; // Check this edit is for this region. - if ( - !Bytes.equals(key.getEncodedRegionName(), this.getRegionInfo().getEncodedNameAsBytes()) - ) { + if (!Bytes.equals(key.getEncodedRegionName(), this.getRegionInfo().getEncodedNameAsBytes())) { checkRowWithinBoundary = true; } @@ -5685,10 +5987,8 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn continue; } // Figure which store the edit is meant for. - if ( - store == null - || !CellUtil.matchingFamily(cell, store.getColumnFamilyDescriptor().getName()) - ) { + if (store == null + || !CellUtil.matchingFamily(cell, store.getColumnFamilyDescriptor().getName())) { store = getStore(cell); } if (store == null) { @@ -5698,19 +5998,14 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn skippedEdits++; continue; } - if ( - checkRowWithinBoundary && !rowIsInRange(this.getRegionInfo(), cell.getRowArray(), - cell.getRowOffset(), cell.getRowLength()) - ) { + if (checkRowWithinBoundary && !rowIsInRange(this.getRegionInfo(), cell.getRowArray(), + cell.getRowOffset(), cell.getRowLength())) { LOG.warn("Row of {} is not within region boundary for region {}", cell, this); skippedEdits++; continue; } // Now, figure if we should skip this edit. - if ( - key.getSequenceId() - <= maxSeqIdInStores.get(store.getColumnFamilyDescriptor().getName()) - ) { + if (key.getSequenceId() <= maxSeqIdInStores.get(store.getColumnFamilyDescriptor().getName())) { skippedEdits++; continue; } @@ -5724,7 +6019,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn flush = isFlushSize(this.memStoreSizing.getMemStoreSize()); if (flush) { internalFlushcache(null, currentEditSeqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } } @@ -5735,21 +6030,20 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn if (!conf.getBoolean(RECOVERED_EDITS_IGNORE_EOF, false)) { Path p = WALSplitUtil.moveAsideBadEditsFile(walFS, edits); msg = "EnLongAddered EOF. Most likely due to Master failure during " - + "wal splitting, so we have this data in another edit. Continuing, but renaming " - + edits + " as " + p + " for region " + this; + + "wal splitting, so we have this data in another edit. Continuing, but renaming " + + edits + " as " + p + " for region " + this; LOG.warn(msg, eof); status.abort(msg); } else { LOG.warn("EOF while replaying recover edits and config '{}' is true so " - + "we will ignore it and continue", RECOVERED_EDITS_IGNORE_EOF, eof); + + "we will ignore it and continue", RECOVERED_EDITS_IGNORE_EOF, eof); } } catch (IOException ioe) { // If the IOE resulted from bad file format, // then this problem is idempotent and retrying won't help if (ioe.getCause() instanceof ParseException) { Path p = WALSplitUtil.moveAsideBadEditsFile(walFS, edits); - msg = - "File corruption enLongAddered! " + "Continuing, but renaming " + edits + " as " + p; + msg = "File corruption enLongAddered! " + "Continuing, but renaming " + edits + " as " + p; LOG.warn(msg, ioe); status.setStatus(msg); } else { @@ -5763,7 +6057,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn reporter.progress(); } msg = "Applied " + editsCount + ", skipped " + skippedEdits + ", firstSequenceIdInLog=" - + firstSeqIdInLog + ", maxSequenceIdInLog=" + currentEditSeqId + ", path=" + edits; + + firstSeqIdInLog + ", maxSequenceIdInLog=" + currentEditSeqId + ", path=" + edits; status.markComplete(msg); LOG.debug(msg); return currentEditSeqId; @@ -5773,14 +6067,16 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn } /** - * Call to complete a compaction. Its for the case where we find in the WAL a compaction that was - * not finished. We could find one recovering a WAL after a regionserver crash. See HBASE-2331. + * Call to complete a compaction. Its for the case where we find in the WAL a + * compaction that was + * not finished. We could find one recovering a WAL after a regionserver crash. + * See HBASE-2331. */ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickCompactionFiles, - boolean removeFiles, long replaySeqId) throws IOException { + boolean removeFiles, long replaySeqId) throws IOException { try { checkTargetRegion(compaction.getEncodedRegionName().toByteArray(), - "Compaction marker from WAL ", compaction); + "Compaction marker from WAL ", compaction); } catch (WrongRegionException wre) { if (RegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { // skip the compaction marker since it is not for this region @@ -5792,16 +6088,16 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp synchronized (writestate) { if (replaySeqId < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying compaction event :" - + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " - + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " + + lastReplayedOpenRegionSeqId); return; } if (replaySeqId < lastReplayedCompactionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying compaction event :" - + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedCompactionSeqId of " - + lastReplayedCompactionSeqId); + + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedCompactionSeqId of " + + lastReplayedCompactionSeqId); return; } else { lastReplayedCompactionSeqId = replaySeqId; @@ -5809,8 +6105,8 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying compaction marker " - + TextFormat.shortDebugString(compaction) + " with seqId=" + replaySeqId - + " and lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(compaction) + " with seqId=" + replaySeqId + + " and lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); } startRegionOperation(Operation.REPLAY_EVENT); @@ -5818,17 +6114,17 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp HStore store = this.getStore(compaction.getFamilyName().toByteArray()); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Found Compaction WAL edit for deleted family:" - + Bytes.toString(compaction.getFamilyName().toByteArray())); + + "Found Compaction WAL edit for deleted family:" + + Bytes.toString(compaction.getFamilyName().toByteArray())); return; } store.replayCompactionMarker(compaction, pickCompactionFiles, removeFiles); logRegionFiles(); } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "At least one of the store files in compaction: " - + TextFormat.shortDebugString(compaction) - + " doesn't exist any more. Skip loading the file(s)", ex); + + "At least one of the store files in compaction: " + + TextFormat.shortDebugString(compaction) + + " doesn't exist any more. Skip loading the file(s)", ex); } finally { closeRegionOperation(Operation.REPLAY_EVENT); } @@ -5836,7 +6132,8 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated @@ -5849,7 +6146,7 @@ void replayWALFlushMarker(FlushDescriptor flush, long replaySeqId) throws IOExce if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying flush marker " - + TextFormat.shortDebugString(flush)); + + TextFormat.shortDebugString(flush)); } startRegionOperation(Operation.REPLAY_EVENT); // use region close lock to guard against close @@ -5870,8 +6167,8 @@ void replayWALFlushMarker(FlushDescriptor flush, long replaySeqId) throws IOExce break; default: LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush event with unknown action, ignoring. " - + TextFormat.shortDebugString(flush)); + + "Received a flush event with unknown action, ignoring. " + + TextFormat.shortDebugString(flush)); break; } @@ -5888,8 +6185,8 @@ private Collection getStoresToFlush(FlushDescriptor flushDesc) { HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush start marker from primary, but the family is not found. Ignoring" - + " StoreFlushDescriptor:" + TextFormat.shortDebugString(storeFlush)); + + "Received a flush start marker from primary, but the family is not found. Ignoring" + + " StoreFlushDescriptor:" + TextFormat.shortDebugString(storeFlush)); continue; } storesToFlush.add(store); @@ -5898,10 +6195,14 @@ private Collection getStoresToFlush(FlushDescriptor flushDesc) { } /** - * Replay the flush marker from primary region by creating a corresponding snapshot of the store - * memstores, only if the memstores do not have a higher seqId from an earlier wal edit (because + * Replay the flush marker from primary region by creating a corresponding + * snapshot of the store + * memstores, only if the memstores do not have a higher seqId from an earlier + * wal edit (because * the events may be coming out of order). - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated @@ -5918,9 +6219,9 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc try { if (flush.getFlushSequenceNumber() < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return null; } if (numMutationsWithoutWAL.sum() > 0) { @@ -5929,12 +6230,14 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc } if (!writestate.flushing) { - // we do not have an active snapshot and corresponding this.prepareResult. This means + // we do not have an active snapshot and corresponding this.prepareResult. This + // means // we can just snapshot our memstores and continue as normal. - // invoke prepareFlushCache. Send null as wal since we do not want the flush events in wal + // invoke prepareFlushCache. Send null as wal since we do not want the flush + // events in wal PrepareFlushResult prepareResult = internalPrepareFlushCache(null, flushSeqId, - storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); + storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); if (prepareResult.result == null) { // save the PrepareFlushResult so that we can use it later from commit flush this.writestate.flushing = true; @@ -5942,20 +6245,18 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc status.markComplete("Flush prepare successful"); if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + " Prepared flush with seqId:" - + flush.getFlushSequenceNumber()); + + flush.getFlushSequenceNumber()); } } else { - // special case empty memstore. We will still save the flush result in this case, since + // special case empty memstore. We will still save the flush result in this + // case, since // our memstore ie empty, but the primary is still flushing - if ( - prepareResult.getResult().getResult() - == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY - ) { + if (prepareResult.getResult().getResult() == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY) { this.writestate.flushing = true; this.prepareFlushResult = prepareResult; if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + " Prepared empty flush with seqId:" + flush.getFlushSequenceNumber()); + + " Prepared empty flush with seqId:" + flush.getFlushSequenceNumber()); } } status.abort("Flush prepare failed with " + prepareResult.result); @@ -5967,34 +6268,42 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc if (flush.getFlushSequenceNumber() == this.prepareFlushResult.flushOpSeqId) { // They define the same flush. Log and continue. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with the same seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); + + "Received a flush prepare marker with the same seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); // ignore } else if (flush.getFlushSequenceNumber() < this.prepareFlushResult.flushOpSeqId) { - // We received a flush with a smaller seqNum than what we have prepared. We can only + // We received a flush with a smaller seqNum than what we have prepared. We can + // only // ignore this prepare flush request. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with a smaller seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); + + "Received a flush prepare marker with a smaller seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); // ignore } else { // We received a flush with a larger seqNum than what we have prepared LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with a larger seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); - // We do not have multiple active snapshots in the memstore or a way to merge current + + "Received a flush prepare marker with a larger seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); + // We do not have multiple active snapshots in the memstore or a way to merge + // current // memstore snapshot with the contents and resnapshot for now. We cannot take // another snapshot and drop the previous one because that will cause temporary - // data loss in the secondary. So we ignore this for now, deferring the resolution - // to happen when we see the corresponding flush commit marker. If we have a memstore - // snapshot with x, and later received another prepare snapshot with y (where x < y), - // when we see flush commit for y, we will drop snapshot for x, and can also drop all - // the memstore edits if everything in memstore is < y. This is the usual case for + // data loss in the secondary. So we ignore this for now, deferring the + // resolution + // to happen when we see the corresponding flush commit marker. If we have a + // memstore + // snapshot with x, and later received another prepare snapshot with y (where x + // < y), + // when we see flush commit for y, we will drop snapshot for x, and can also + // drop all + // the memstore edits if everything in memstore is < y. This is the usual case + // for // RS crash + recovery where we might see consequtive prepare flush wal markers. - // Otherwise, this will cause more memory to be used in secondary replica until a + // Otherwise, this will cause more memory to be used in secondary replica until + // a // further prapare + commit flush is seen and replayed. } } @@ -6007,26 +6316,29 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", - justification = "Intentional; post memstore flush") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; post memstore flush") void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { MonitoredTask status = TaskMonitor.get().createStatus("Committing flush " + this); - // check whether we have the memstore snapshot with the corresponding seqId. Replay to - // secondary region replicas are in order, except for when the region moves or then the - // region server crashes. In those cases, we may receive replay requests out of order from + // check whether we have the memstore snapshot with the corresponding seqId. + // Replay to + // secondary region replicas are in order, except for when the region moves or + // then the + // region server crashes. In those cases, we may receive replay requests out of + // order from // the original seqIds. synchronized (writestate) { try { if (flush.getFlushSequenceNumber() < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return; } @@ -6035,8 +6347,8 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { if (flush.getFlushSequenceNumber() == prepareFlushResult.flushOpSeqId) { if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with seqId:" + flush.getFlushSequenceNumber() - + " and a previous prepared snapshot was found"); + + "Received a flush commit marker with seqId:" + flush.getFlushSequenceNumber() + + " and a previous prepared snapshot was found"); } // This is the regular case where we received commit flush after prepare flush // corresponding to the same seqId. @@ -6047,30 +6359,35 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { this.prepareFlushResult = null; writestate.flushing = false; } else if (flush.getFlushSequenceNumber() < prepareFlushResult.flushOpSeqId) { - // This should not happen normally. However, lets be safe and guard against these cases + // This should not happen normally. However, lets be safe and guard against + // these cases // we received a flush commit with a smaller seqId than what we have prepared - // we will pick the flush file up from this commit (if we have not seen it), but we + // we will pick the flush file up from this commit (if we have not seen it), but + // we // will not drop the memstore LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with smaller seqId: " - + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " - + prepareFlushResult.flushOpSeqId + ". Picking up new file, but not dropping" - + " prepared memstore snapshot"); + + "Received a flush commit marker with smaller seqId: " + + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " + + prepareFlushResult.flushOpSeqId + ". Picking up new file, but not dropping" + + " prepared memstore snapshot"); replayFlushInStores(flush, prepareFlushResult, false); // snapshot is not dropped, so memstore sizes should not be decremented // we still have the prepared snapshot, flushing should still be true } else { - // This should not happen normally. However, lets be safe and guard against these cases + // This should not happen normally. However, lets be safe and guard against + // these cases // we received a flush commit with a larger seqId than what we have prepared - // we will pick the flush file for this. We will also obtain the updates lock and - // look for contents of the memstore to see whether we have edits after this seqId. + // we will pick the flush file for this. We will also obtain the updates lock + // and + // look for contents of the memstore to see whether we have edits after this + // seqId. // If not, we will drop all the memstore edits and the snapshot as well. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with larger seqId: " - + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " - + prepareFlushResult.flushOpSeqId + ". Picking up new file and dropping prepared" - + " memstore snapshot"); + + "Received a flush commit marker with larger seqId: " + + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " + + prepareFlushResult.flushOpSeqId + ". Picking up new file and dropping prepared" + + " memstore snapshot"); replayFlushInStores(flush, prepareFlushResult, true); @@ -6084,16 +6401,20 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { this.prepareFlushResult = null; writestate.flushing = false; } - // If we were waiting for observing a flush or region opening event for not showing - // partial data after a secondary region crash, we can allow reads now. We can only make - // sure that we are not showing partial data (for example skipping some previous edits) - // until we observe a full flush start and flush commit. So if we were not able to find + // If we were waiting for observing a flush or region opening event for not + // showing + // partial data after a secondary region crash, we can allow reads now. We can + // only make + // sure that we are not showing partial data (for example skipping some previous + // edits) + // until we observe a full flush start and flush commit. So if we were not able + // to find // a previous flush we will not enable reads now. this.setReadsEnabled(true); } else { LOG.warn( - getRegionInfo().getEncodedName() + " : " + "Received a flush commit marker with seqId:" - + flush.getFlushSequenceNumber() + ", but no previous prepared snapshot was found"); + getRegionInfo().getEncodedName() + " : " + "Received a flush commit marker with seqId:" + + flush.getFlushSequenceNumber() + ", but no previous prepared snapshot was found"); // There is no corresponding prepare snapshot from before. // We will pick up the new flushed file replayFlushInStores(flush, null, false); @@ -6113,8 +6434,8 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "At least one of the store files in flush: " + TextFormat.shortDebugString(flush) - + " doesn't exist any more. Skip loading the file(s)", ex); + + "At least one of the store files in flush: " + TextFormat.shortDebugString(flush) + + " doesn't exist any more. Skip loading the file(s)", ex); } finally { status.cleanup(); writestate.notifyAll(); @@ -6129,21 +6450,24 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { } /** - * Replays the given flush descriptor by opening the flush files in stores and dropping the + * Replays the given flush descriptor by opening the flush files in stores and + * dropping the * memstore snapshots if requested. - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated private void replayFlushInStores(FlushDescriptor flush, PrepareFlushResult prepareFlushResult, - boolean dropMemstoreSnapshot) throws IOException { + boolean dropMemstoreSnapshot) throws IOException { for (StoreFlushDescriptor storeFlush : flush.getStoreFlushesList()) { byte[] family = storeFlush.getFamilyName().toByteArray(); HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker from primary, but the family is not found." - + "Ignoring StoreFlushDescriptor:" + storeFlush); + + "Received a flush commit marker from primary, but the family is not found." + + "Ignoring StoreFlushDescriptor:" + storeFlush); continue; } List flushFiles = storeFlush.getFlushOutputList(); @@ -6158,8 +6482,8 @@ private void replayFlushInStores(FlushDescriptor flush, PrepareFlushResult prepa if (ctx == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Unexpected: flush commit marker received from store " + Bytes.toString(family) - + " but no associated flush context. Ignoring"); + + "Unexpected: flush commit marker received from store " + Bytes.toString(family) + + " but no associated flush context. Ignoring"); continue; } @@ -6175,8 +6499,7 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept long maxSeqId = -1; for (HStore store : stores) { String familyName = store.getColumnFamilyName(); - FileStatus[] files = - WALSplitUtil.getRecoveredHFiles(fs.getFileSystem(), regionDir, familyName); + FileStatus[] files = WALSplitUtil.getRecoveredHFiles(fs.getFileSystem(), regionDir, familyName); if (files != null && files.length != 0) { for (FileStatus file : files) { Path filePath = file.getPath(); @@ -6194,8 +6517,8 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept } if (this.rsServices != null && store.needsCompaction()) { this.rsServices.getCompactionRequestor().requestCompaction(this, store, - "load recovered hfiles request compaction", Store.PRIORITY_USER + 1, - CompactionLifeCycleTracker.DUMMY, null); + "load recovered hfiles request compaction", Store.PRIORITY_USER + 1, + CompactionLifeCycleTracker.DUMMY, null); } } } @@ -6203,8 +6526,10 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept } /** - * Be careful, this method will drop all data in the memstore of this region. Currently, this - * method is used to drop memstore to prevent memory leak when replaying recovered.edits while + * Be careful, this method will drop all data in the memstore of this region. + * Currently, this + * method is used to drop memstore to prevent memory leak when replaying + * recovered.edits while * opening region. */ private MemStoreSize dropMemStoreContents() throws IOException { @@ -6214,8 +6539,8 @@ private MemStoreSize dropMemStoreContents() throws IOException { for (HStore s : stores.values()) { MemStoreSize memStoreSize = doDropStoreMemStoreContentsForSeqId(s, HConstants.NO_SEQNUM); LOG.info("Drop memstore for Store " + s.getColumnFamilyName() + " in region " - + this.getRegionInfo().getRegionNameAsString() + " , dropped memstoresize: [" - + memStoreSize + " }"); + + this.getRegionInfo().getRegionNameAsString() + " , dropped memstoresize: [" + + memStoreSize + " }"); totalFreedSize.incMemStoreSize(memStoreSize); } return totalFreedSize.getMemStoreSize(); @@ -6225,7 +6550,8 @@ private MemStoreSize dropMemStoreContents() throws IOException { } /** - * Drops the memstore contents after replaying a flush descriptor or region open event replay if + * Drops the memstore contents after replaying a flush descriptor or region open + * event replay if * the memstore edits have seqNums smaller than the given seq id */ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) throws IOException { @@ -6237,8 +6563,8 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro if (seqId >= currentSeqId) { // then we can drop the memstore contents since everything is below this seqId LOG.info(getRegionInfo().getEncodedName() + " : " - + "Dropping memstore contents as well since replayed flush seqId: " + seqId - + " is greater than current seqId:" + currentSeqId); + + "Dropping memstore contents as well since replayed flush seqId: " + seqId + + " is greater than current seqId:" + currentSeqId); // Prepare flush (take a snapshot) and then abort (drop the snapshot) if (store == null) { @@ -6250,8 +6576,8 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro } } else { LOG.info(getRegionInfo().getEncodedName() + " : " - + "Not dropping memstore contents since replayed flush seqId: " + seqId - + " is smaller than current seqId:" + currentSeqId); + + "Not dropping memstore contents since replayed flush seqId: " + seqId + + " is smaller than current seqId:" + currentSeqId); } } finally { this.updatesLock.writeLock().unlock(); @@ -6260,7 +6586,7 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro } private MemStoreSize doDropStoreMemStoreContentsForSeqId(HStore s, long currentSeqId) - throws IOException { + throws IOException { MemStoreSize flushableSize = s.getFlushableSize(); this.decrMemStoreSize(flushableSize); StoreFlushContext ctx = s.createFlushContext(currentSeqId, FlushLifeCycleTracker.DUMMY); @@ -6270,8 +6596,10 @@ private MemStoreSize doDropStoreMemStoreContentsForSeqId(HStore s, long currentS } private void replayWALFlushAbortMarker(FlushDescriptor flush) { - // nothing to do for now. A flush abort will cause a RS abort which means that the region - // will be opened somewhere else later. We will see the region open event soon, and replaying + // nothing to do for now. A flush abort will cause a RS abort which means that + // the region + // will be opened somewhere else later. We will see the region open event soon, + // and replaying // that will drop the snapshot } @@ -6279,16 +6607,20 @@ private void replayWALFlushCannotFlushMarker(FlushDescriptor flush, long replayS synchronized (writestate) { if (this.lastReplayedOpenRegionSeqId > replaySeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " - + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " + + lastReplayedOpenRegionSeqId); return; } - // If we were waiting for observing a flush or region opening event for not showing partial - // data after a secondary region crash, we can allow reads now. This event means that the - // primary was not able to flush because memstore is empty when we requested flush. By the - // time we observe this, we are guaranteed to have up to date seqId with our previous + // If we were waiting for observing a flush or region opening event for not + // showing partial + // data after a secondary region crash, we can allow reads now. This event means + // that the + // primary was not able to flush because memstore is empty when we requested + // flush. By the + // time we observe this, we are guaranteed to have up to date seqId with our + // previous // assignment. this.setReadsEnabled(true); } @@ -6299,15 +6631,15 @@ PrepareFlushResult getPrepareFlushResult() { } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", - justification = "Intentional; cleared the memstore") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; cleared the memstore") void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOException { checkTargetRegion(regionEvent.getEncodedRegionName().toByteArray(), - "RegionEvent marker from WAL ", regionEvent); + "RegionEvent marker from WAL ", regionEvent); startRegionOperation(Operation.REPLAY_EVENT); try { @@ -6321,34 +6653,40 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } if (regionEvent.getEventType() != EventType.REGION_OPEN) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Unknown region event received, ignoring :" + TextFormat.shortDebugString(regionEvent)); + + "Unknown region event received, ignoring :" + TextFormat.shortDebugString(regionEvent)); return; } if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying region open event marker " - + TextFormat.shortDebugString(regionEvent)); + + TextFormat.shortDebugString(regionEvent)); } // we will use writestate as a coarse-grain lock for all the replay events synchronized (writestate) { - // Replication can deliver events out of order when primary region moves or the region - // server crashes, since there is no coordination between replication of different wal files - // belonging to different region servers. We have to safe guard against this case by using - // region open event's seqid. Since this is the first event that the region puts (after - // possibly flushing recovered.edits), after seeing this event, we can ignore every edit + // Replication can deliver events out of order when primary region moves or the + // region + // server crashes, since there is no coordination between replication of + // different wal files + // belonging to different region servers. We have to safe guard against this + // case by using + // region open event's seqid. Since this is the first event that the region puts + // (after + // possibly flushing recovered.edits), after seeing this event, we can ignore + // every edit // smaller than this seqId if (this.lastReplayedOpenRegionSeqId <= regionEvent.getLogSequenceNumber()) { this.lastReplayedOpenRegionSeqId = regionEvent.getLogSequenceNumber(); } else { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying region event :" - + TextFormat.shortDebugString(regionEvent) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(regionEvent) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return; } - // region open lists all the files that the region has at the time of the opening. Just pick + // region open lists all the files that the region has at the time of the + // opening. Just pick // all the files and drop prepared flushes and empty memstores for (StoreDescriptor storeDescriptor : regionEvent.getStoresList()) { // stores of primary may be different now @@ -6356,8 +6694,8 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a region open marker from primary, but the family is not found. " - + "Ignoring. StoreDescriptor:" + storeDescriptor); + + "Received a region open marker from primary, but the family is not found. " + + "Ignoring. StoreDescriptor:" + storeDescriptor); continue; } @@ -6367,7 +6705,7 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce store.refreshStoreFiles(storeFiles); // replace the files with the new ones } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "At least one of the store files: " - + storeFiles + " doesn't exist any more. Skip loading the file(s)", ex); + + storeFiles + " doesn't exist any more. Skip loading the file(s)", ex); continue; } if (store.getMaxSequenceId().orElse(0L) != storeSeqId) { @@ -6376,11 +6714,12 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } if (writestate.flushing) { - // only drop memstore snapshots if they are smaller than last flush for the store + // only drop memstore snapshots if they are smaller than last flush for the + // store if (this.prepareFlushResult.flushOpSeqId <= regionEvent.getLogSequenceNumber()) { StoreFlushContext ctx = this.prepareFlushResult.storeFlushCtxs == null - ? null - : this.prepareFlushResult.storeFlushCtxs.get(family); + ? null + : this.prepareFlushResult.storeFlushCtxs.get(family); if (ctx != null) { MemStoreSize mss = store.getFlushableSize(); ctx.abort(); @@ -6390,7 +6729,8 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } } - // Drop the memstore contents if they are now smaller than the latest seen flushed file + // Drop the memstore contents if they are now smaller than the latest seen + // flushed file dropMemStoreContentsForSeqId(regionEvent.getLogSequenceNumber(), store); if (storeSeqId > this.maxFlushedSeqId) { this.maxFlushedSeqId = storeSeqId; @@ -6404,7 +6744,8 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce // advance the mvcc read point so that the new flushed file is visible. mvcc.await(); - // If we were waiting for observing a flush or region opening event for not showing partial + // If we were waiting for observing a flush or region opening event for not + // showing partial // data after a secondary region crash, we can allow reads now. this.setReadsEnabled(true); @@ -6421,13 +6762,14 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep + * compatibility for old region * replica implementation. */ @Deprecated void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) throws IOException { checkTargetRegion(bulkLoadEvent.getEncodedRegionName().toByteArray(), - "BulkLoad marker from WAL ", bulkLoadEvent); + "BulkLoad marker from WAL ", bulkLoadEvent); if (ServerRegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { return; // if primary nothing to do @@ -6435,7 +6777,7 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying bulkload event marker " - + TextFormat.shortDebugString(bulkLoadEvent)); + + TextFormat.shortDebugString(bulkLoadEvent)); } // check if multiple families involved boolean multipleFamilies = false; @@ -6454,20 +6796,23 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th try { // we will use writestate as a coarse-grain lock for all the replay events synchronized (writestate) { - // Replication can deliver events out of order when primary region moves or the region - // server crashes, since there is no coordination between replication of different wal files - // belonging to different region servers. We have to safe guard against this case by using - // region open event's seqid. Since this is the first event that the region puts (after - // possibly flushing recovered.edits), after seeing this event, we can ignore every edit + // Replication can deliver events out of order when primary region moves or the + // region + // server crashes, since there is no coordination between replication of + // different wal files + // belonging to different region servers. We have to safe guard against this + // case by using + // region open event's seqid. Since this is the first event that the region puts + // (after + // possibly flushing recovered.edits), after seeing this event, we can ignore + // every edit // smaller than this seqId - if ( - bulkLoadEvent.getBulkloadSeqNum() >= 0 - && this.lastReplayedOpenRegionSeqId >= bulkLoadEvent.getBulkloadSeqNum() - ) { + if (bulkLoadEvent.getBulkloadSeqNum() >= 0 + && this.lastReplayedOpenRegionSeqId >= bulkLoadEvent.getBulkloadSeqNum()) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying bulkload event :" - + TextFormat.shortDebugString(bulkLoadEvent) - + " because its sequence id is smaller than this region's lastReplayedOpenRegionSeqId" - + " =" + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(bulkLoadEvent) + + " because its sequence id is smaller than this region's lastReplayedOpenRegionSeqId" + + " =" + lastReplayedOpenRegionSeqId); return; } @@ -6478,8 +6823,8 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a bulk load marker from primary, but the family is not found. " - + "Ignoring. StoreDescriptor:" + storeDescriptor); + + "Received a bulk load marker from primary, but the family is not found. " + + "Ignoring. StoreDescriptor:" + storeDescriptor); continue; } @@ -6491,10 +6836,10 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th store.bulkLoadHFile(storeFileInfo); } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + ((storeFileInfo != null) - ? storeFileInfo.toString() - : (new Path(Bytes.toString(family), storeFile)).toString()) - + " doesn't exist any more. Skip loading the file"); + + ((storeFileInfo != null) + ? storeFileInfo.toString() + : (new Path(Bytes.toString(family), storeFile)).toString()) + + " doesn't exist any more. Skip loading the file"); } } } @@ -6512,9 +6857,11 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th *

    * We will directly apply the cells to the memstore. This is because: *

      - *
    1. All the cells are gotten from {@link WALEdit}, so we only have {@link Put} and + *
    2. All the cells are gotten from {@link WALEdit}, so we only have + * {@link Put} and * {@link Delete} here
    3. - *
    4. The replay is single threaded, we do not need to acquire row lock, as the region is read + *
    5. The replay is single threaded, we do not need to acquire row lock, as the + * region is read * only so no one else can write it.
    6. *
    7. We do not need to write WAL.
    8. *
    9. We will advance MVCC in the caller directly.
    10. @@ -6532,12 +6879,16 @@ private void replayWALBatchMutate(Map> family2Cells) throws I } /** - * Replay the meta edits, i.e, flush marker, compaction marker, bulk load marker, region event + * Replay the meta edits, i.e, flush marker, compaction marker, bulk load + * marker, region event * marker, etc. *

      - * For all events other than start flush, we will just call {@link #refreshStoreFiles()} as the - * logic is straight-forward and robust. For start flush, we need to snapshot the memstore, so - * later {@link #refreshStoreFiles()} call could drop the snapshot, otherwise we may run out of + * For all events other than start flush, we will just call + * {@link #refreshStoreFiles()} as the + * logic is straight-forward and robust. For start flush, we need to snapshot + * the memstore, so + * later {@link #refreshStoreFiles()} call could drop the snapshot, otherwise we + * may run out of * memory. */ private void replayWALMetaEdit(Cell cell) throws IOException { @@ -6552,19 +6903,20 @@ private void replayWALMetaEdit(Cell cell) throws IOException { if (!writestate.flushing) { this.writestate.flushing = true; } else { - // usually this should not happen but let's make the code more robust, it is not a - // big deal to just ignore it, the refreshStoreFiles call should have the ability to + // usually this should not happen but let's make the code more robust, it is not + // a + // big deal to just ignore it, the refreshStoreFiles call should have the + // ability to // clean up the inconsistent state. LOG.debug("NOT flushing {} as already flushing", getRegionInfo()); break; } } - MonitoredTask status = - TaskMonitor.get().createStatus("Preparing flush " + getRegionInfo()); + MonitoredTask status = TaskMonitor.get().createStatus("Preparing flush " + getRegionInfo()); Collection storesToFlush = getStoresToFlush(flushDesc); try { - PrepareFlushResult prepareResult = - internalPrepareFlushCache(null, flushDesc.getFlushSequenceNumber(), storesToFlush, + PrepareFlushResult prepareResult = internalPrepareFlushCache(null, flushDesc.getFlushSequenceNumber(), + storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); if (prepareResult.result == null) { // save the PrepareFlushResult so that we can use it later from commit flush @@ -6572,19 +6924,17 @@ private void replayWALMetaEdit(Cell cell) throws IOException { status.markComplete("Flush prepare successful"); if (LOG.isDebugEnabled()) { LOG.debug("{} prepared flush with seqId: {}", getRegionInfo(), - flushDesc.getFlushSequenceNumber()); + flushDesc.getFlushSequenceNumber()); } } else { - // special case empty memstore. We will still save the flush result in this case, + // special case empty memstore. We will still save the flush result in this + // case, // since our memstore is empty, but the primary is still flushing - if ( - prepareResult.getResult().getResult() - == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY - ) { + if (prepareResult.getResult().getResult() == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY) { this.prepareFlushResult = prepareResult; if (LOG.isDebugEnabled()) { LOG.debug("{} prepared empty flush with seqId: {}", getRegionInfo(), - flushDesc.getFlushSequenceNumber()); + flushDesc.getFlushSequenceNumber()); } } status.abort("Flush prepare failed with " + prepareResult.result); @@ -6595,8 +6945,10 @@ private void replayWALMetaEdit(Cell cell) throws IOException { } break; case ABORT_FLUSH: - // do nothing, an abort flush means the source region server will crash itself, after - // the primary region online, it will send us an open region marker, then we can clean + // do nothing, an abort flush means the source region server will crash itself, + // after + // the primary region online, it will send us an open region marker, then we can + // clean // up the memstore. synchronized (writestate) { writestate.flushing = false; @@ -6613,7 +6965,7 @@ private void replayWALMetaEdit(Cell cell) throws IOException { break; default: LOG.warn("{} received a flush event with unknown action: {}", getRegionInfo(), - TextFormat.shortDebugString(flushDesc)); + TextFormat.shortDebugString(flushDesc)); } } else { // for all other region events, we will do a refreshStoreFiles @@ -6646,7 +6998,7 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { try { if (!replayLock.tryLock(timeout, TimeUnit.MILLISECONDS)) { throw new TimeoutIOException( - "Timeout while waiting for lock when replaying edits for " + getRegionInfo()); + "Timeout while waiting for lock when replaying edits for " + getRegionInfo()); } } catch (InterruptedException e) { throw throwOnInterrupt(e); @@ -6659,7 +7011,8 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { long sequenceId = entry.getKey().getLogSequenceNumber(); if (lastReplayedSequenceId >= sequenceId) { // we have already replayed this edit, skip - // remember to advance the CellScanner, as we may have multiple WALEntries, we may still + // remember to advance the CellScanner, as we may have multiple WALEntries, we + // may still // need apply later WALEntries for (int i = 0; i < count; i++) { // Throw index out of bounds if our cell count is off @@ -6677,14 +7030,21 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { } Cell cell = cells.current(); if (WALEdit.isMetaEditFamily(cell)) { - // If there is meta edit, i.e, we have done flush/compaction/open, then we need to apply - // the previous cells first, and then replay the special meta edit. The meta edit is like - // a barrier, We need to keep the order. For example, the flush marker will contain a - // flush sequence number, which makes us possible to drop memstore content, but if we - // apply some edits which have greater sequence id first, then we can not drop the - // memstore content when replaying the flush marker, which is not good as we could run out + // If there is meta edit, i.e, we have done flush/compaction/open, then we need + // to apply + // the previous cells first, and then replay the special meta edit. The meta + // edit is like + // a barrier, We need to keep the order. For example, the flush marker will + // contain a + // flush sequence number, which makes us possible to drop memstore content, but + // if we + // apply some edits which have greater sequence id first, then we can not drop + // the + // memstore content when replaying the flush marker, which is not good as we + // could run out // of memory. - // And usually, a meta edit will have a special WALEntry for it, so this is just a safe + // And usually, a meta edit will have a special WALEntry for it, so this is just + // a safe // guard logic to make sure we do not break things in the worst case. if (!family2Cells.isEmpty()) { replayWALBatchMutate(family2Cells); @@ -6693,7 +7053,7 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { replayWALMetaEdit(cell); } else { family2Cells.computeIfAbsent(CellUtil.cloneFamily(cell), k -> new ArrayList<>()) - .add(cell); + .add(cell); } } // do not forget to apply the remaining cells @@ -6708,14 +7068,15 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { } /** - * If all stores ended up dropping their snapshots, we can safely drop the prepareFlushResult + * If all stores ended up dropping their snapshots, we can safely drop the + * prepareFlushResult */ private void dropPrepareFlushIfPossible() { if (writestate.flushing) { boolean canDrop = true; if (prepareFlushResult.storeFlushCtxs != null) { for (Entry entry : prepareFlushResult.storeFlushCtxs - .entrySet()) { + .entrySet()) { HStore store = getStore(entry.getKey()); if (store == null) { continue; @@ -6727,7 +7088,8 @@ private void dropPrepareFlushIfPossible() { } } - // this means that all the stores in the region has finished flushing, but the WAL marker + // this means that all the stores in the region has finished flushing, but the + // WAL marker // may not have been written or we did not receive it yet. if (canDrop) { writestate.flushing = false; @@ -6741,8 +7103,7 @@ public boolean refreshStoreFiles() throws IOException { return refreshStoreFiles(false); } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", - justification = "Notify is about post replay. Intentional") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Notify is about post replay. Intentional") protected boolean refreshStoreFiles(boolean force) throws IOException { if (!force && ServerRegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { return false; // if primary nothing to do @@ -6750,7 +7111,7 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + "Refreshing store files to see whether we can free up memstore"); + + "Refreshing store files to see whether we can free up memstore"); } long totalFreedDataSize = 0; @@ -6766,7 +7127,8 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { // MIGHT break atomic edits across column families. long maxSeqIdBefore = store.getMaxSequenceId().orElse(0L); - // refresh the store files. This is similar to observing a region open wal marker. + // refresh the store files. This is similar to observing a region open wal + // marker. store.refreshStoreFiles(); long storeSeqId = store.getMaxSequenceId().orElse(0L); @@ -6777,18 +7139,19 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { // see whether we can drop the memstore or the snapshot if (storeSeqId > maxSeqIdBefore) { if (writestate.flushing) { - // only drop memstore snapshots if they are smaller than last flush for the store + // only drop memstore snapshots if they are smaller than last flush for the + // store if (this.prepareFlushResult.flushOpSeqId <= storeSeqId) { StoreFlushContext ctx = this.prepareFlushResult.storeFlushCtxs == null - ? null - : this.prepareFlushResult.storeFlushCtxs - .get(store.getColumnFamilyDescriptor().getName()); + ? null + : this.prepareFlushResult.storeFlushCtxs + .get(store.getColumnFamilyDescriptor().getName()); if (ctx != null) { MemStoreSize mss = store.getFlushableSize(); ctx.abort(); this.decrMemStoreSize(mss); this.prepareFlushResult.storeFlushCtxs - .remove(store.getColumnFamilyDescriptor().getName()); + .remove(store.getColumnFamilyDescriptor().getName()); totalFreedDataSize += mss.getDataSize(); } } @@ -6803,14 +7166,18 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { dropPrepareFlushIfPossible(); // advance the mvcc read point so that the new flushed files are visible. - // either greater than flush seq number or they were already picked up via flush. + // either greater than flush seq number or they were already picked up via + // flush. for (HStore s : stores.values()) { mvcc.advanceTo(s.getMaxMemStoreTS().orElse(0L)); } - // smallestSeqIdInStores is the seqId that we have a corresponding hfile for. We can safely - // skip all edits that are to be replayed in the future with that has a smaller seqId - // than this. We are updating lastReplayedOpenRegionSeqId so that we can skip all edits + // smallestSeqIdInStores is the seqId that we have a corresponding hfile for. We + // can safely + // skip all edits that are to be replayed in the future with that has a smaller + // seqId + // than this. We are updating lastReplayedOpenRegionSeqId so that we can skip + // all edits // that we have picked the flush files for if (this.lastReplayedOpenRegionSeqId < smallestSeqIdInStores) { this.lastReplayedOpenRegionSeqId = smallestSeqIdInStores; @@ -6818,9 +7185,9 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { } if (!map.isEmpty()) { for (Map.Entry entry : map.entrySet()) { - // Drop the memstore contents if they are now smaller than the latest seen flushed file - totalFreedDataSize += - dropMemStoreContentsForSeqId(entry.getValue(), entry.getKey()).getDataSize(); + // Drop the memstore contents if they are now smaller than the latest seen + // flushed file + totalFreedDataSize += dropMemStoreContentsForSeqId(entry.getValue(), entry.getKey()).getDataSize(); } } // C. Finally notify anyone waiting on memstore to clear: @@ -6838,35 +7205,35 @@ private void logRegionFiles() { if (LOG.isTraceEnabled()) { LOG.trace(getRegionInfo().getEncodedName() + " : Store files for region: "); stores.values().stream().filter(s -> s.getStorefiles() != null) - .flatMap(s -> s.getStorefiles().stream()) - .forEachOrdered(sf -> LOG.trace(getRegionInfo().getEncodedName() + " : " + sf)); + .flatMap(s -> s.getStorefiles().stream()) + .forEachOrdered(sf -> LOG.trace(getRegionInfo().getEncodedName() + " : " + sf)); } } /** - * Checks whether the given regionName is either equal to our region, or that the regionName is + * Checks whether the given regionName is either equal to our region, or that + * the regionName is * the primary region to our corresponding range for the secondary replica. */ private void checkTargetRegion(byte[] encodedRegionName, String exceptionMsg, Object payload) - throws WrongRegionException { + throws WrongRegionException { if (Bytes.equals(this.getRegionInfo().getEncodedNameAsBytes(), encodedRegionName)) { return; } - if ( - !RegionReplicaUtil.isDefaultReplica(this.getRegionInfo()) - && Bytes.equals(encodedRegionName, this.fs.getRegionInfoForFS().getEncodedNameAsBytes()) - ) { + if (!RegionReplicaUtil.isDefaultReplica(this.getRegionInfo()) + && Bytes.equals(encodedRegionName, this.fs.getRegionInfoForFS().getEncodedNameAsBytes())) { return; } throw new WrongRegionException( - exceptionMsg + payload + " targetted for region " + Bytes.toStringBinary(encodedRegionName) - + " does not match this region: " + this.getRegionInfo()); + exceptionMsg + payload + " targetted for region " + Bytes.toStringBinary(encodedRegionName) + + " does not match this region: " + this.getRegionInfo()); } /** * Used by tests + * * @param s Store to add edit too. * @param cell Cell to add. */ @@ -6875,13 +7242,15 @@ protected void restoreEdit(HStore s, Cell cell, MemStoreSizing memstoreAccountin } /** - * make sure have been through lease recovery before get file status, so the file length can be + * make sure have been through lease recovery before get file status, so the + * file length can be * trusted. + * * @param p File to check. * @return True if file was zero-length (and if so, we'll delete it in here). */ private static boolean isZeroLengthThenDelete(final FileSystem fs, final FileStatus stat, - final Path p) throws IOException { + final Path p) throws IOException { if (stat.getLen() > 0) { return false; } @@ -6891,12 +7260,12 @@ private static boolean isZeroLengthThenDelete(final FileSystem fs, final FileSta } protected HStore instantiateHStore(final ColumnFamilyDescriptor family, boolean warmup) - throws IOException { + throws IOException { if (family.isMobEnabled()) { if (HFile.getFormatVersion(this.conf) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) { throw new IOException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS - + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY - + " accordingly."); + + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY + + " accordingly."); } return new HMobStore(this, family, this.conf, warmup); } @@ -6909,12 +7278,13 @@ public HStore getStore(byte[] column) { } /** - * Return HStore instance. Does not do any copy: as the number of store is limited, we iterate on + * Return HStore instance. Does not do any copy: as the number of store is + * limited, we iterate on * the list. */ private HStore getStore(Cell cell) { return stores.entrySet().stream().filter(e -> CellUtil.matchingFamily(cell, e.getKey())) - .map(e -> e.getValue()).findFirst().orElse(null); + .map(e -> e.getValue()).findFirst().orElse(null); } @Override @@ -6930,7 +7300,7 @@ public List getStoreFileList(byte[][] columns) throws IllegalArgumentExc HStore store = this.stores.get(column); if (store == null) { throw new IllegalArgumentException( - "No column family : " + new String(column, StandardCharsets.UTF_8) + " available"); + "No column family : " + new String(column, StandardCharsets.UTF_8) + " available"); } Collection storeFiles = store.getStorefiles(); if (storeFiles == null) { @@ -6954,14 +7324,15 @@ public List getStoreFileList(byte[][] columns) throws IllegalArgumentExc void checkRow(byte[] row, String op) throws IOException { if (!rowIsInRange(getRegionInfo(), row)) { throw new WrongRegionException("Requested row out of range for " + op + " on HRegion " + this - + ", startKey='" + Bytes.toStringBinary(getRegionInfo().getStartKey()) + "', getEndKey()='" - + Bytes.toStringBinary(getRegionInfo().getEndKey()) + "', row='" + Bytes.toStringBinary(row) - + "'"); + + ", startKey='" + Bytes.toStringBinary(getRegionInfo().getStartKey()) + "', getEndKey()='" + + Bytes.toStringBinary(getRegionInfo().getEndKey()) + "', row='" + Bytes.toStringBinary(row) + + "'"); } } /** * Get an exclusive ( write lock ) lock on a given row. + * * @param row Which row to lock. * @return A locked RowLock. The lock is exclusive and already aqquired. */ @@ -6977,12 +7348,12 @@ public RowLock getRowLock(byte[] row, boolean readLock) throws IOException { Span createRegionSpan(String name) { return TraceUtil.createSpan(name).setAttribute(REGION_NAMES_KEY, - Collections.singletonList(getRegionInfo().getRegionNameAsString())); + Collections.singletonList(getRegionInfo().getRegionNameAsString())); } // will be override in tests protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevRowLock) - throws IOException { + throws IOException { // create an object to use a a key in the row lock map HashedBytes rowKey = new HashedBytes(row); @@ -6998,13 +7369,12 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR // Now try an get the lock. // This can fail as if (readLock) { - // For read lock, if the caller has locked the same row previously, it will not try + // For read lock, if the caller has locked the same row previously, it will not + // try // to acquire the same read lock. It simply returns the previous row lock. RowLockImpl prevRowLockImpl = (RowLockImpl) prevRowLock; - if ( - (prevRowLockImpl != null) - && (prevRowLockImpl.getLock() == rowLockContext.readWriteLock.readLock()) - ) { + if ((prevRowLockImpl != null) + && (prevRowLockImpl.getLock() == rowLockContext.readWriteLock.readLock())) { success = true; return prevRowLock; } @@ -7030,11 +7400,12 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR if (timeout <= 0 || !result.getLock().tryLock(timeout, TimeUnit.MILLISECONDS)) { String message = "Timed out waiting for lock for row: " + rowKey + " in region " - + getRegionInfo().getEncodedName(); + + getRegionInfo().getEncodedName(); if (reachDeadlineFirst) { throw new TimeoutIOException(message); } else { - // If timeToDeadline is larger than rowLockWaitDuration, we can not drop the request. + // If timeToDeadline is larger than rowLockWaitDuration, we can not drop the + // request. throw new IOException(message); } } @@ -7044,19 +7415,22 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR } catch (InterruptedException ie) { if (LOG.isDebugEnabled()) { LOG.debug("Thread interrupted waiting for lock on row: {}, in region {}", rowKey, - getRegionInfo().getRegionNameAsString()); + getRegionInfo().getRegionNameAsString()); } throw throwOnInterrupt(ie); } catch (Error error) { - // The maximum lock count for read lock is 64K (hardcoded), when this maximum count - // is reached, it will throw out an Error. This Error needs to be caught so it can + // The maximum lock count for read lock is 64K (hardcoded), when this maximum + // count + // is reached, it will throw out an Error. This Error needs to be caught so it + // can // go ahead to process the minibatch with lock acquired. LOG.warn("Error to get row lock for {}, in region {}, cause: {}", Bytes.toStringBinary(row), - getRegionInfo().getRegionNameAsString(), error); + getRegionInfo().getRegionNameAsString(), error); IOException ioe = new IOException(error); throw ioe; } finally { - // Clean up the counts just in case this was the thing keeping the context alive. + // Clean up the counts just in case this was the thing keeping the context + // alive. if (!success && rowLockContext != null) { rowLockContext.cleanUp(); } @@ -7064,9 +7438,9 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR } private RowLock getRowLock(byte[] row, boolean readLock, final RowLock prevRowLock) - throws IOException { + throws IOException { return TraceUtil.trace(() -> getRowLockInternal(row, readLock, prevRowLock), - () -> createRegionSpan("Region.getRowLock").setAttribute(ROW_LOCK_READ_LOCK_KEY, readLock)); + () -> createRegionSpan("Region.getRowLock").setAttribute(ROW_LOCK_READ_LOCK_KEY, readLock)); } private void releaseRowLocks(List rowLocks) { @@ -7139,7 +7513,7 @@ public void setThreadName(String threadName) { @Override public String toString() { return "RowLockContext{" + "row=" + row + ", readWriteLock=" + readWriteLock + ", count=" - + count + ", threadName=" + threadName + '}'; + + count + ", threadName=" + threadName + '}'; } } @@ -7176,7 +7550,9 @@ public String toString() { } /** - * Determines whether multiple column families are present Precondition: familyPaths is not null + * Determines whether multiple column families are present Precondition: + * familyPaths is not null + * * @param familyPaths List of (column family, hfilePath) */ private static boolean hasMultipleColumnFamilies(Collection> familyPaths) { @@ -7195,35 +7571,43 @@ private static boolean hasMultipleColumnFamilies(Collection } /** - * Attempts to atomically load a group of hfiles. This is critical for loading rows with multiple + * Attempts to atomically load a group of hfiles. This is critical for loading + * rows with multiple * column families atomically. - * @param familyPaths List of Pair<byte[] column family, String hfilePath> - * @param bulkLoadListener Internal hooks enabling massaging/preparation of a file about to be + * + * @param familyPaths List of Pair<byte[] column family, String + * hfilePath> + * @param bulkLoadListener Internal hooks enabling massaging/preparation of a + * file about to be * bulk loaded - * @return Map from family to List of store file paths if successful, null if failed recoverably + * @return Map from family to List of store file paths if successful, null if + * failed recoverably * @throws IOException if failed unrecoverably. */ public Map> bulkLoadHFiles(Collection> familyPaths, - boolean assignSeqId, BulkLoadListener bulkLoadListener) throws IOException { + boolean assignSeqId, BulkLoadListener bulkLoadListener) throws IOException { return bulkLoadHFiles(familyPaths, assignSeqId, bulkLoadListener, false, null, true); } /** - * Listener class to enable callers of bulkLoadHFile() to perform any necessary pre/post + * Listener class to enable callers of bulkLoadHFile() to perform any necessary + * pre/post * processing of a given bulkload call */ public interface BulkLoadListener { /** * Called before an HFile is actually loaded + * * @param family family being loaded to * @param srcPath path of HFile * @return final path to be used for actual loading */ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String customStaging) - throws IOException; + throws IOException; /** * Called after a successful HFile load + * * @param family family being loaded to * @param srcPath path of HFile */ @@ -7231,6 +7615,7 @@ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String c /** * Called after a failed HFile load + * * @param family family being loaded to * @param srcPath path of HFile */ @@ -7238,19 +7623,25 @@ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String c } /** - * Attempts to atomically load a group of hfiles. This is critical for loading rows with multiple + * Attempts to atomically load a group of hfiles. This is critical for loading + * rows with multiple * column families atomically. - * @param familyPaths List of Pair<byte[] column family, String hfilePath> - * @param bulkLoadListener Internal hooks enabling massaging/preparation of a file about to be + * + * @param familyPaths List of Pair<byte[] column family, String + * hfilePath> + * @param bulkLoadListener Internal hooks enabling massaging/preparation of a + * file about to be * bulk loaded * @param copyFile always copy hfiles if true - * @param clusterIds ids from clusters that had already handled the given bulkload event. - * @return Map from family to List of store file paths if successful, null if failed recoverably + * @param clusterIds ids from clusters that had already handled the given + * bulkload event. + * @return Map from family to List of store file paths if successful, null if + * failed recoverably * @throws IOException if failed unrecoverably. */ public Map> bulkLoadHFiles(Collection> familyPaths, - boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile, - List clusterIds, boolean replicate) throws IOException { + boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile, + List clusterIds, boolean replicate) throws IOException { long seqId = -1; Map> storeFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR); Map storeFilesSizes = new HashMap<>(); @@ -7273,7 +7664,7 @@ public Map> bulkLoadHFiles(Collection> f HStore store = getStore(familyName); if (store == null) { ioException = new org.apache.hadoop.hbase.DoNotRetryIOException( - "No such column family " + Bytes.toStringBinary(familyName)); + "No such column family " + Bytes.toStringBinary(familyName)); } else { try { store.assertBulkLoadHFileOk(new Path(path)); @@ -7289,7 +7680,7 @@ public Map> bulkLoadHFiles(Collection> f // validation failed because of some sort of IO problem. if (ioException != null) { LOG.error("There was IO error when checking if the bulk load is ok in region {}.", this, - ioException); + ioException); throw ioException; } } @@ -7298,18 +7689,22 @@ public Map> bulkLoadHFiles(Collection> f StringBuilder list = new StringBuilder(); for (Pair p : failures) { list.append("\n").append(Bytes.toString(p.getFirst())).append(" : ") - .append(p.getSecond()); + .append(p.getSecond()); } // problem when validating LOG.warn("There was a recoverable bulk load failure likely due to a split. These (family," - + " HFile) pairs were not loaded: {}, in region {}", list.toString(), this); + + " HFile) pairs were not loaded: {}, in region {}", list.toString(), this); return null; } - // We need to assign a sequential ID that's in between two memstores in order to preserve - // the guarantee that all the edits lower than the highest sequential ID from all the - // HFiles are flushed on disk. See HBASE-10958. The sequence id returned when we flush is - // guaranteed to be one beyond the file made when we flushed (or if nothing to flush, it is + // We need to assign a sequential ID that's in between two memstores in order to + // preserve + // the guarantee that all the edits lower than the highest sequential ID from + // all the + // HFiles are flushed on disk. See HBASE-10958. The sequence id returned when we + // flush is + // guaranteed to be one beyond the file made when we flushed (or if nothing to + // flush, it is // a sequence id that we can be sure is beyond the last hfile written). if (assignSeqId) { FlushResult fs = flushcache(true, false, FlushLifeCycleTracker.DUMMY); @@ -7323,12 +7718,11 @@ public Map> bulkLoadHFiles(Collection> f waitForFlushes(); } else { throw new IOException("Could not bulk load with an assigned sequential ID because the " - + "flush didn't run. Reason for not flushing: " + ((FlushResultImpl) fs).failureReason); + + "flush didn't run. Reason for not flushing: " + ((FlushResultImpl) fs).failureReason); } } - Map>> familyWithFinalPath = - new TreeMap<>(Bytes.BYTES_COMPARATOR); + Map>> familyWithFinalPath = new TreeMap<>(Bytes.BYTES_COMPARATOR); for (Pair p : familyPaths) { byte[] familyName = p.getFirst(); String path = p.getSecond(); @@ -7342,7 +7736,7 @@ public Map> bulkLoadHFiles(Collection> f boolean reqTmp = store.storeEngine.requireWritingToTmpDirFirst(); if (bulkLoadListener != null) { finalPath = bulkLoadListener.prepareBulkLoad(familyName, path, copyFile, - reqTmp ? null : fs.getRegionDir().toString()); + reqTmp ? null : fs.getRegionDir().toString()); } Pair pair = null; if (reqTmp || !StoreFileInfo.isHFile(finalPath)) { @@ -7357,13 +7751,13 @@ public Map> bulkLoadHFiles(Collection> f // cannot recover from since it is likely a failed HDFS operation. LOG.error("There was a partial failure due to IO when attempting to" + " load " - + Bytes.toString(p.getFirst()) + " : " + p.getSecond(), ioe); + + Bytes.toString(p.getFirst()) + " : " + p.getSecond(), ioe); if (bulkLoadListener != null) { try { bulkLoadListener.failedBulkLoad(familyName, finalPath); } catch (Exception ex) { LOG.error("Error while calling failedBulkLoad for family " - + Bytes.toString(familyName) + " with path " + path, ex); + + Bytes.toString(familyName) + " with path " + path, ex); } } throw ioe; @@ -7387,7 +7781,7 @@ public Map> bulkLoadHFiles(Collection> f try { FileSystem fs = commitedStoreFile.getFileSystem(baseConf); storeFilesSizes.put(commitedStoreFile.getName(), - fs.getFileStatus(commitedStoreFile).getLen()); + fs.getFileStatus(commitedStoreFile).getLen()); } catch (IOException e) { LOG.warn("Failed to find the size of hfile " + commitedStoreFile, e); storeFilesSizes.put(commitedStoreFile.getName(), 0L); @@ -7409,13 +7803,13 @@ public Map> bulkLoadHFiles(Collection> f // TODO Need a better story for reverting partial failures due to HDFS. LOG.error("There was a partial failure due to IO when attempting to" + " load " - + Bytes.toString(familyName) + " : " + p.getSecond(), ioe); + + Bytes.toString(familyName) + " : " + p.getSecond(), ioe); if (bulkLoadListener != null) { try { bulkLoadListener.failedBulkLoad(familyName, path); } catch (Exception ex) { LOG.error("Error while calling failedBulkLoad for family " - + Bytes.toString(familyName) + " with path " + path, ex); + + Bytes.toString(familyName) + " with path " + path, ex); } } throw ioe; @@ -7431,9 +7825,9 @@ public Map> bulkLoadHFiles(Collection> f try { if (this.rsServices != null && store.needsCompaction()) { this.rsServices.getCompactionRequestor().requestSystemCompaction(this, store, - "bulkload hfiles request compaction", true); + "bulkload hfiles request compaction", true); LOG.info("Request compaction for region {} family {} after bulk load", - this.getRegionInfo().getEncodedName(), store.getColumnFamilyName()); + this.getRegionInfo().getEncodedName(), store.getColumnFamilyName()); } } catch (IOException e) { LOG.error("bulkload hfiles request compaction error ", e); @@ -7444,15 +7838,16 @@ public Map> bulkLoadHFiles(Collection> f if (wal != null && !storeFiles.isEmpty()) { // Write a bulk load event for hfiles that are loaded try { - WALProtos.BulkLoadDescriptor loadDescriptor = - ProtobufUtil.toBulkLoadDescriptor(this.getRegionInfo().getTable(), + WALProtos.BulkLoadDescriptor loadDescriptor = ProtobufUtil.toBulkLoadDescriptor( + this.getRegionInfo().getTable(), UnsafeByteOperations.unsafeWrap(this.getRegionInfo().getEncodedNameAsBytes()), storeFiles, storeFilesSizes, seqId, clusterIds, replicate); WALUtil.writeBulkLoadMarkerAndSync(this.wal, this.getReplicationScope(), getRegionInfo(), - loadDescriptor, mvcc, regionReplicationSink.orElse(null)); + loadDescriptor, mvcc, regionReplicationSink.orElse(null)); } catch (IOException ioe) { if (this.rsServices != null) { - // Have to abort region server because some hfiles has been loaded but we can't write + // Have to abort region server because some hfiles has been loaded but we can't + // write // the event into WAL isSuccessful = false; this.rsServices.abort("Failed to write bulk load event into WAL.", ioe); @@ -7468,7 +7863,7 @@ public Map> bulkLoadHFiles(Collection> f @Override public boolean equals(Object o) { return o instanceof HRegion && Bytes.equals(getRegionInfo().getRegionName(), - ((HRegion) o).getRegionInfo().getRegionName()); + ((HRegion) o).getRegionInfo().getRegionName()); } @Override @@ -7483,31 +7878,39 @@ public String toString() { // Utility methods /** - * A utility method to create new instances of HRegion based on the {@link HConstants#REGION_IMPL} + * A utility method to create new instances of HRegion based on the + * {@link HConstants#REGION_IMPL} * configuration property. - * @param tableDir qualified path of directory where region should be located, usually the table + * + * @param tableDir qualified path of directory where region should be located, + * usually the table * directory. - * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a - * logfile from the previous execution that's custom-computed for this HRegion. - * The HRegionServer computes and sorts the appropriate wal info for this - * HRegion. If there is a previous file (implying that the HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion + * The wal file is a + * logfile from the previous execution that's custom-computed + * for this HRegion. + * The HRegionServer computes and sorts the appropriate wal + * info for this + * HRegion. If there is a previous file (implying that the + * HRegion has been * written-to before), then read it from the supplied path. * @param fs is the filesystem. * @param conf is global configuration settings. - * @param regionInfo - RegionInfo that describes the region is new), then read them from the + * @param regionInfo - RegionInfo that describes the region is new), then read + * them from the * supplied path. * @param htd the table descriptor * @return the new instance */ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configuration conf, - RegionInfo regionInfo, final TableDescriptor htd, RegionServerServices rsServices) { + RegionInfo regionInfo, final TableDescriptor htd, RegionServerServices rsServices) { try { @SuppressWarnings("unchecked") - Class regionClass = - (Class) conf.getClass(HConstants.REGION_IMPL, HRegion.class); + Class regionClass = (Class) conf.getClass(HConstants.REGION_IMPL, + HRegion.class); - Constructor c = - regionClass.getConstructor(Path.class, WAL.class, FileSystem.class, Configuration.class, + Constructor c = regionClass.getConstructor(Path.class, WAL.class, FileSystem.class, + Configuration.class, RegionInfo.class, TableDescriptor.class, RegionServerServices.class); return c.newInstance(tableDir, wal, fs, conf, regionInfo, htd, rsServices); @@ -7519,6 +7922,7 @@ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configur /** * Convenience method creating new HRegions. Used by createTable. + * * @param info Info for region to create. * @param rootDir Root directory for HBase instance * @param wal shared WAL @@ -7526,13 +7930,14 @@ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configur * @return new HRegion */ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, - final boolean initialize) throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, + final boolean initialize) throws IOException { return createHRegion(info, rootDir, conf, hTableDescriptor, wal, initialize, null); } /** * Convenience method creating new HRegions. Used by createTable. + * * @param info Info for region to create. * @param rootDir Root directory for HBase instance * @param wal shared WAL @@ -7541,15 +7946,14 @@ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, * @return new HRegion */ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, - final boolean initialize, RegionServerServices rsRpcServices) throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, + final boolean initialize, RegionServerServices rsRpcServices) throws IOException { LOG.info("creating " + info + ", tableDescriptor=" - + (hTableDescriptor == null ? "null" : hTableDescriptor) + ", regionDir=" + rootDir); + + (hTableDescriptor == null ? "null" : hTableDescriptor) + ", regionDir=" + rootDir); createRegionDir(conf, info, rootDir); FileSystem fs = rootDir.getFileSystem(conf); Path tableDir = CommonFSUtils.getTableDir(rootDir, info.getTable()); - HRegion region = - HRegion.newHRegion(tableDir, wal, fs, conf, info, hTableDescriptor, rsRpcServices); + HRegion region = HRegion.newHRegion(tableDir, wal, fs, conf, info, hTableDescriptor, rsRpcServices); if (initialize) { region.initialize(null); } @@ -7560,9 +7964,9 @@ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, * Create a region under the given table directory. */ public static HRegion createHRegion(Configuration conf, RegionInfo regionInfo, FileSystem fs, - Path tableDir, TableDescriptor tableDesc) throws IOException { + Path tableDir, TableDescriptor tableDesc) throws IOException { LOG.info("Creating {}, tableDescriptor={}, under table dir {}", regionInfo, tableDesc, - tableDir); + tableDir); HRegionFileSystem.createRegionOnFileSystem(conf, fs, tableDir, regionInfo); HRegion region = HRegion.newHRegion(tableDir, null, fs, conf, regionInfo, tableDesc, null); return region; @@ -7572,40 +7976,49 @@ public static HRegion createHRegion(Configuration conf, RegionInfo regionInfo, F * Create the region directory in the filesystem. */ public static HRegionFileSystem createRegionDir(Configuration configuration, RegionInfo ri, - Path rootDir) throws IOException { + Path rootDir) throws IOException { FileSystem fs = rootDir.getFileSystem(configuration); Path tableDir = CommonFSUtils.getTableDir(rootDir, ri.getTable()); - // If directory already exists, will log warning and keep going. Will try to create + // If directory already exists, will log warning and keep going. Will try to + // create // .regioninfo. If one exists, will overwrite. return HRegionFileSystem.createRegionOnFileSystem(configuration, fs, tableDir, ri); } public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal) - throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal) + throws IOException { return createHRegion(info, rootDir, conf, hTableDescriptor, wal, true); } /** * Open a Region. + * * @param info Info for region to be opened. - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is - * properly kept up. HRegionStore does this every time it opens a new region. + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure + * the wal id is + * properly kept up. HRegionStore does this every time it opens a + * new region. * @return new HRegion */ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor htd, final WAL wal, - final Configuration conf) throws IOException { + final Configuration conf) throws IOException { return openHRegion(info, htd, wal, conf, null, null); } /** * Open a Region. + * * @param info Info for region to be opened * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) - * passing the result of the call to HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every time it opens a new + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) + * passing the result of the call to + * HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every + * time it opens a new * region. * @param conf The Configuration object to use. * @param rsServices An interface we can request flushes against. @@ -7613,35 +8026,43 @@ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor h * @return new HRegion */ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor htd, final WAL wal, - final Configuration conf, final RegionServerServices rsServices, - final CancelableProgressable reporter) throws IOException { + final Configuration conf, final RegionServerServices rsServices, + final CancelableProgressable reporter) throws IOException { return openHRegion(CommonFSUtils.getRootDir(conf), info, htd, wal, conf, rsServices, reporter); } /** * Open a Region. + * * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is - * properly kept up. HRegionStore does this every time it opens a new region. + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure + * the wal id is + * properly kept up. HRegionStore does this every time it opens a + * new region. * @param conf The Configuration object to use. * @return new HRegion */ public static HRegion openHRegion(Path rootDir, final RegionInfo info, final TableDescriptor htd, - final WAL wal, final Configuration conf) throws IOException { + final WAL wal, final Configuration conf) throws IOException { return openHRegion(rootDir, info, htd, wal, conf, null, null); } /** * Open a Region. + * * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) - * passing the result of the call to HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every time it opens a new + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) + * passing the result of the call to + * HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every + * time it opens a new * region. * @param conf The Configuration object to use. * @param rsServices An interface we can request flushes against. @@ -7649,9 +8070,9 @@ public static HRegion openHRegion(Path rootDir, final RegionInfo info, final Tab * @return new HRegion */ public static HRegion openHRegion(final Path rootDir, final RegionInfo info, - final TableDescriptor htd, final WAL wal, final Configuration conf, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final TableDescriptor htd, final WAL wal, final Configuration conf, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { FileSystem fs = null; if (rsServices != null) { fs = rsServices.getFileSystem(); @@ -7664,54 +8085,66 @@ public static HRegion openHRegion(final Path rootDir, final RegionInfo info, /** * Open a Region. + * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is - * properly kept up. HRegionStore does this every time it opens a new region. + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure + * the wal id is + * properly kept up. HRegionStore does this every time it opens a + * new region. * @return new HRegion */ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, - final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal) - throws IOException { + final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal) + throws IOException { return openHRegion(conf, fs, rootDir, info, htd, wal, null, null); } /** * Open a Region. + * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) - * passing the result of the call to HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every time it opens a new + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) + * passing the result of the call to + * HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every + * time it opens a new * region. * @param rsServices An interface we can request flushes against. * @param reporter An interface we can report progress against. * @return new HRegion */ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, - final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { Path tableDir = CommonFSUtils.getTableDir(rootDir, info.getTable()); return openHRegionFromTableDir(conf, fs, tableDir, info, htd, wal, rsServices, reporter); } /** * Open a Region. + * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) - * passing the result of the call to HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every time it opens a new + * @param wal WAL for region to use. This method will call + * WAL#setSequenceNumber(long) + * passing the result of the call to + * HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every + * time it opens a new * region. * @param rsServices An interface we can request flushes against. * @param reporter An interface we can report progress against. @@ -7719,9 +8152,9 @@ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, * @throws NullPointerException if {@code info} is {@code null} */ public static HRegion openHRegionFromTableDir(final Configuration conf, final FileSystem fs, - final Path tableDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final Path tableDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); LOG.debug("Opening region: {}", info); HRegion r = HRegion.newHRegion(tableDir, wal, fs, conf, info, htd, rsServices); @@ -7734,20 +8167,21 @@ public NavigableMap getReplicationScope() { /** * Useful when reopening a closed region (normally for unit tests) + * * @param other original object * @param reporter An interface we can report progress against. * @return new HRegion */ public static HRegion openHRegion(final HRegion other, final CancelableProgressable reporter) - throws IOException { + throws IOException { HRegionFileSystem regionFs = other.getRegionFileSystem(); HRegion r = newHRegion(regionFs.getTableDir(), other.getWAL(), regionFs.getFileSystem(), - other.baseConf, other.getRegionInfo(), other.getTableDescriptor(), null); + other.baseConf, other.getRegionInfo(), other.getTableDescriptor(), null); return r.openHRegion(reporter); } public static Region openHRegion(final Region other, final CancelableProgressable reporter) - throws IOException { + throws IOException { return openHRegion((HRegion) other, reporter); } @@ -7755,12 +8189,12 @@ public static Region openHRegion(final Region other, final CancelableProgressabl * Open HRegion. *

      * Calls initialize and sets sequenceId. + * * @return Returns this */ private HRegion openHRegion(final CancelableProgressable reporter) throws IOException { try { - CompoundConfiguration cConfig = - new CompoundConfiguration().add(conf).addBytesMap(htableDescriptor.getValues()); + CompoundConfiguration cConfig = new CompoundConfiguration().add(conf).addBytesMap(htableDescriptor.getValues()); // Refuse to open the region if we are missing local compression support TableDescriptorChecker.checkCompression(cConfig, htableDescriptor); // Refuse to open the region if encryption configuration is incorrect or @@ -7772,13 +8206,13 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce TableDescriptorChecker.checkClassLoading(cConfig, htableDescriptor); this.openSeqNum = initialize(reporter); this.mvcc.advanceTo(openSeqNum); - // The openSeqNum must be increased every time when a region is assigned, as we rely on it to - // determine whether a region has been successfully reopened. So here we always write open + // The openSeqNum must be increased every time when a region is assigned, as we + // rely on it to + // determine whether a region has been successfully reopened. So here we always + // write open // marker, even if the table is read only. - if ( - wal != null && getRegionServerServices() != null - && RegionReplicaUtil.isDefaultReplica(getRegionInfo()) - ) { + if (wal != null && getRegionServerServices() != null + && RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { writeRegionOpenMarker(wal, openSeqNum); } } catch (Throwable t) { @@ -7791,7 +8225,7 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce this.close(true); } catch (Throwable e) { LOG.warn("Open region: {} failed. Try close region but got exception ", - this.getRegionInfo(), e); + this.getRegionInfo(), e); } throw t; } @@ -7800,6 +8234,7 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce /** * Open a Region on a read-only file-system (like hdfs snapshots) + * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param info Info for region to be opened. @@ -7808,7 +8243,7 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce * @throws NullPointerException if {@code info} is {@code null} */ public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, final FileSystem fs, - final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException { + final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); if (LOG.isDebugEnabled()) { LOG.debug("Opening region (readOnly filesystem): " + info); @@ -7822,8 +8257,8 @@ public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, fi } public static HRegion warmupHRegion(final RegionInfo info, final TableDescriptor htd, - final WAL wal, final Configuration conf, final RegionServerServices rsServices, - final CancelableProgressable reporter) throws IOException { + final WAL wal, final Configuration conf, final RegionServerServices rsServices, + final CancelableProgressable reporter) throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); LOG.debug("Warmup {}", info); @@ -7844,6 +8279,7 @@ public static HRegion warmupHRegion(final RegionInfo info, final TableDescriptor /** * Computes the Path of the HRegion + * * @param tabledir qualified path for table * @param name ENCODED region name * @return Path of HRegion directory @@ -7855,24 +8291,24 @@ public static Path getRegionDir(final Path tabledir, final String name) { } /** - * Determines if the specified row is within the row range specified by the specified RegionInfo + * Determines if the specified row is within the row range specified by the + * specified RegionInfo + * * @param info RegionInfo that specifies the row range * @param row row to be checked * @return true if the row is within the range specified by the RegionInfo */ public static boolean rowIsInRange(RegionInfo info, final byte[] row) { return ((info.getStartKey().length == 0) || (Bytes.compareTo(info.getStartKey(), row) <= 0)) - && ((info.getEndKey().length == 0) || (Bytes.compareTo(info.getEndKey(), row) > 0)); + && ((info.getEndKey().length == 0) || (Bytes.compareTo(info.getEndKey(), row) > 0)); } public static boolean rowIsInRange(RegionInfo info, final byte[] row, final int offset, - final short length) { + final short length) { return ((info.getStartKey().length == 0) - || (Bytes.compareTo(info.getStartKey(), 0, info.getStartKey().length, row, offset, length) - <= 0)) - && ((info.getEndKey().length == 0) - || (Bytes.compareTo(info.getEndKey(), 0, info.getEndKey().length, row, offset, length) - > 0)); + || (Bytes.compareTo(info.getStartKey(), 0, info.getStartKey().length, row, offset, length) <= 0)) + && ((info.getEndKey().length == 0) + || (Bytes.compareTo(info.getEndKey(), 0, info.getEndKey().length, row, offset, length) > 0)); } @Override @@ -7903,13 +8339,13 @@ public List get(Get get, boolean withCoprocessor) throws IOException { } private List get(Get get, boolean withCoprocessor, long nonceGroup, long nonce) - throws IOException { + throws IOException { return TraceUtil.trace(() -> getInternal(get, withCoprocessor, nonceGroup, nonce), - () -> createRegionSpan("Region.get")); + () -> createRegionSpan("Region.get")); } private List getInternal(Get get, boolean withCoprocessor, long nonceGroup, long nonce) - throws IOException { + throws IOException { List results = new ArrayList<>(); // pre-get CP hook @@ -7927,7 +8363,8 @@ private List getInternal(Get get, boolean withCoprocessor, long nonceGroup List tmp = new ArrayList<>(); scanner.next(tmp); // Copy EC to heap, then close the scanner. - // This can be an EXPENSIVE call. It may make an extra copy from offheap to onheap buffers. + // This can be an EXPENSIVE call. It may make an extra copy from offheap to + // onheap buffers. // See more details in HBASE-26036. for (Cell cell : tmp) { results.add(CellUtil.cloneIfNecessary(cell)); @@ -7986,23 +8423,29 @@ public Result mutateRow(RowMutations rm, long nonceGroup, long nonce) throws IOE /** * Perform atomic (all or none) mutations within the region. - * @param mutations The list of mutations to perform. mutations can contain - * operations for multiple rows. Caller has to ensure that all rows are + * + * @param mutations The list of mutations to perform. mutations + * can contain + * operations for multiple rows. Caller has to ensure that all + * rows are * contained in this region. * @param rowsToLock Rows to lock * @param nonceGroup Optional nonce group of the operation (client Id) - * @param nonce Optional nonce of the operation (unique random id to ensure "more - * idempotence") If multiple rows are locked care should be taken that - * rowsToLock is sorted in order to avoid deadlocks. + * @param nonce Optional nonce of the operation (unique random id to ensure + * "more + * idempotence") If multiple rows are locked care should be + * taken that + * rowsToLock is sorted in order to avoid + * deadlocks. */ @Override public void mutateRowsWithLocks(Collection mutations, Collection rowsToLock, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { batchMutate(new MutationBatchOperation(this, mutations.toArray(new Mutation[mutations.size()]), - true, nonceGroup, nonce) { + true, nonceGroup, nonce) { @Override - public MiniBatchOperationInProgress - lockRowsAndBuildMiniBatch(List acquiredRowLocks) throws IOException { + public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List acquiredRowLocks) + throws IOException { RowLock prevRowLock = null; for (byte[] row : rowsToLock) { try { @@ -8013,7 +8456,7 @@ public void mutateRowsWithLocks(Collection mutations, Collection 100 - ? 100 - : rsServices.getCompactionPressure() * 100)); + ? 100 + : rsServices.getCompactionPressure() * 100)); return stats.build(); } @@ -8057,7 +8500,8 @@ public Result append(Append append, long nonceGroup, long nonce) throws IOExcept checkResources(); startRegionOperation(Operation.APPEND); try { - // All edits for the given row (across all column families) must happen atomically. + // All edits for the given row (across all column families) must happen + // atomically. return mutate(append, true, nonceGroup, nonce).getResult(); } finally { closeRegionOperation(Operation.APPEND); @@ -8076,7 +8520,8 @@ public Result increment(Increment increment, long nonceGroup, long nonce) throws checkResources(); startRegionOperation(Operation.INCREMENT); try { - // All edits for the given row (across all column families) must happen atomically. + // All edits for the given row (across all column families) must happen + // atomically. return mutate(increment, true, nonceGroup, nonce).getResult(); } finally { closeRegionOperation(Operation.INCREMENT); @@ -8085,14 +8530,14 @@ public Result increment(Increment increment, long nonceGroup, long nonce) throws } private WALKeyImpl createWALKeyForWALAppend(boolean isReplay, BatchOperation batchOp, long now, - long nonceGroup, long nonce) { + long nonceGroup, long nonce) { WALKeyImpl walKey = isReplay - ? new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), - this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, - batchOp.getClusterIds(), nonceGroup, nonce, mvcc) - : new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), - this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, - batchOp.getClusterIds(), nonceGroup, nonce, mvcc, this.getReplicationScope()); + ? new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), + this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, + batchOp.getClusterIds(), nonceGroup, nonce, mvcc) + : new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), + this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, + batchOp.getClusterIds(), nonceGroup, nonce, mvcc, this.getReplicationScope()); if (isReplay) { walKey.setOrigLogSeqNum(batchOp.getOrigLogSeqNum()); } @@ -8101,15 +8546,15 @@ private WALKeyImpl createWALKeyForWALAppend(boolean isReplay, BatchOperation /** Returns writeEntry associated with this append */ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, - MiniBatchOperationInProgress miniBatchOp, long now, NonceKey nonceKey) - throws IOException { + MiniBatchOperationInProgress miniBatchOp, long now, NonceKey nonceKey) + throws IOException { Preconditions.checkArgument(walEdit != null && !walEdit.isEmpty(), "WALEdit is null or empty!"); Preconditions.checkArgument( - !walEdit.isReplay() || batchOp.getOrigLogSeqNum() != SequenceId.NO_SEQUENCE_ID, - "Invalid replay sequence Id for replay WALEdit!"); + !walEdit.isReplay() || batchOp.getOrigLogSeqNum() != SequenceId.NO_SEQUENCE_ID, + "Invalid replay sequence Id for replay WALEdit!"); WALKeyImpl walKey = createWALKeyForWALAppend(walEdit.isReplay(), batchOp, now, - nonceKey.getNonceGroup(), nonceKey.getNonce()); + nonceKey.getNonceGroup(), nonceKey.getNonce()); // don't call the coproc hook for writes to the WAL caused by // system lifecycle events like flushes or compactions if (this.coprocessorHost != null && !walEdit.isMetaEdit()) { @@ -8123,9 +8568,12 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, sync(txid, batchOp.durability); } /** - * If above {@link HRegion#sync} throws Exception, the RegionServer should be aborted and - * following {@link BatchOperation#writeMiniBatchOperationsToMemStore} will not be executed, - * so there is no need to replicate to secondary replica, for this reason here we attach the + * If above {@link HRegion#sync} throws Exception, the RegionServer should be + * aborted and + * following {@link BatchOperation#writeMiniBatchOperationsToMemStore} will not + * be executed, + * so there is no need to replicate to secondary replica, for this reason here + * we attach the * region replication action after the {@link HRegion#sync} is successful. */ this.attachRegionReplicationInWALAppend(batchOp, miniBatchOp, walKey, walEdit, writeEntry); @@ -8136,10 +8584,14 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, } /** - * If {@link WAL#sync} get a timeout exception, the only correct way is to abort the region - * server, as the design of {@link WAL#sync}, is to succeed or die, there is no 'failure'. It - * is usually not a big deal is because we set a very large default value(5 minutes) for - * {@link AbstractFSWAL#WAL_SYNC_TIMEOUT_MS}, usually the WAL system will abort the region + * If {@link WAL#sync} get a timeout exception, the only correct way is to abort + * the region + * server, as the design of {@link WAL#sync}, is to succeed or die, there is no + * 'failure'. It + * is usually not a big deal is because we set a very large default value(5 + * minutes) for + * {@link AbstractFSWAL#WAL_SYNC_TIMEOUT_MS}, usually the WAL system will abort + * the region * server if it can not finish the sync within 5 minutes. */ if (ioe instanceof WALSyncTimeoutIOException) { @@ -8152,25 +8604,31 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, } /** - * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for replicating to region + * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for + * replicating to region * replica. */ private void attachRegionReplicationInWALAppend(BatchOperation batchOp, - MiniBatchOperationInProgress miniBatchOp, WALKeyImpl walKey, WALEdit walEdit, - WriteEntry writeEntry) { + MiniBatchOperationInProgress miniBatchOp, WALKeyImpl walKey, WALEdit walEdit, + WriteEntry writeEntry) { if (!regionReplicationSink.isPresent()) { return; } /** - * If {@link HRegion#regionReplicationSink} is present,only {@link MutationBatchOperation} is + * If {@link HRegion#regionReplicationSink} is present,only + * {@link MutationBatchOperation} is * used and {@link NonceKey} is all the same for {@link Mutation}s in * {@link MutationBatchOperation},so for HBASE-26993 case 1,if - * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is not null and we could + * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is not + * null and we could * enter {@link HRegion#doWALAppend},that means partial {@link Mutation}s are * {@link Durability#SKIP_WAL}, we use - * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} to replicate to region - * replica,but if {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is - * null,that means there is no {@link Mutation} is {@link Durability#SKIP_WAL},so we just use + * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} to + * replicate to region + * replica,but if + * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is + * null,that means there is no {@link Mutation} is + * {@link Durability#SKIP_WAL},so we just use * walEdit to replicate. */ assert batchOp instanceof MutationBatchOperation; @@ -8182,11 +8640,12 @@ private void attachRegionReplicationInWALAppend(BatchOperation batchOp, } /** - * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for replicating to region + * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for + * replicating to region * replica. */ private void doAttachReplicateRegionReplicaAction(WALKeyImpl walKey, WALEdit walEdit, - WriteEntry writeEntry) { + WriteEntry writeEntry) { if (walEdit == null || walEdit.isEmpty()) { return; } @@ -8210,34 +8669,43 @@ private void doAttachReplicateRegionReplicaAction(WALKeyImpl walKey, WALEdit wal // 1 x MetricsRegionWrapperImpl - metricsRegionWrapper // 1 x ReadPointCalculationLock - smallestReadPointCalcLock public static final long DEEP_OVERHEAD = FIXED_OVERHEAD + ClassSize.OBJECT + // closeLock - (2 * ClassSize.ATOMIC_BOOLEAN) + // closed, closing - (3 * ClassSize.ATOMIC_LONG) + // numPutsWithoutWAL, dataInMemoryWithoutWAL, - // compactionsFailed - (3 * ClassSize.CONCURRENT_HASHMAP) + // lockedRows, scannerReadPoints, regionLockHolders - WriteState.HEAP_SIZE + // writestate - ClassSize.CONCURRENT_SKIPLISTMAP + ClassSize.CONCURRENT_SKIPLISTMAP_ENTRY + // stores - (2 * ClassSize.REENTRANT_LOCK) + // lock, updatesLock - MultiVersionConcurrencyControl.FIXED_SIZE // mvcc - + 2 * ClassSize.TREEMAP // maxSeqIdInStores, replicationScopes - + 2 * ClassSize.ATOMIC_INTEGER // majorInProgress, minorInProgress - + ClassSize.STORE_SERVICES // store services - + StoreHotnessProtector.FIXED_SIZE; + (2 * ClassSize.ATOMIC_BOOLEAN) + // closed, closing + (3 * ClassSize.ATOMIC_LONG) + // numPutsWithoutWAL, dataInMemoryWithoutWAL, + // compactionsFailed + (3 * ClassSize.CONCURRENT_HASHMAP) + // lockedRows, scannerReadPoints, regionLockHolders + WriteState.HEAP_SIZE + // writestate + ClassSize.CONCURRENT_SKIPLISTMAP + ClassSize.CONCURRENT_SKIPLISTMAP_ENTRY + // stores + (2 * ClassSize.REENTRANT_LOCK) + // lock, updatesLock + MultiVersionConcurrencyControl.FIXED_SIZE // mvcc + + 2 * ClassSize.TREEMAP // maxSeqIdInStores, replicationScopes + + 2 * ClassSize.ATOMIC_INTEGER // majorInProgress, minorInProgress + + ClassSize.STORE_SERVICES // store services + + StoreHotnessProtector.FIXED_SIZE; @Override public long heapSize() { - // this does not take into account row locks, recent flushes, mvcc entries, and more + // this does not take into account row locks, recent flushes, mvcc entries, and + // more return DEEP_OVERHEAD + stores.values().stream().mapToLong(HStore::heapSize).sum(); } /** - * Registers a new protocol buffer {@link Service} subclass as a coprocessor endpoint to be - * available for handling {@link #execService(RpcController, CoprocessorServiceCall)} calls. + * Registers a new protocol buffer {@link Service} subclass as a coprocessor + * endpoint to be + * available for handling + * {@link #execService(RpcController, CoprocessorServiceCall)} calls. *

      - * Only a single instance may be registered per region for a given {@link Service} subclass (the - * instances are keyed on {@link ServiceDescriptor#getFullName()}.. After the first registration, - * subsequent calls with the same service name will fail with a return value of {@code false}. - * @param instance the {@code Service} subclass instance to expose as a coprocessor endpoint - * @return {@code true} if the registration was successful, {@code false} otherwise + * Only a single instance may be registered per region for a given + * {@link Service} subclass (the + * instances are keyed on {@link ServiceDescriptor#getFullName()}.. After the + * first registration, + * subsequent calls with the same service name will fail with a return value of + * {@code false}. + * + * @param instance the {@code Service} subclass instance to expose as a + * coprocessor endpoint + * @return {@code true} if the registration was successful, {@code false} + * otherwise */ public boolean registerService(Service instance) { // No stacking of instances is allowed for a single service name @@ -8245,37 +8713,44 @@ public boolean registerService(Service instance) { String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc); if (coprocessorServiceHandlers.containsKey(serviceName)) { LOG.error("Coprocessor service {} already registered, rejecting request from {} in region {}", - serviceName, instance, this); + serviceName, instance, this); return false; } coprocessorServiceHandlers.put(serviceName, instance); if (LOG.isDebugEnabled()) { LOG.debug("Registered coprocessor service: region=" - + Bytes.toStringBinary(getRegionInfo().getRegionName()) + " service=" + serviceName); + + Bytes.toStringBinary(getRegionInfo().getRegionName()) + " service=" + serviceName); } return true; } /** - * Executes a single protocol buffer coprocessor endpoint {@link Service} method using the - * registered protocol handlers. {@link Service} implementations must be registered via the + * Executes a single protocol buffer coprocessor endpoint {@link Service} method + * using the + * registered protocol handlers. {@link Service} implementations must be + * registered via the * {@link #registerService(Service)} method before they are available. - * @param controller an {@code RpcContoller} implementation to pass to the invoked service - * @param call a {@code CoprocessorServiceCall} instance identifying the service, method, + * + * @param controller an {@code RpcContoller} implementation to pass to the + * invoked service + * @param call a {@code CoprocessorServiceCall} instance identifying the + * service, method, * and parameters for the method invocation - * @return a protocol buffer {@code Message} instance containing the method's result - * @throws IOException if no registered service handler is found or an error occurs during the + * @return a protocol buffer {@code Message} instance containing the method's + * result + * @throws IOException if no registered service handler is found or an error + * occurs during the * invocation * @see #registerService(Service) */ public Message execService(RpcController controller, CoprocessorServiceCall call) - throws IOException { + throws IOException { String serviceName = call.getServiceName(); Service service = coprocessorServiceHandlers.get(serviceName); if (service == null) { throw new UnknownProtocolException(null, "No registered coprocessor service found for " - + serviceName + " in region " + Bytes.toStringBinary(getRegionInfo().getRegionName())); + + serviceName + " in region " + Bytes.toStringBinary(getRegionInfo().getRegionName())); } ServiceDescriptor serviceDesc = service.getDescriptorForType(); @@ -8292,8 +8767,7 @@ public Message execService(RpcController controller, CoprocessorServiceCall call request = coprocessorHost.preEndpointInvocation(service, methodName, request); } - final Message.Builder responseBuilder = - service.getResponsePrototype(methodDesc).newBuilderForType(); + final Message.Builder responseBuilder = service.getResponsePrototype(methodDesc).newBuilderForType(); service.callMethod(methodDesc, controller, request, new RpcCallback() { @Override public void run(Message message) { @@ -8306,8 +8780,7 @@ public void run(Message message) { if (coprocessorHost != null) { coprocessorHost.postEndpointInvocation(service, methodName, request, responseBuilder); } - IOException exception = - org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.getControllerException(controller); + IOException exception = org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.getControllerException(controller); if (exception != null) { throw exception; } @@ -8320,7 +8793,8 @@ public Optional checkSplit() { } /** - * Return the split point. An empty result indicates the region isn't splittable. + * Return the split point. An empty result indicates the region isn't + * splittable. */ public Optional checkSplit(boolean force) { // Can't split META @@ -8362,7 +8836,7 @@ public int getCompactPriority() { return Store.PRIORITY_USER; } return stores.values().stream().mapToInt(HStore::getCompactPriority).min() - .orElse(Store.NO_PRIORITY); + .orElse(Store.NO_PRIORITY); } /** Returns the coprocessor host */ @@ -8400,11 +8874,10 @@ public void startRegionOperation(Operation op) throws IOException { default: // all others break; } - if ( - op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op == Operation.COMPACT_REGION - || op == Operation.COMPACT_SWITCH - ) { - // split, merge or compact region doesn't need to check the closing/closed state or lock the + if (op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op == Operation.COMPACT_REGION + || op == Operation.COMPACT_SWITCH) { + // split, merge or compact region doesn't need to check the closing/closed state + // or lock the // region return; } @@ -8412,7 +8885,8 @@ public void startRegionOperation(Operation op) throws IOException { throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closing"); } lock(lock.readLock()); - // Update regionLockHolders ONLY for any startRegionOperation call that is invoked from + // Update regionLockHolders ONLY for any startRegionOperation call that is + // invoked from // an RPC handler Thread thisThread = Thread.currentThread(); if (isInterruptableOp) { @@ -8433,7 +8907,8 @@ public void startRegionOperation(Operation op) throws IOException { } } catch (Exception e) { if (isInterruptableOp) { - // would be harmless to remove what we didn't add but we know by 'isInterruptableOp' + // would be harmless to remove what we didn't add but we know by + // 'isInterruptableOp' // if we added this thread to regionLockHolders regionLockHolders.remove(thisThread); } @@ -8461,9 +8936,13 @@ public void closeRegionOperation(Operation operation) throws IOException { } /** - * This method needs to be called before any public call that reads or modifies stores in bulk. It - * has to be called just before a try. #closeBulkRegionOperation needs to be called in the try's - * finally block Acquires a writelock and checks if the region is closing or closed. + * This method needs to be called before any public call that reads or modifies + * stores in bulk. It + * has to be called just before a try. #closeBulkRegionOperation needs to be + * called in the try's + * finally block Acquires a writelock and checks if the region is closing or + * closed. + * * @throws NotServingRegionException when the region is closing or closed * @throws RegionTooBusyException if failed to get the lock in time * @throws InterruptedIOException if interrupted while waiting for a lock @@ -8472,41 +8951,50 @@ private void startBulkRegionOperation(boolean writeLockNeeded) throws IOExceptio if (this.closing.get()) { throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closing"); } - if (writeLockNeeded) lock(lock.writeLock()); - else lock(lock.readLock()); + if (writeLockNeeded) + lock(lock.writeLock()); + else + lock(lock.readLock()); if (this.closed.get()) { - if (writeLockNeeded) lock.writeLock().unlock(); - else lock.readLock().unlock(); + if (writeLockNeeded) + lock.writeLock().unlock(); + else + lock.readLock().unlock(); throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closed"); } regionLockHolders.put(Thread.currentThread(), true); } /** - * Closes the lock. This needs to be called in the finally block corresponding to the try block of + * Closes the lock. This needs to be called in the finally block corresponding + * to the try block of * #startRegionOperation */ private void closeBulkRegionOperation() { regionLockHolders.remove(Thread.currentThread()); - if (lock.writeLock().isHeldByCurrentThread()) lock.writeLock().unlock(); - else lock.readLock().unlock(); + if (lock.writeLock().isHeldByCurrentThread()) + lock.writeLock().unlock(); + else + lock.readLock().unlock(); } /** - * Update LongAdders for number of puts without wal and the size of possible data loss. These + * Update LongAdders for number of puts without wal and the size of possible + * data loss. These * information are exposed by the region server metrics. */ private void recordMutationWithoutWal(final Map> familyMap) { numMutationsWithoutWAL.increment(); if (numMutationsWithoutWAL.sum() <= 1) { LOG.info("writing data to region " + this - + " with WAL disabled. Data may be lost in the event of a crash."); + + " with WAL disabled. Data may be lost in the event of a crash."); } long mutationSize = 0; for (List cells : familyMap.values()) { // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator + // objects assert cells instanceof RandomAccess; int listSize = cells.size(); for (int i = 0; i < listSize; i++) { @@ -8523,25 +9011,26 @@ private void lock(final Lock lock) throws IOException { } /** - * Try to acquire a lock. Throw RegionTooBusyException if failed to get the lock in time. Throw + * Try to acquire a lock. Throw RegionTooBusyException if failed to get the lock + * in time. Throw * InterruptedIOException if interrupted while waiting for the lock. */ private void lock(final Lock lock, final int multiplier) throws IOException { try { final long waitTime = Math.min(maxBusyWaitDuration, - busyWaitDuration * Math.min(multiplier, maxBusyWaitMultiplier)); + busyWaitDuration * Math.min(multiplier, maxBusyWaitMultiplier)); if (!lock.tryLock(waitTime, TimeUnit.MILLISECONDS)) { // Don't print millis. Message is used as a key over in // RetriesExhaustedWithDetailsException processing. - final String regionName = - this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getRegionNameAsString(); + final String regionName = this.getRegionInfo() == null ? "unknown" + : this.getRegionInfo().getRegionNameAsString(); final String serverName = this.getRegionServerServices() == null - ? "unknown" - : (this.getRegionServerServices().getServerName() == null ? "unknown" - : this.getRegionServerServices().getServerName().toString()); + : (this.getRegionServerServices().getServerName() == null + ? "unknown" + : this.getRegionServerServices().getServerName().toString()); RegionTooBusyException rtbe = new RegionTooBusyException( - "Failed to obtain lock; regionName=" + regionName + ", server=" + serverName); + "Failed to obtain lock; regionName=" + regionName + ", server=" + serverName); LOG.warn("Region is too busy to allow lock acquisition.", rtbe); throw rtbe; } @@ -8555,6 +9044,7 @@ private void lock(final Lock lock, final int multiplier) throws IOException { /** * Calls sync with the given transaction ID + * * @param txid should sync up to which transaction * @throws IOException If anything goes wrong with DFS */ @@ -8594,7 +9084,10 @@ private boolean shouldSyncWAL() { return regionDurability.ordinal() > Durability.ASYNC_WAL.ordinal(); } - /** Returns the latest sequence number that was read from storage when this region was opened */ + /** + * Returns the latest sequence number that was read from storage when this + * region was opened + */ public long getOpenSeqNum() { return this.openSeqNum; } @@ -8612,8 +9105,8 @@ public long getOldestSeqIdOfStore(byte[] familyName) { public CompactionState getCompactionState() { boolean hasMajor = majorInProgress.get() > 0, hasMinor = minorInProgress.get() > 0; return (hasMajor - ? (hasMinor ? CompactionState.MAJOR_AND_MINOR : CompactionState.MAJOR) - : (hasMinor ? CompactionState.MINOR : CompactionState.NONE)); + ? (hasMinor ? CompactionState.MAJOR_AND_MINOR : CompactionState.MAJOR) + : (hasMinor ? CompactionState.MINOR : CompactionState.NONE)); } public void reportCompactionRequestStart(boolean isMajor) { @@ -8652,7 +9145,8 @@ protected void decrementFlushesQueuedCount() { } /** - * If a handler thread is eligible for interrupt, make it ineligible. Should be paired with + * If a handler thread is eligible for interrupt, make it ineligible. Should be + * paired with * {{@link #enableInterrupts()}. */ void disableInterrupts() { @@ -8660,7 +9154,8 @@ void disableInterrupts() { } /** - * If a handler thread was made ineligible for interrupt via {{@link #disableInterrupts()}, make + * If a handler thread was made ineligible for interrupt via + * {{@link #disableInterrupts()}, make * it eligible again. No-op if interrupts are already enabled. */ void enableInterrupts() { @@ -8669,7 +9164,8 @@ void enableInterrupts() { /** * Interrupt any region options that have acquired the region lock via - * {@link #startRegionOperation(org.apache.hadoop.hbase.regionserver.Region.Operation)}, or + * {@link #startRegionOperation(org.apache.hadoop.hbase.regionserver.Region.Operation)}, + * or * {@link #startBulkRegionOperation(boolean)}. */ private void interruptRegionOperations() { @@ -8684,6 +9180,7 @@ private void interruptRegionOperations() { /** * Check thread interrupt status and throw an exception if interrupted. + * * @throws NotServingRegionException if region is closing * @throws InterruptedIOException if interrupted but region is not closing */ @@ -8692,7 +9189,7 @@ void checkInterrupt() throws NotServingRegionException, InterruptedIOException { if (Thread.interrupted()) { if (this.closing.get()) { throw new NotServingRegionException( - getRegionInfo().getRegionNameAsString() + " is closing"); + getRegionInfo().getRegionNameAsString() + " is closing"); } throw new InterruptedIOException(); } @@ -8700,13 +9197,14 @@ void checkInterrupt() throws NotServingRegionException, InterruptedIOException { /** * Throw the correct exception upon interrupt + * * @param t cause */ // Package scope for tests IOException throwOnInterrupt(Throwable t) { if (this.closing.get()) { return (NotServingRegionException) new NotServingRegionException( - getRegionInfo().getRegionNameAsString() + " is closing").initCause(t); + getRegionInfo().getRegionNameAsString() + " is closing").initCause(t); } return (InterruptedIOException) new InterruptedIOException().initCause(t); } @@ -8718,11 +9216,9 @@ IOException throwOnInterrupt(Throwable t) { public void onConfigurationChange(Configuration conf) { this.storeHotnessProtector.update(conf); // update coprocessorHost if the configuration has changed. - if ( - CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(), conf, + if (CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(), conf, CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, - CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY) - ) { + CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY)) { LOG.info("Update the system coprocessors because the configuration has changed"); decorateRegionConfiguration(conf); this.coprocessorHost = new RegionCoprocessorHost(this, rsServices, conf); @@ -8778,27 +9274,27 @@ void throwException(String title, String regionName) { @Override public void requestCompaction(String why, int priority, boolean major, - CompactionLifeCycleTracker tracker) throws IOException { + CompactionLifeCycleTracker tracker) throws IOException { if (major) { stores.values().forEach(HStore::triggerMajorCompaction); } rsServices.getCompactionRequestor().requestCompaction(this, why, priority, tracker, - RpcServer.getRequestUser().orElse(null)); + RpcServer.getRequestUser().orElse(null)); } @Override public void requestCompaction(byte[] family, String why, int priority, boolean major, - CompactionLifeCycleTracker tracker) throws IOException { + CompactionLifeCycleTracker tracker) throws IOException { HStore store = stores.get(family); if (store == null) { throw new NoSuchColumnFamilyException("column family " + Bytes.toString(family) - + " does not exist in region " + getRegionInfo().getRegionNameAsString()); + + " does not exist in region " + getRegionInfo().getRegionNameAsString()); } if (major) { store.triggerMajorCompaction(); } rsServices.getCompactionRequestor().requestCompaction(this, store, why, priority, tracker, - RpcServer.getRequestUser().orElse(null)); + RpcServer.getRequestUser().orElse(null)); } private void requestFlushIfNeeded() throws RegionTooBusyException { @@ -8839,7 +9335,9 @@ public void requestFlush(FlushLifeCycleTracker tracker) throws IOException { } /** - * This method modifies the region's configuration in order to inject replication-related features + * This method modifies the region's configuration in order to inject + * replication-related features + * * @param conf region configurations */ private static void decorateRegionConfiguration(Configuration conf) { @@ -8848,7 +9346,7 @@ private static void decorateRegionConfiguration(Configuration conf) { String replicationCoprocessorClass = ReplicationObserver.class.getCanonicalName(); if (!plugins.contains(replicationCoprocessorClass)) { conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, - (plugins.equals("") ? "" : (plugins + ",")) + replicationCoprocessorClass); + (plugins.equals("") ? "" : (plugins + ",")) + replicationCoprocessorClass); } } } @@ -8865,8 +9363,7 @@ public void addWriteRequestsCount(long writeRequestsCount) { this.writeRequestsCount.add(writeRequestsCount); } - @RestrictedApi(explanation = "Should only be called in tests", link = "", - allowedOnPath = ".*/src/test/.*") + @RestrictedApi(explanation = "Should only be called in tests", link = "", allowedOnPath = ".*/src/test/.*") boolean isReadsEnabled() { return this.writestate.readsEnabled; } From 6465e6019704d7cf110780ec4599ec3232ffd5cd Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:25:53 +0900 Subject: [PATCH 3/7] Remove exclamation mark in while loop --- .../main/java/org/apache/hadoop/hbase/regionserver/HRegion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 62732f96fa7f..6782061db490 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -4264,7 +4264,7 @@ private static Get toGet(final Mutation mutation) throws IOException { assert mutation instanceof Increment || mutation instanceof Append; Get get = new Get(mutation.getRow()); CellScanner cellScanner = mutation.cellScanner(); - while (!cellScanner.advance()) { + while (cellScanner.advance()) { Cell cell = cellScanner.current(); get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } From 874ba3d5e7cdb39e3c3bef41f48163df89f270ee Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:54:57 +0900 Subject: [PATCH 4/7] Revert "Remove exclamation mark in while loop" This reverts commit 6465e6019704d7cf110780ec4599ec3232ffd5cd. --- .../main/java/org/apache/hadoop/hbase/regionserver/HRegion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 6782061db490..62732f96fa7f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -4264,7 +4264,7 @@ private static Get toGet(final Mutation mutation) throws IOException { assert mutation instanceof Increment || mutation instanceof Append; Get get = new Get(mutation.getRow()); CellScanner cellScanner = mutation.cellScanner(); - while (cellScanner.advance()) { + while (!cellScanner.advance()) { Cell cell = cellScanner.current(); get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } From 9c24bd2ff0a7e38d2fed389fb25a2f0394bb874a Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:56:37 +0900 Subject: [PATCH 5/7] Revert "Rollback 9081a1e0de886fa33f445cf48e6a468571166c24" This reverts commit 11364718fe68893cd5e02d75032ece8d63e1306d. --- .../hadoop/hbase/regionserver/HRegion.java | 3229 +++++++---------- 1 file changed, 1366 insertions(+), 1863 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 62732f96fa7f..4dcf8ab58093 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -222,74 +222,65 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.WALProtos.StoreDescriptor; /** - * Regions store data for a certain region of a table. It stores all columns for - * each row. A given + * Regions store data for a certain region of a table. It stores all columns for each row. A given * table consists of one or more Regions. *

      * An Region is defined by its table and its key extent. *

      - * Locking at the Region level serves only one purpose: preventing the region - * from being closed (and - * consequently split) while other operations are ongoing. Each row level - * operation obtains both a - * row lock and a region read lock for the duration of the operation. While a - * scanner is being - * constructed, getScanner holds a read lock. If the scanner is successfully - * constructed, it holds a - * read lock until it is closed. A close takes out a write lock and consequently - * will block for - * ongoing operations and will block new operations from starting while the - * close is in progress. + * Locking at the Region level serves only one purpose: preventing the region from being closed (and + * consequently split) while other operations are ongoing. Each row level operation obtains both a + * row lock and a region read lock for the duration of the operation. While a scanner is being + * constructed, getScanner holds a read lock. If the scanner is successfully constructed, it holds a + * read lock until it is closed. A close takes out a write lock and consequently will block for + * ongoing operations and will block new operations from starting while the close is in progress. */ @SuppressWarnings("deprecation") @InterfaceAudience.Private public class HRegion implements HeapSize, PropagatingConfigurationObserver, Region { private static final Logger LOG = LoggerFactory.getLogger(HRegion.class); - public static final String LOAD_CFS_ON_DEMAND_CONFIG_KEY = "hbase.hregion.scan.loadColumnFamiliesOnDemand"; + public static final String LOAD_CFS_ON_DEMAND_CONFIG_KEY = + "hbase.hregion.scan.loadColumnFamiliesOnDemand"; public static final String HBASE_MAX_CELL_SIZE_KEY = "hbase.server.keyvalue.maxsize"; public static final int DEFAULT_MAX_CELL_SIZE = 10485760; - public static final String HBASE_REGIONSERVER_MINIBATCH_SIZE = "hbase.regionserver.minibatch.size"; + public static final String HBASE_REGIONSERVER_MINIBATCH_SIZE = + "hbase.regionserver.minibatch.size"; public static final int DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE = 20000; public static final String WAL_HSYNC_CONF_KEY = "hbase.wal.hsync"; public static final boolean DEFAULT_WAL_HSYNC = false; /** Parameter name for compaction after bulkload */ - public static final String COMPACTION_AFTER_BULKLOAD_ENABLE = "hbase.compaction.after.bulkload.enable"; + public static final String COMPACTION_AFTER_BULKLOAD_ENABLE = + "hbase.compaction.after.bulkload.enable"; - /** - * Config for allow split when file count greater than the configured blocking - * file count - */ - public static final String SPLIT_IGNORE_BLOCKING_ENABLED_KEY = "hbase.hregion.split.ignore.blocking.enabled"; + /** Config for allow split when file count greater than the configured blocking file count */ + public static final String SPLIT_IGNORE_BLOCKING_ENABLED_KEY = + "hbase.hregion.split.ignore.blocking.enabled"; public static final String REGION_STORAGE_POLICY_KEY = "hbase.hregion.block.storage.policy"; public static final String DEFAULT_REGION_STORAGE_POLICY = "NONE"; /** - * This is for for using HRegion as a local storage, where we may put the - * recovered edits in a - * special place. Once this is set, we will only replay the recovered edits - * under this directory + * This is for for using HRegion as a local storage, where we may put the recovered edits in a + * special place. Once this is set, we will only replay the recovered edits under this directory * and ignore the original replay directory configs. */ - public static final String SPECIAL_RECOVERED_EDITS_DIR = "hbase.hregion.special.recovered.edits.dir"; + public static final String SPECIAL_RECOVERED_EDITS_DIR = + "hbase.hregion.special.recovered.edits.dir"; /** - * Mainly used for master local region, where we will replay the WAL file - * directly without - * splitting, so it is possible to have WAL files which are not closed cleanly, - * in this way, + * Mainly used for master local region, where we will replay the WAL file directly without + * splitting, so it is possible to have WAL files which are not closed cleanly, in this way, * hitting EOF is expected so should not consider it as a critical problem. */ - public static final String RECOVERED_EDITS_IGNORE_EOF = "hbase.hregion.recovered.edits.ignore.eof"; + public static final String RECOVERED_EDITS_IGNORE_EOF = + "hbase.hregion.recovered.edits.ignore.eof"; /** - * Whether to use {@link MetaCellComparator} even if we are not meta region. - * Used when creating + * Whether to use {@link MetaCellComparator} even if we are not meta region. Used when creating * master local region. */ public static final String USE_META_CELL_COMPARATOR = "hbase.region.use.meta.cell.comparator"; @@ -299,35 +290,28 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi final AtomicBoolean closed = new AtomicBoolean(false); /* - * Closing can take some time; use the closing flag if there is stuff we don't - * want to do while in - * closing state; e.g. like offer this region up to the master as a region to - * close if the + * Closing can take some time; use the closing flag if there is stuff we don't want to do while in + * closing state; e.g. like offer this region up to the master as a region to close if the * carrying regionserver is overloaded. Once set, it is never cleared. */ final AtomicBoolean closing = new AtomicBoolean(false); /** - * The max sequence id of flushed data on this region. There is no edit in - * memory that is less + * The max sequence id of flushed data on this region. There is no edit in memory that is less * that this sequence id. */ private volatile long maxFlushedSeqId = HConstants.NO_SEQNUM; /** - * Record the sequence id of last flush operation. Can be in advance of - * {@link #maxFlushedSeqId} - * when flushing a single column family. In this case, {@link #maxFlushedSeqId} - * will be older than + * Record the sequence id of last flush operation. Can be in advance of {@link #maxFlushedSeqId} + * when flushing a single column family. In this case, {@link #maxFlushedSeqId} will be older than * the oldest edit in memory. */ private volatile long lastFlushOpSeqId = HConstants.NO_SEQNUM; /** - * The sequence id of the last replayed open region event from the primary - * region. This is used to - * skip entries before this due to the possibility of replay edits coming out of - * order from + * The sequence id of the last replayed open region event from the primary region. This is used to + * skip entries before this due to the possibility of replay edits coming out of order from * replication. */ protected volatile long lastReplayedOpenRegionSeqId = -1L; @@ -342,9 +326,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi // - the thread that owns the lock (allow reentrancy) // - reference count of (reentrant) locks held by the thread // - the row itself - private final ConcurrentHashMap lockedRows = new ConcurrentHashMap<>(); + private final ConcurrentHashMap lockedRows = + new ConcurrentHashMap<>(); - protected final Map stores = new ConcurrentSkipListMap<>(Bytes.BYTES_RAWCOMPARATOR); + protected final Map stores = + new ConcurrentSkipListMap<>(Bytes.BYTES_RAWCOMPARATOR); // TODO: account for each registered handler in HeapSize computation private Map coprocessorServiceHandlers = Maps.newHashMap(); @@ -392,8 +378,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi private Path regionWalDir; private FileSystem walFS; - // set to true if the region is restored from snapshot for reading by - // ClientSideRegionScanner + // set to true if the region is restored from snapshot for reading by ClientSideRegionScanner private boolean isRestoredRegion = false; public void setRestoredRegion(boolean restoredRegion) { @@ -441,8 +426,7 @@ public MetricsTableRequests getMetricsTableRequests() { private long openSeqNum = HConstants.NO_SEQNUM; /** - * The default setting for whether to enable on-demand CF loading for scan - * requests to this + * The default setting for whether to enable on-demand CF loading for scan requests to this * region. Requests can override it. */ private boolean isLoadingCfsOnDemandDefault = false; @@ -458,8 +442,7 @@ public MetricsTableRequests getMetricsTableRequests() { // The following map is populated when opening the region Map maxSeqIdInStores = new TreeMap<>(Bytes.BYTES_COMPARATOR); - // lock used to protect the replay operation for secondary replicas, so the - // below two fields does + // lock used to protect the replay operation for secondary replicas, so the below two fields does // not need to be volatile. private Lock replayLock; @@ -478,8 +461,7 @@ public MetricsTableRequests getMetricsTableRequests() { private final int minBlockSizeBytes; /** - * @return The smallest mvcc readPoint across all the scanners in this region. - * Writes older than + * @return The smallest mvcc readPoint across all the scanners in this region. Writes older than * this readPoint, are included in every read operation. */ public long getSmallestReadPoint() { @@ -498,8 +480,7 @@ public long getSmallestReadPoint() { } /* - * Data structure of write state flags used coordinating flushes, compactions - * and closes. + * Data structure of write state flags used coordinating flushes, compactions and closes. */ static class WriteState { // Set while a memstore flush is happening. @@ -512,14 +493,12 @@ static class WriteState { volatile boolean writesEnabled = true; // Set if region is read-only volatile boolean readOnly = false; - // whether the reads are enabled. This is different than readOnly, because - // readOnly is + // whether the reads are enabled. This is different than readOnly, because readOnly is // static in the lifetime of the region, while readsEnabled is dynamic volatile boolean readsEnabled = true; /** * Set flags that make this region read-only. - * * @param onOff flip value for region r/o setting */ synchronized void setReadOnly(final boolean onOff) { @@ -543,12 +522,9 @@ void setReadsEnabled(boolean readsEnabled) { } /** - * Objects from this class are created when flushing to describe all the - * different states that - * that method ends up in. The Result enum describes those states. The sequence - * id should only be - * specified if the flush was successful, and the failure message should only be - * specified if it + * Objects from this class are created when flushing to describe all the different states that + * that method ends up in. The Result enum describes those states. The sequence id should only be + * specified if the flush was successful, and the failure message should only be specified if it * didn't flush. */ public static class FlushResultImpl implements FlushResult { @@ -558,25 +534,20 @@ public static class FlushResultImpl implements FlushResult { final boolean wroteFlushWalMarker; /** - * Convenience constructor to use when the flush is successful, the failure - * message is set to + * Convenience constructor to use when the flush is successful, the failure message is set to * null. - * - * @param result Expecting FLUSHED_NO_COMPACTION_NEEDED or - * FLUSHED_COMPACTION_NEEDED. - * @param flushSequenceId Generated sequence id that comes right after the edits - * in the + * @param result Expecting FLUSHED_NO_COMPACTION_NEEDED or FLUSHED_COMPACTION_NEEDED. + * @param flushSequenceId Generated sequence id that comes right after the edits in the * memstores. */ FlushResultImpl(Result result, long flushSequenceId) { this(result, flushSequenceId, null, false); assert result == Result.FLUSHED_NO_COMPACTION_NEEDED - || result == Result.FLUSHED_COMPACTION_NEEDED; + || result == Result.FLUSHED_COMPACTION_NEEDED; } /** * Convenience constructor to use when we cannot flush. - * * @param result Expecting CANNOT_FLUSH_MEMSTORE_EMPTY or CANNOT_FLUSH. * @param failureReason Reason why we couldn't flush. */ @@ -587,14 +558,12 @@ public static class FlushResultImpl implements FlushResult { /** * Constructor with all the parameters. - * * @param result Any of the Result. - * @param flushSequenceId Generated sequence id if the memstores were flushed - * else -1. + * @param flushSequenceId Generated sequence id if the memstores were flushed else -1. * @param failureReason Reason why we couldn't flush, or null. */ FlushResultImpl(Result result, long flushSequenceId, String failureReason, - boolean wroteFlushMarker) { + boolean wroteFlushMarker) { this.result = result; this.flushSequenceId = flushSequenceId; this.failureReason = failureReason; @@ -602,24 +571,19 @@ public static class FlushResultImpl implements FlushResult { } /** - * Convenience method, the equivalent of checking if result is - * FLUSHED_NO_COMPACTION_NEEDED or + * Convenience method, the equivalent of checking if result is FLUSHED_NO_COMPACTION_NEEDED or * FLUSHED_NO_COMPACTION_NEEDED. - * * @return true if the memstores were flushed, else false. */ @Override public boolean isFlushSucceeded() { return result == Result.FLUSHED_NO_COMPACTION_NEEDED - || result == Result.FLUSHED_COMPACTION_NEEDED; + || result == Result.FLUSHED_COMPACTION_NEEDED; } /** - * Convenience method, the equivalent of checking if result is - * FLUSHED_COMPACTION_NEEDED. - * - * @return True if the flush requested a compaction, else false (doesn't even - * mean it flushed). + * Convenience method, the equivalent of checking if result is FLUSHED_COMPACTION_NEEDED. + * @return True if the flush requested a compaction, else false (doesn't even mean it flushed). */ @Override public boolean isCompactionNeeded() { @@ -629,8 +593,8 @@ public boolean isCompactionNeeded() { @Override public String toString() { return new StringBuilder().append("flush result:").append(result).append(", ") - .append("failureReason:").append(failureReason).append(",").append("flush seq id") - .append(flushSequenceId).toString(); + .append("failureReason:").append(failureReason).append(",").append("flush seq id") + .append(flushSequenceId).toString(); } @Override @@ -657,16 +621,16 @@ protected static class PrepareFlushResult { /** Constructs a successful prepare flush result */ PrepareFlushResult(TreeMap storeFlushCtxs, - TreeMap> committedFiles, TreeMap storeFlushableSize, - long startTime, long flushSeqId, long flushedSeqId, MemStoreSizing totalFlushableSize) { + TreeMap> committedFiles, TreeMap storeFlushableSize, + long startTime, long flushSeqId, long flushedSeqId, MemStoreSizing totalFlushableSize) { this(null, storeFlushCtxs, committedFiles, storeFlushableSize, startTime, flushSeqId, - flushedSeqId, totalFlushableSize); + flushedSeqId, totalFlushableSize); } private PrepareFlushResult(FlushResultImpl result, - TreeMap storeFlushCtxs, TreeMap> committedFiles, - TreeMap storeFlushableSize, long startTime, long flushSeqId, - long flushedSeqId, MemStoreSizing totalFlushableSize) { + TreeMap storeFlushCtxs, TreeMap> committedFiles, + TreeMap storeFlushableSize, long startTime, long flushSeqId, + long flushedSeqId, MemStoreSizing totalFlushableSize) { this.result = result; this.storeFlushCtxs = storeFlushCtxs; this.committedFiles = committedFiles; @@ -683,8 +647,7 @@ public FlushResult getResult() { } /** - * A class that tracks exceptions that have been observed in one batch. Not - * thread safe. + * A class that tracks exceptions that have been observed in one batch. Not thread safe. */ static class ObservedExceptionsInBatch { private boolean wrongRegion = false; @@ -744,10 +707,8 @@ void sawNoSuchFamily() { private long blockingMemStoreSize; // Used to guard closes final ReentrantReadWriteLock lock; - // Used to track interruptible holders of the region lock. Currently that is - // only RPC handler - // threads. Boolean value in map determines if lock holder can be interrupted, - // normally true, + // Used to track interruptible holders of the region lock. Currently that is only RPC handler + // threads. Boolean value in map determines if lock holder can be interrupted, normally true, // but may be false when thread is transiting a critical section. final ConcurrentHashMap regionLockHolders; @@ -770,34 +731,27 @@ void sawNoSuchFamily() { private final boolean regionStatsEnabled; // Stores the replication scope of the various column families of the table // that has non-default scope - private final NavigableMap replicationScope = new TreeMap<>(Bytes.BYTES_COMPARATOR); + private final NavigableMap replicationScope = + new TreeMap<>(Bytes.BYTES_COMPARATOR); private final StoreHotnessProtector storeHotnessProtector; protected Optional regionReplicationSink = Optional.empty(); /** - * HRegion constructor. This constructor should only be used for testing and - * extensions. Instances + * HRegion constructor. This constructor should only be used for testing and extensions. Instances * of HRegion should be instantiated with the {@link HRegion#createHRegion} or * {@link HRegion#openHRegion} method. - * - * @param tableDir qualified path of directory where region should be located, - * usually the table + * @param tableDir qualified path of directory where region should be located, usually the table * directory. - * @param wal The WAL is the outbound log for any updates to the HRegion - * The wal file is a - * logfile from the previous execution that's custom-computed - * for this HRegion. - * The HRegionServer computes and sorts the appropriate wal - * info for this - * HRegion. If there is a previous wal file (implying that the - * HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a + * logfile from the previous execution that's custom-computed for this HRegion. + * The HRegionServer computes and sorts the appropriate wal info for this + * HRegion. If there is a previous wal file (implying that the HRegion has been * written-to before), then read it from the supplied path. * @param fs is the filesystem. * @param confParam is global configuration settings. - * @param regionInfo - RegionInfo that describes the region is new), then read - * them from the + * @param regionInfo - RegionInfo that describes the region is new), then read them from the * supplied path. * @param htd the table descriptor * @param rsServices reference to {@link RegionServerServices} or null @@ -805,34 +759,28 @@ void sawNoSuchFamily() { */ @Deprecated public HRegion(final Path tableDir, final WAL wal, final FileSystem fs, - final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd, - final RegionServerServices rsServices) { + final Configuration confParam, final RegionInfo regionInfo, final TableDescriptor htd, + final RegionServerServices rsServices) { this(new HRegionFileSystem(confParam, fs, tableDir, regionInfo), wal, confParam, htd, - rsServices); + rsServices); } /** - * HRegion constructor. This constructor should only be used for testing and - * extensions. Instances + * HRegion constructor. This constructor should only be used for testing and extensions. Instances * of HRegion should be instantiated with the {@link HRegion#createHRegion} or * {@link HRegion#openHRegion} method. - * * @param fs is the filesystem. - * @param wal The WAL is the outbound log for any updates to the HRegion - * The wal file is a - * logfile from the previous execution that's custom-computed - * for this HRegion. - * The HRegionServer computes and sorts the appropriate wal - * info for this - * HRegion. If there is a previous wal file (implying that the - * HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a + * logfile from the previous execution that's custom-computed for this HRegion. + * The HRegionServer computes and sorts the appropriate wal info for this + * HRegion. If there is a previous wal file (implying that the HRegion has been * written-to before), then read it from the supplied path. * @param confParam is global configuration settings. * @param htd the table descriptor * @param rsServices reference to {@link RegionServerServices} or null */ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration confParam, - final TableDescriptor htd, final RegionServerServices rsServices) { + final TableDescriptor htd, final RegionServerServices rsServices) { if (htd == null) { throw new IllegalArgumentException("Need table descriptor"); } @@ -849,22 +797,24 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co this.baseConf = confParam; this.conf = new CompoundConfiguration().add(confParam).addBytesMap(htd.getValues()); this.cellComparator = htd.isMetaTable() - || conf.getBoolean(USE_META_CELL_COMPARATOR, DEFAULT_USE_META_CELL_COMPARATOR) - ? MetaCellComparator.META_COMPARATOR - : CellComparatorImpl.COMPARATOR; + || conf.getBoolean(USE_META_CELL_COMPARATOR, DEFAULT_USE_META_CELL_COMPARATOR) + ? MetaCellComparator.META_COMPARATOR + : CellComparatorImpl.COMPARATOR; this.lock = new ReentrantReadWriteLock( - conf.getBoolean(FAIR_REENTRANT_CLOSE_LOCK, DEFAULT_FAIR_REENTRANT_CLOSE_LOCK)); + conf.getBoolean(FAIR_REENTRANT_CLOSE_LOCK, DEFAULT_FAIR_REENTRANT_CLOSE_LOCK)); this.regionLockHolders = new ConcurrentHashMap<>(); - this.flushCheckInterval = conf.getInt(MEMSTORE_PERIODIC_FLUSH_INTERVAL, DEFAULT_CACHE_FLUSH_INTERVAL); + this.flushCheckInterval = + conf.getInt(MEMSTORE_PERIODIC_FLUSH_INTERVAL, DEFAULT_CACHE_FLUSH_INTERVAL); this.flushPerChanges = conf.getLong(MEMSTORE_FLUSH_PER_CHANGES, DEFAULT_FLUSH_PER_CHANGES); if (this.flushPerChanges > MAX_FLUSH_PER_CHANGES) { throw new IllegalArgumentException( - MEMSTORE_FLUSH_PER_CHANGES + " can not exceed " + MAX_FLUSH_PER_CHANGES); + MEMSTORE_FLUSH_PER_CHANGES + " can not exceed " + MAX_FLUSH_PER_CHANGES); } - int tmpRowLockDuration = conf.getInt("hbase.rowlock.wait.duration", DEFAULT_ROWLOCK_WAIT_DURATION); + int tmpRowLockDuration = + conf.getInt("hbase.rowlock.wait.duration", DEFAULT_ROWLOCK_WAIT_DURATION); if (tmpRowLockDuration <= 0) { LOG.info("Found hbase.rowlock.wait.duration set to {}. values <= 0 will cause all row " - + "locking to fail. Treating it as 1ms to avoid region failure.", tmpRowLockDuration); + + "locking to fail. Treating it as 1ms to avoid region failure.", tmpRowLockDuration); tmpRowLockDuration = 1; } this.rowLockWaitDuration = tmpRowLockDuration; @@ -899,35 +849,32 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co this.maxBusyWaitMultiplier = conf.getInt("hbase.busy.wait.multiplier.max", 2); if (busyWaitDuration * maxBusyWaitMultiplier <= 0L) { throw new IllegalArgumentException("Invalid hbase.busy.wait.duration (" + busyWaitDuration - + ") or hbase.busy.wait.multiplier.max (" + maxBusyWaitMultiplier - + "). Their product should be positive"); + + ") or hbase.busy.wait.multiplier.max (" + maxBusyWaitMultiplier + + "). Their product should be positive"); } - this.maxBusyWaitDuration = conf.getLong("hbase.ipc.client.call.purge.timeout", - 2 * HConstants.DEFAULT_HBASE_RPC_TIMEOUT); + this.maxBusyWaitDuration = + conf.getLong("hbase.ipc.client.call.purge.timeout", 2 * HConstants.DEFAULT_HBASE_RPC_TIMEOUT); /* - * timestamp.slop provides a server-side constraint on the timestamp. This - * assumes that you base - * your TS around EnvironmentEdgeManager.currentTime(). In this case, throw an - * error to the user - * if the user-specified TS is newer than now + slop. LATEST_TIMESTAMP == don't - * use this + * timestamp.slop provides a server-side constraint on the timestamp. This assumes that you base + * your TS around EnvironmentEdgeManager.currentTime(). In this case, throw an error to the user + * if the user-specified TS is newer than now + slop. LATEST_TIMESTAMP == don't use this * functionality */ - this.timestampSlop = conf.getLong("hbase.hregion.keyvalue.timestamp.slop.millisecs", HConstants.LATEST_TIMESTAMP); + this.timestampSlop = + conf.getLong("hbase.hregion.keyvalue.timestamp.slop.millisecs", HConstants.LATEST_TIMESTAMP); this.storeHotnessProtector = new StoreHotnessProtector(this, conf); boolean forceSync = conf.getBoolean(WAL_HSYNC_CONF_KEY, DEFAULT_WAL_HSYNC); /** - * This is the global default value for durability. All tables/mutations not - * defining a + * This is the global default value for durability. All tables/mutations not defining a * durability or using USE_DEFAULT will default to this value. */ Durability defaultDurability = forceSync ? Durability.FSYNC_WAL : Durability.SYNC_WAL; this.regionDurability = this.htableDescriptor.getDurability() == Durability.USE_DEFAULT - ? defaultDurability - : this.htableDescriptor.getDurability(); + ? defaultDurability + : this.htableDescriptor.getDurability(); decorateRegionConfiguration(conf); if (rsServices != null) { @@ -948,32 +895,32 @@ public HRegion(final HRegionFileSystem fs, final WAL wal, final Configuration co configurationManager = null; - // disable stats tracking system tables, but check the config for everything - // else + // disable stats tracking system tables, but check the config for everything else this.regionStatsEnabled = htd.getTableName().getNamespaceAsString() - .equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) - ? false - : conf.getBoolean(HConstants.ENABLE_CLIENT_BACKPRESSURE, - HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE); + .equals(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR) + ? false + : conf.getBoolean(HConstants.ENABLE_CLIENT_BACKPRESSURE, + HConstants.DEFAULT_ENABLE_CLIENT_BACKPRESSURE); this.maxCellSize = conf.getLong(HBASE_MAX_CELL_SIZE_KEY, DEFAULT_MAX_CELL_SIZE); - this.miniBatchSize = conf.getInt(HBASE_REGIONSERVER_MINIBATCH_SIZE, DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE); + this.miniBatchSize = + conf.getInt(HBASE_REGIONSERVER_MINIBATCH_SIZE, DEFAULT_HBASE_REGIONSERVER_MINIBATCH_SIZE); // recover the metrics of read and write requests count if they were retained if (rsServices != null && rsServices.getRegionServerAccounting() != null) { Pair retainedRWRequestsCnt = rsServices.getRegionServerAccounting() - .getRetainedRegionRWRequestsCnt().get(getRegionInfo().getEncodedName()); + .getRetainedRegionRWRequestsCnt().get(getRegionInfo().getEncodedName()); if (retainedRWRequestsCnt != null) { this.addReadRequestsCount(retainedRWRequestsCnt.getFirst()); this.addWriteRequestsCount(retainedRWRequestsCnt.getSecond()); // remove them since won't use again rsServices.getRegionServerAccounting().getRetainedRegionRWRequestsCnt() - .remove(getRegionInfo().getEncodedName()); + .remove(getRegionInfo().getEncodedName()); } } minBlockSizeBytes = Arrays.stream(this.htableDescriptor.getColumnFamilies()) - .mapToInt(ColumnFamilyDescriptor::getBlocksize).min().orElse(HConstants.DEFAULT_BLOCKSIZE); + .mapToInt(ColumnFamilyDescriptor::getBlocksize).min().orElse(HConstants.DEFAULT_BLOCKSIZE); } private void setHTableSpecificConf() { @@ -984,19 +931,17 @@ private void setHTableSpecificConf() { if (flushSize <= 0) { flushSize = conf.getLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, - TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE); + TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE); } this.memstoreFlushSize = flushSize; long mult = conf.getLong(HConstants.HREGION_MEMSTORE_BLOCK_MULTIPLIER, - HConstants.DEFAULT_HREGION_MEMSTORE_BLOCK_MULTIPLIER); + HConstants.DEFAULT_HREGION_MEMSTORE_BLOCK_MULTIPLIER); this.blockingMemStoreSize = this.memstoreFlushSize * mult; } /** - * Initialize this region. Used only by tests and SplitTransaction to reopen the - * region. You + * Initialize this region. Used only by tests and SplitTransaction to reopen the region. You * should use createHRegion() or openHRegion() - * * @return What the next sequence (edit) id should be. * @throws IOException e * @deprecated use HRegion.createHRegion() or HRegion.openHRegion() @@ -1008,7 +953,6 @@ public long initialize() throws IOException { /** * Initialize this region. - * * @param reporter Tickle every so often if initialize is taking a while. * @return What the next sequence (edit) id should be. */ @@ -1017,17 +961,18 @@ long initialize(final CancelableProgressable reporter) throws IOException { // Refuse to open the region if there is no column family in the table if (htableDescriptor.getColumnFamilyCount() == 0) { throw new DoNotRetryIOException("Table " + htableDescriptor.getTableName().getNameAsString() - + " should have at least one column family."); + + " should have at least one column family."); } - MonitoredTask status = TaskMonitor.get().createStatus("Initializing region " + this, false, true); + MonitoredTask status = + TaskMonitor.get().createStatus("Initializing region " + this, false, true); long nextSeqId = -1; try { nextSeqId = initializeRegionInternals(reporter, status); return nextSeqId; } catch (IOException e) { LOG.warn("Failed initialize of region= {}, starting to roll back memstore", - getRegionInfo().getRegionNameAsString(), e); + getRegionInfo().getRegionNameAsString(), e); // global memstore size will be decreased when dropping memstore try { // drop the memory used by memstore if open region fails @@ -1035,9 +980,9 @@ long initialize(final CancelableProgressable reporter) throws IOException { } catch (IOException ioE) { if (conf.getBoolean(MemStoreLAB.USEMSLAB_KEY, MemStoreLAB.USEMSLAB_DEFAULT)) { LOG.warn( - "Failed drop memstore of region= {}, " - + "some chunks may not released forever since MSLAB is enabled", - getRegionInfo().getRegionNameAsString()); + "Failed drop memstore of region= {}, " + + "some chunks may not released forever since MSLAB is enabled", + getRegionInfo().getRegionNameAsString()); } } @@ -1050,18 +995,18 @@ long initialize(final CancelableProgressable reporter) throws IOException { // At least it will be 0 otherwise. if (nextSeqId == -1) { status.abort("Exception during region " + getRegionInfo().getRegionNameAsString() - + " initialization."); + + " initialization."); } if (LOG.isDebugEnabled()) { LOG.debug("Region open journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } } private long initializeRegionInternals(final CancelableProgressable reporter, - final MonitoredTask status) throws IOException { + final MonitoredTask status) throws IOException { if (coprocessorHost != null) { status.setStatus("Running coprocessor pre-open hook"); coprocessorHost.preOpen(); @@ -1088,7 +1033,8 @@ private long initializeRegionInternals(final CancelableProgressable reporter, LOG.debug("replaying wal for " + this.getRegionInfo().getEncodedName()); stores.forEach(HStore::startReplayingFromWAL); // Recover any edits if available. - maxSeqId = Math.max(maxSeqId, replayRecoveredEditsIfAny(maxSeqIdInStores, reporter, status)); + maxSeqId = + Math.max(maxSeqId, replayRecoveredEditsIfAny(maxSeqIdInStores, reporter, status)); // Recover any hfiles if available maxSeqId = Math.max(maxSeqId, loadRecoveredHFilesIfAny(stores)); // Make sure mvcc is up to max. @@ -1130,28 +1076,23 @@ private long initializeRegionInternals(final CancelableProgressable reporter, // (particularly if no recovered edits, seqid will be -1). long nextSeqId = maxSeqId + 1; if (!isRestoredRegion) { - // always get openSeqNum from the default replica, even if we are secondary - // replicas + // always get openSeqNum from the default replica, even if we are secondary replicas long maxSeqIdFromFile = WALSplitUtil.getMaxRegionSequenceId(conf, - RegionReplicaUtil.getRegionInfoForDefaultReplica(getRegionInfo()), this::getFilesystem, - this::getWalFileSystem); + RegionReplicaUtil.getRegionInfoForDefaultReplica(getRegionInfo()), this::getFilesystem, + this::getWalFileSystem); nextSeqId = Math.max(maxSeqId, maxSeqIdFromFile) + 1; - // The openSeqNum will always be increase even for read only region, as we rely - // on it to - // determine whether a region has been successfully reopened, so here we always - // need to update + // The openSeqNum will always be increase even for read only region, as we rely on it to + // determine whether a region has been successfully reopened, so here we always need to update // the max sequence id file. if (RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { LOG.debug("writing seq id for {}", this.getRegionInfo().getEncodedName()); WALSplitUtil.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), - nextSeqId - 1); - // This means we have replayed all the recovered edits and also written out the - // max sequence - // id file, let's delete the wrong directories introduced in HBASE-20734, see - // HBASE-22617 + nextSeqId - 1); + // This means we have replayed all the recovered edits and also written out the max sequence + // id file, let's delete the wrong directories introduced in HBASE-20734, see HBASE-22617 // for more details. Path wrongRegionWALDir = CommonFSUtils.getWrongWALRegionDir(conf, - getRegionInfo().getTable(), getRegionInfo().getEncodedName()); + getRegionInfo().getTable(), getRegionInfo().getEncodedName()); FileSystem walFs = getWalFileSystem(); if (walFs.exists(wrongRegionWALDir)) { if (!walFs.delete(wrongRegionWALDir, true)) { @@ -1166,7 +1107,7 @@ private long initializeRegionInternals(final CancelableProgressable reporter, } LOG.info("Opened {}; next sequenceid={}; {}, {}", this.getRegionInfo().getShortNameToLog(), - nextSeqId, this.splitPolicy, this.flushPolicy); + nextSeqId, this.splitPolicy, this.flushPolicy); // A region can be reopened if failed a split; reset flags this.closing.set(false); @@ -1185,36 +1126,37 @@ private long initializeRegionInternals(final CancelableProgressable reporter, } private void initializeRegionReplicationSink(CancelableProgressable reporter, - MonitoredTask status) { + MonitoredTask status) { RegionServerServices rss = getRegionServerServices(); TableDescriptor td = getTableDescriptor(); int regionReplication = td.getRegionReplication(); RegionInfo regionInfo = getRegionInfo(); - if (regionReplication <= 1 || !RegionReplicaUtil.isDefaultReplica(regionInfo) + if ( + regionReplication <= 1 || !RegionReplicaUtil.isDefaultReplica(regionInfo) || !ServerRegionReplicaUtil.isRegionReplicaReplicationEnabled(conf, regionInfo.getTable()) - || rss == null) { + || rss == null + ) { regionReplicationSink = Optional.empty(); return; } status.setStatus("Initializaing region replication sink"); regionReplicationSink = Optional.of(new RegionReplicationSink(conf, regionInfo, td, - rss.getRegionReplicationBufferManager(), () -> rss.getFlushRequester().requestFlush(this, - new ArrayList<>(td.getColumnFamilyNames()), FlushLifeCycleTracker.DUMMY), - rss.getAsyncClusterConnection())); + rss.getRegionReplicationBufferManager(), () -> rss.getFlushRequester().requestFlush(this, + new ArrayList<>(td.getColumnFamilyNames()), FlushLifeCycleTracker.DUMMY), + rss.getAsyncClusterConnection())); } /** * Open all Stores. - * * @return Highest sequenceId found out in a Store. */ private long initializeStores(CancelableProgressable reporter, MonitoredTask status) - throws IOException { + throws IOException { return initializeStores(reporter, status, false); } private long initializeStores(CancelableProgressable reporter, MonitoredTask status, - boolean warmup) throws IOException { + boolean warmup) throws IOException { // Load in all the HStores. long maxSeqId = -1; // initialized to -1 so that we pick up MemstoreTS from column families @@ -1222,9 +1164,10 @@ private long initializeStores(CancelableProgressable reporter, MonitoredTask sta if (htableDescriptor.getColumnFamilyCount() != 0) { // initialize the thread pool for opening stores in parallel. - ThreadPoolExecutor storeOpenerThreadPool = getStoreOpenAndCloseThreadPool( - "StoreOpener-" + this.getRegionInfo().getShortNameToLog()); - CompletionService completionService = new ExecutorCompletionService<>(storeOpenerThreadPool); + ThreadPoolExecutor storeOpenerThreadPool = + getStoreOpenAndCloseThreadPool("StoreOpener-" + this.getRegionInfo().getShortNameToLog()); + CompletionService completionService = + new ExecutorCompletionService<>(storeOpenerThreadPool); // initialize each store in parallel for (final ColumnFamilyDescriptor family : htableDescriptor.getColumnFamilies()) { @@ -1260,7 +1203,7 @@ public HStore call() throws IOException { allStoresOpened = true; if (hasSloppyStores) { htableDescriptor = TableDescriptorBuilder.newBuilder(htableDescriptor) - .setFlushPolicyClassName(FlushNonSloppyStoresFirstPolicy.class.getName()).build(); + .setFlushPolicyClassName(FlushNonSloppyStoresFirstPolicy.class.getName()).build(); LOG.info("Setting FlushNonSloppyStoresFirstPolicy for the region=" + this); } } catch (InterruptedException e) { @@ -1315,31 +1258,29 @@ private NavigableMap> getStoreFiles() { protected void writeRegionOpenMarker(WAL wal, long openSeqId) throws IOException { Map> storeFiles = getStoreFiles(); - RegionEventDescriptor regionOpenDesc = ProtobufUtil.toRegionEventDescriptor( - RegionEventDescriptor.EventType.REGION_OPEN, + RegionEventDescriptor regionOpenDesc = + ProtobufUtil.toRegionEventDescriptor(RegionEventDescriptor.EventType.REGION_OPEN, getRegionInfo(), openSeqId, getRegionServerServices().getServerName(), storeFiles); WALUtil.writeRegionEventMarker(wal, getReplicationScope(), getRegionInfo(), regionOpenDesc, - mvcc, regionReplicationSink.orElse(null)); + mvcc, regionReplicationSink.orElse(null)); } private void writeRegionCloseMarker(WAL wal) throws IOException { Map> storeFiles = getStoreFiles(); RegionEventDescriptor regionEventDesc = ProtobufUtil.toRegionEventDescriptor( - RegionEventDescriptor.EventType.REGION_CLOSE, getRegionInfo(), mvcc.getReadPoint(), - getRegionServerServices().getServerName(), storeFiles); - // we do not care region close event at secondary replica side so just pass a - // null + RegionEventDescriptor.EventType.REGION_CLOSE, getRegionInfo(), mvcc.getReadPoint(), + getRegionServerServices().getServerName(), storeFiles); + // we do not care region close event at secondary replica side so just pass a null // RegionReplicationSink WALUtil.writeRegionEventMarker(wal, getReplicationScope(), getRegionInfo(), regionEventDesc, - mvcc, null); + mvcc, null); // Store SeqId in WAL FileSystem when a region closes - // checking region folder exists is due to many tests which delete the table - // folder while a + // checking region folder exists is due to many tests which delete the table folder while a // table is still online if (getWalFileSystem().exists(getWALRegionDir())) { WALSplitUtil.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), - mvcc.getReadPoint()); + mvcc.getReadPoint()); } } @@ -1359,28 +1300,27 @@ public void unblockUpdates() { public HDFSBlocksDistribution getHDFSBlocksDistribution() { HDFSBlocksDistribution hdfsBlocksDistribution = new HDFSBlocksDistribution(); stores.values().stream().filter(s -> s.getStorefiles() != null) - .flatMap(s -> s.getStorefiles().stream()).map(HStoreFile::getHDFSBlockDistribution) - .forEachOrdered(hdfsBlocksDistribution::add); + .flatMap(s -> s.getStorefiles().stream()).map(HStoreFile::getHDFSBlockDistribution) + .forEachOrdered(hdfsBlocksDistribution::add); return hdfsBlocksDistribution; } /** * This is a helper function to compute HDFS block distribution on demand - * * @param conf configuration * @param tableDescriptor TableDescriptor of the table * @param regionInfo encoded name of the region * @return The HDFS blocks distribution for the given region. */ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf, - TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException { - Path tablePath = CommonFSUtils.getTableDir(CommonFSUtils.getRootDir(conf), tableDescriptor.getTableName()); + TableDescriptor tableDescriptor, RegionInfo regionInfo) throws IOException { + Path tablePath = + CommonFSUtils.getTableDir(CommonFSUtils.getRootDir(conf), tableDescriptor.getTableName()); return computeHDFSBlocksDistribution(conf, tableDescriptor, regionInfo, tablePath); } /** * This is a helper function to compute HDFS block distribution on demand - * * @param conf configuration * @param tableDescriptor TableDescriptor of the table * @param regionInfo encoded name of the region @@ -1388,14 +1328,14 @@ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration * @return The HDFS blocks distribution for the given region. */ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration conf, - TableDescriptor tableDescriptor, RegionInfo regionInfo, Path tablePath) throws IOException { + TableDescriptor tableDescriptor, RegionInfo regionInfo, Path tablePath) throws IOException { HDFSBlocksDistribution hdfsBlocksDistribution = new HDFSBlocksDistribution(); FileSystem fs = tablePath.getFileSystem(conf); HRegionFileSystem regionFs = new HRegionFileSystem(conf, fs, tablePath, regionInfo); for (ColumnFamilyDescriptor family : tableDescriptor.getColumnFamilies()) { - List locatedFileStatusList = HRegionFileSystem.getStoreFilesLocatedStatus(regionFs, - family.getNameAsString(), true); + List locatedFileStatusList = + HRegionFileSystem.getStoreFilesLocatedStatus(regionFs, family.getNameAsString(), true); if (locatedFileStatusList == null) { continue; } @@ -1420,48 +1360,45 @@ public static HDFSBlocksDistribution computeHDFSBlocksDistribution(Configuration } /** - * Increase the size of mem store in this region and the size of global mem - * store + * Increase the size of mem store in this region and the size of global mem store */ private void incMemStoreSize(MemStoreSize mss) { incMemStoreSize(mss.getDataSize(), mss.getHeapSize(), mss.getOffHeapSize(), - mss.getCellsCount()); + mss.getCellsCount()); } void incMemStoreSize(long dataSizeDelta, long heapSizeDelta, long offHeapSizeDelta, - int cellsCountDelta) { + int cellsCountDelta) { if (this.rsAccounting != null) { rsAccounting.incGlobalMemStoreSize(dataSizeDelta, heapSizeDelta, offHeapSizeDelta); } long dataSize = this.memStoreSizing.incMemStoreSize(dataSizeDelta, heapSizeDelta, - offHeapSizeDelta, cellsCountDelta); + offHeapSizeDelta, cellsCountDelta); checkNegativeMemStoreDataSize(dataSize, dataSizeDelta); } void decrMemStoreSize(MemStoreSize mss) { decrMemStoreSize(mss.getDataSize(), mss.getHeapSize(), mss.getOffHeapSize(), - mss.getCellsCount()); + mss.getCellsCount()); } private void decrMemStoreSize(long dataSizeDelta, long heapSizeDelta, long offHeapSizeDelta, - int cellsCountDelta) { + int cellsCountDelta) { if (this.rsAccounting != null) { rsAccounting.decGlobalMemStoreSize(dataSizeDelta, heapSizeDelta, offHeapSizeDelta); } long dataSize = this.memStoreSizing.decMemStoreSize(dataSizeDelta, heapSizeDelta, - offHeapSizeDelta, cellsCountDelta); + offHeapSizeDelta, cellsCountDelta); checkNegativeMemStoreDataSize(dataSize, -dataSizeDelta); } private void checkNegativeMemStoreDataSize(long memStoreDataSize, long delta) { - // This is extremely bad if we make memStoreSizing negative. Log as much info on - // the offending - // caller as possible. (memStoreSizing might be a negative value already -- - // freeing memory) + // This is extremely bad if we make memStoreSizing negative. Log as much info on the offending + // caller as possible. (memStoreSizing might be a negative value already -- freeing memory) if (memStoreDataSize < 0) { LOG.error("Asked to modify this region's (" + this.toString() - + ") memStoreSizing to a negative value which is incorrect. Current memStoreSizing=" - + (memStoreDataSize - delta) + ", delta=" + delta, new Exception()); + + ") memStoreSizing to a negative value which is incorrect. Current memStoreSizing=" + + (memStoreDataSize - delta) + ", delta=" + delta, new Exception()); } } @@ -1471,8 +1408,7 @@ public RegionInfo getRegionInfo() { } /** - * Returns Instance of {@link RegionServerServices} used by this HRegion. Can be - * null. + * Returns Instance of {@link RegionServerServices} used by this HRegion. Can be null. */ RegionServerServices getRegionServerServices() { return this.rsServices; @@ -1513,10 +1449,7 @@ public long getMemStoreOffHeapSize() { return memStoreSizing.getOffHeapSize(); } - /** - * Returns store services for this region, to access services required by store - * level needs - */ + /** Returns store services for this region, to access services required by store level needs */ public RegionServicesForStores getRegionServicesForStores() { return regionServicesForStores; } @@ -1546,10 +1479,8 @@ public long getCheckAndMutateChecksFailed() { return checkAndMutateChecksFailed.sum(); } - // TODO Needs to check whether we should expose our metrics system to CPs. If - // CPs themselves doing - // the op and bypassing the core, this might be needed? Should be stop - // supporting the bypass + // TODO Needs to check whether we should expose our metrics system to CPs. If CPs themselves doing + // the op and bypassing the core, this might be needed? Should be stop supporting the bypass // feature? public MetricsRegion getMetrics() { return metricsRegion; @@ -1609,10 +1540,7 @@ public long getMaxFlushedSeqId() { return maxFlushedSeqId; } - /** - * Returns readpoint considering given IsolationLevel. Pass {@code null} for - * default - */ + /** Returns readpoint considering given IsolationLevel. Pass {@code null} for default */ public long getReadPoint(IsolationLevel isolationLevel) { if (isolationLevel != null && isolationLevel == IsolationLevel.READ_UNCOMMITTED) { // This scan can read even uncommitted transactions @@ -1626,22 +1554,15 @@ public boolean isLoadingCfsOnDemandDefault() { } /** - * Close down this HRegion. Flush the cache, shut down each HStore, don't - * service any more calls. + * Close down this HRegion. Flush the cache, shut down each HStore, don't service any more calls. *

      - * This method could take some time to execute, so don't call it from a - * time-sensitive thread. - * - * @return Vector of all the storage files that the HRegion's component HStores - * make use of. It's - * a list of all StoreFile objects. Returns empty vector if already - * closed and null if + * This method could take some time to execute, so don't call it from a time-sensitive thread. + * @return Vector of all the storage files that the HRegion's component HStores make use of. It's + * a list of all StoreFile objects. Returns empty vector if already closed and null if * judged that it should not close. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required - * because a Snapshot was - * not properly persisted. The region is put in - * closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was + * not properly persisted. The region is put in closing mode, and * the caller MUST abort after this. */ public Map> close() throws IOException { @@ -1651,26 +1572,23 @@ public Map> close() throws IOException { private final Object closeLock = new Object(); /** Conf key for fair locking policy */ - public static final String FAIR_REENTRANT_CLOSE_LOCK = "hbase.regionserver.fair.region.close.lock"; + public static final String FAIR_REENTRANT_CLOSE_LOCK = + "hbase.regionserver.fair.region.close.lock"; public static final boolean DEFAULT_FAIR_REENTRANT_CLOSE_LOCK = true; /** Conf key for the periodic flush interval */ - public static final String MEMSTORE_PERIODIC_FLUSH_INTERVAL = "hbase.regionserver.optionalcacheflushinterval"; + public static final String MEMSTORE_PERIODIC_FLUSH_INTERVAL = + "hbase.regionserver.optionalcacheflushinterval"; /** Default interval for the memstore flush */ public static final int DEFAULT_CACHE_FLUSH_INTERVAL = 3600000; /** Default interval for System tables memstore flush */ public static final int SYSTEM_CACHE_FLUSH_INTERVAL = 300000; // 5 minutes - /** - * Conf key to force a flush if there are already enough changes for one region - * in memstore - */ + /** Conf key to force a flush if there are already enough changes for one region in memstore */ public static final String MEMSTORE_FLUSH_PER_CHANGES = "hbase.regionserver.flush.per.changes"; public static final long DEFAULT_FLUSH_PER_CHANGES = 30000000; // 30 millions /** - * The following MAX_FLUSH_PER_CHANGES is large enough because each KeyValue has - * 20+ bytes - * overhead. Therefore, even 1G empty KVs occupy at least 20GB memstore size for - * a single region + * The following MAX_FLUSH_PER_CHANGES is large enough because each KeyValue has 20+ bytes + * overhead. Therefore, even 1G empty KVs occupy at least 20GB memstore size for a single region */ public static final long MAX_FLUSH_PER_CHANGES = 1000000000; // 1G @@ -1687,57 +1605,44 @@ public Map> close(boolean abort) throws IOException { /** * Close this HRegion. - * * @param abort true if server is aborting (only during testing) * @param ignoreStatus true if ignore the status (won't be showed on task list) - * @return Vector of all the storage files that the HRegion's component HStores - * make use of. It's - * a list of StoreFile objects. Can be null if we are not to close at - * this time, or we are + * @return Vector of all the storage files that the HRegion's component HStores make use of. It's + * a list of StoreFile objects. Can be null if we are not to close at this time, or we are * already closed. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required - * because a Snapshot was - * not properly persisted. The region is put in - * closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was + * not properly persisted. The region is put in closing mode, and * the caller MUST abort after this. */ public Map> close(boolean abort, boolean ignoreStatus) - throws IOException { + throws IOException { return close(abort, ignoreStatus, false); } /** - * Close down this HRegion. Flush the cache unless abort parameter is true, Shut - * down each HStore, - * don't service any more calls. This method could take some time to execute, so - * don't call it + * Close down this HRegion. Flush the cache unless abort parameter is true, Shut down each HStore, + * don't service any more calls. This method could take some time to execute, so don't call it * from a time-sensitive thread. - * * @param abort true if server is aborting (only during testing) * @param ignoreStatus true if ignore the status (wont be showed on task list) - * @param isGracefulStop true if region is being closed during graceful stop and - * the blocks in the + * @param isGracefulStop true if region is being closed during graceful stop and the blocks in the * BucketCache should not be evicted. - * @return Vector of all the storage files that the HRegion's component HStores - * make use of. It's - * a list of StoreFile objects. Can be null if we are not to close at - * this time or we are + * @return Vector of all the storage files that the HRegion's component HStores make use of. It's + * a list of StoreFile objects. Can be null if we are not to close at this time or we are * already closed. * @throws IOException e - * @throws DroppedSnapshotException Thrown when replay of wal is required - * because a Snapshot was - * not properly persisted. The region is put in - * closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was + * not properly persisted. The region is put in closing mode, and * the caller MUST abort after this. */ public Map> close(boolean abort, boolean ignoreStatus, - boolean isGracefulStop) throws IOException { + boolean isGracefulStop) throws IOException { // Only allow one thread to close at a time. Serialize them so dual // threads attempting to close will run up against each other. MonitoredTask status = TaskMonitor.get().createStatus( - "Closing region " + this.getRegionInfo().getEncodedName() + (abort ? " due to abort" : ""), - ignoreStatus, true); + "Closing region " + this.getRegionInfo().getEncodedName() + (abort ? " due to abort" : ""), + ignoreStatus, true); status.setStatus("Waiting for close lock"); try { synchronized (closeLock) { @@ -1748,9 +1653,9 @@ public Map> close(boolean abort, boolean ignoreStatus, if (l2 instanceof BucketCache) { if (((BucketCache) l2).isCachePersistenceEnabled()) { LOG.info( - "Closing region {} during a graceful stop, and cache persistence is on, " - + "so setting evict on close to false. ", - this.getRegionInfo().getRegionNameAsString()); + "Closing region {} during a graceful stop, and cache persistence is on, " + + "so setting evict on close to false. ", + this.getRegionInfo().getRegionNameAsString()); this.getStores().forEach(s -> s.getCacheConfig().setEvictOnClose(false)); } } @@ -1762,7 +1667,7 @@ public Map> close(boolean abort, boolean ignoreStatus, } finally { if (LOG.isDebugEnabled()) { LOG.debug("Region close journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } @@ -1776,12 +1681,9 @@ public void setClosing(boolean closing) { } /** - * The {@link HRegion#doClose} will block forever if someone tries proving the - * dead lock via the - * unit test. Instead of blocking, the {@link HRegion#doClose} will throw - * exception if you set the + * The {@link HRegion#doClose} will block forever if someone tries proving the dead lock via the + * unit test. Instead of blocking, the {@link HRegion#doClose} will throw exception if you set the * timeout. - * * @param timeoutForWriteLock the second time to wait for the write lock in * {@link HRegion#doClose} */ @@ -1790,9 +1692,10 @@ public void setTimeoutForWriteLock(long timeoutForWriteLock) { this.timeoutForWriteLock = timeoutForWriteLock; } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "UL_UNRELEASED_LOCK_EXCEPTION_PATH", justification = "I think FindBugs is confused") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "UL_UNRELEASED_LOCK_EXCEPTION_PATH", + justification = "I think FindBugs is confused") private Map> doClose(boolean abort, MonitoredTask status) - throws IOException { + throws IOException { if (isClosed()) { LOG.warn("Region " + this + " already closed"); return null; @@ -1810,7 +1713,7 @@ private Map> doClose(boolean abort, MonitoredTask statu canFlush = !writestate.readOnly; writestate.writesEnabled = false; LOG.debug("Closing {}, disabling compactions & flushes", - this.getRegionInfo().getEncodedName()); + this.getRegionInfo().getEncodedName()); waitForFlushesAndCompactions(); } // If we were not just flushing, is it worth doing a preflush...one @@ -1828,10 +1731,8 @@ private Map> doClose(boolean abort, MonitoredTask statu } if (regionReplicationSink.isPresent()) { // stop replicating to secondary replicas - // the open event marker can make secondary replicas refresh store files and - // catch up - // everything, so here we just give up replicating later edits, to speed up the - // reopen process + // the open event marker can make secondary replicas refresh store files and catch up + // everything, so here we just give up replicating later edits, to speed up the reopen process RegionReplicationSink sink = regionReplicationSink.get(); sink.stop(); try { @@ -1866,7 +1767,7 @@ private Map> doClose(boolean abort, MonitoredTask statu } if (LOG.isDebugEnabled()) { LOG.debug((useTimedWait ? "Time limited wait" : "Waiting without time limit") - + " for close lock on " + this); + + " for close lock on " + this); } final long closeWaitInterval = conf.getLong(CLOSE_WAIT_INTERVAL, DEFAULT_CLOSE_WAIT_INTERVAL); long elapsedWaitTime = 0; @@ -1875,8 +1776,8 @@ private Map> doClose(boolean abort, MonitoredTask statu long remainingWaitTime = timeoutForWriteLock; if (remainingWaitTime < closeWaitInterval) { LOG.warn("Time limit for close wait of " + timeoutForWriteLock - + " ms is less than the configured lock acquisition wait interval " + closeWaitInterval - + " ms, using wait interval as time limit"); + + " ms is less than the configured lock acquisition wait interval " + closeWaitInterval + + " ms, using wait interval as time limit"); remainingWaitTime = closeWaitInterval; } boolean acquired = false; @@ -1884,12 +1785,10 @@ private Map> doClose(boolean abort, MonitoredTask statu long start = EnvironmentEdgeManager.currentTime(); try { acquired = lock.writeLock().tryLock(Math.min(remainingWaitTime, closeWaitInterval), - TimeUnit.MILLISECONDS); + TimeUnit.MILLISECONDS); } catch (InterruptedException e) { - // Interrupted waiting for close lock. More likely the server is shutting down, - // not - // normal operation, so aborting upon interrupt while waiting on this lock would - // not + // Interrupted waiting for close lock. More likely the server is shutting down, not + // normal operation, so aborting upon interrupt while waiting on this lock would not // provide much value. Throw an IOE (as IIOE) like we would in the case where we // fail to acquire the lock. String msg = "Interrupted while waiting for close lock on " + this; @@ -1906,17 +1805,17 @@ private Map> doClose(boolean abort, MonitoredTask statu // endRegionOperation. if (LOG.isDebugEnabled()) { LOG.debug("Interrupting region operations after waiting for close lock for " - + elapsedWaitTime + " ms on " + this + ", " + remainingWaitTime + " ms remaining"); + + elapsedWaitTime + " ms on " + this + ", " + remainingWaitTime + " ms remaining"); } interruptRegionOperations(); } } while (!acquired && remainingWaitTime > 0); - // If we fail to acquire the lock, trigger an abort if we can; otherwise throw - // an IOE + // If we fail to acquire the lock, trigger an abort if we can; otherwise throw an IOE // to let the caller know we could not proceed with the close. if (!acquired) { - String msg = "Failed to acquire close lock on " + this + " after waiting " + elapsedWaitTime + " ms"; + String msg = + "Failed to acquire close lock on " + this + " after waiting " + elapsedWaitTime + " ms"; LOG.error(msg); if (canAbort) { // If we failed to acquire the write lock, abort the server @@ -1967,7 +1866,7 @@ private Map> doClose(boolean abort, MonitoredTask statu // If we failed 5 times and are unable to clear memory, abort // so we do not lose data throw new DroppedSnapshotException("Failed clearing memory after " + flushCount - + " attempts on region: " + Bytes.toStringBinary(getRegionInfo().getRegionName())); + + " attempts on region: " + Bytes.toStringBinary(getRegionInfo().getRegionName())); } } catch (IOException ioe) { status.setStatus("Failed flush " + this + ", putting online again"); @@ -1983,10 +1882,10 @@ private Map> doClose(boolean abort, MonitoredTask statu Map> result = new TreeMap<>(Bytes.BYTES_COMPARATOR); if (!stores.isEmpty()) { // initialize the thread pool for closing stores in parallel. - ThreadPoolExecutor storeCloserThreadPool = getStoreOpenAndCloseThreadPool( - "StoreCloser-" + getRegionInfo().getRegionNameAsString()); - CompletionService>> completionService = new ExecutorCompletionService<>( - storeCloserThreadPool); + ThreadPoolExecutor storeCloserThreadPool = + getStoreOpenAndCloseThreadPool("StoreCloser-" + getRegionInfo().getRegionNameAsString()); + CompletionService>> completionService = + new ExecutorCompletionService<>(storeCloserThreadPool); // close each store in parallel for (HStore store : stores.values()) { @@ -1994,10 +1893,10 @@ private Map> doClose(boolean abort, MonitoredTask statu if (!(abort || mss.getDataSize() == 0 || writestate.readOnly)) { if (getRegionServerServices() != null) { getRegionServerServices().abort("Assertion failed while closing store " - + getRegionInfo().getRegionNameAsString() + " " + store - + ". flushableSize expected=0, actual={" + mss + "}. Current memStoreSize=" - + this.memStoreSizing.getMemStoreSize() + ". Maybe a coprocessor " - + "operation failed and left the memstore in a partially updated state.", null); + + getRegionInfo().getRegionNameAsString() + " " + store + + ". flushableSize expected=0, actual={" + mss + "}. Current memStoreSize=" + + this.memStoreSizing.getMemStoreSize() + ". Maybe a coprocessor " + + "operation failed and left the memstore in a partially updated state.", null); } } completionService.submit(new Callable>>() { @@ -2032,12 +1931,12 @@ public Pair> call() throws IOException { } status.setStatus("Writing region close event to WAL"); - // Always write close marker to wal even for read only table. This is not a big - // problem as we - // do not write any data into the region; it is just a meta edit in the WAL - // file. - if (!abort && wal != null && getRegionServerServices() != null - && RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { + // Always write close marker to wal even for read only table. This is not a big problem as we + // do not write any data into the region; it is just a meta edit in the WAL file. + if ( + !abort && wal != null && getRegionServerServices() != null + && RegionReplicaUtil.isDefaultReplica(getRegionInfo()) + ) { writeRegionCloseMarker(wal); } this.closed.set(true); @@ -2072,14 +1971,12 @@ public Pair> call() throws IOException { } /** Wait for all current flushes and compactions of the region to complete */ - // TODO HBASE-18906. Check the usage (if any) in Phoenix and expose this or give - // alternate way for + // TODO HBASE-18906. Check the usage (if any) in Phoenix and expose this or give alternate way for // Phoenix needs. public void waitForFlushesAndCompactions() { synchronized (writestate) { if (this.writestate.readOnly) { - // we should not wait for replayed flushed if we are read only (for example in - // case the + // we should not wait for replayed flushed if we are read only (for example in case the // region is a secondary replica). return; } @@ -2087,7 +1984,7 @@ public void waitForFlushesAndCompactions() { try { while (writestate.compacting.get() > 0 || writestate.flushing) { LOG.debug("waiting for " + writestate.compacting + " compactions" - + (writestate.flushing ? " & cache flush" : "") + " to complete for region " + this); + + (writestate.flushing ? " & cache flush" : "") + " to complete for region " + this); try { writestate.wait(); } catch (InterruptedException iex) { @@ -2116,21 +2013,18 @@ public void waitForFlushes() { public boolean waitForFlushes(long timeout) { synchronized (writestate) { if (this.writestate.readOnly) { - // we should not wait for replayed flushed if we are read only (for example in - // case the + // we should not wait for replayed flushed if we are read only (for example in case the // region is a secondary replica). return true; } - if (!writestate.flushing) - return true; + if (!writestate.flushing) return true; long start = EnvironmentEdgeManager.currentTime(); long duration = 0; boolean interrupted = false; LOG.debug("waiting for cache flush to complete for region " + this); try { while (writestate.flushing) { - if (timeout > 0 && duration >= timeout) - break; + if (timeout > 0 && duration >= timeout) break; try { long toWait = timeout == 0 ? 0 : (timeout - duration); writestate.wait(toWait); @@ -2166,33 +2060,34 @@ public int getMinBlockSizeBytes() { private ThreadPoolExecutor getStoreOpenAndCloseThreadPool(final String threadNamePrefix) { int numStores = Math.max(1, this.htableDescriptor.getColumnFamilyCount()); int maxThreads = Math.min(numStores, conf.getInt(HConstants.HSTORE_OPEN_AND_CLOSE_THREADS_MAX, - HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX)); + HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX)); return getOpenAndCloseThreadPool(maxThreads, threadNamePrefix); } ThreadPoolExecutor getStoreFileOpenAndCloseThreadPool(final String threadNamePrefix) { int numStores = Math.max(1, this.htableDescriptor.getColumnFamilyCount()); int maxThreads = Math.max(1, conf.getInt(HConstants.HSTORE_OPEN_AND_CLOSE_THREADS_MAX, - HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX) / numStores); + HConstants.DEFAULT_HSTORE_OPEN_AND_CLOSE_THREADS_MAX) / numStores); return getOpenAndCloseThreadPool(maxThreads, threadNamePrefix); } private static ThreadPoolExecutor getOpenAndCloseThreadPool(int maxThreads, - final String threadNamePrefix) { + final String threadNamePrefix) { return Threads.getBoundedCachedThreadPool(maxThreads, 30L, TimeUnit.SECONDS, - new ThreadFactory() { - private int count = 1; + new ThreadFactory() { + private int count = 1; - @Override - public Thread newThread(Runnable r) { - return new Thread(r, threadNamePrefix + "-" + count++); - } - }); + @Override + public Thread newThread(Runnable r) { + return new Thread(r, threadNamePrefix + "-" + count++); + } + }); } /** Returns True if its worth doing a flush before we put up the close flag. */ private boolean worthPreFlushing() { - return this.memStoreSizing.getDataSize() > this.conf.getLong("hbase.hregion.preclose.flush.size", 1024 * 1024 * 5); + return this.memStoreSizing.getDataSize() + > this.conf.getLong("hbase.hregion.preclose.flush.size", 1024 * 1024 * 5); } ////////////////////////////////////////////////////////////////////////////// @@ -2241,14 +2136,10 @@ RegionSplitPolicy getSplitPolicy() { } /** - * A split takes the config from the parent region & passes it to the daughter - * region's - * constructor. If 'conf' was passed, you would end up using the HTD of the - * parent region in - * addition to the new daughter HTD. Pass 'baseConf' to the daughter regions to - * avoid this tricky + * A split takes the config from the parent region & passes it to the daughter region's + * constructor. If 'conf' was passed, you would end up using the HTD of the parent region in + * addition to the new daughter HTD. Pass 'baseConf' to the daughter regions to avoid this tricky * dedupe problem. - * * @return Configuration object */ Configuration getBaseConf() { @@ -2268,7 +2159,7 @@ public HRegionFileSystem getRegionFileSystem() { /** Returns the WAL {@link HRegionFileSystem} used by this region */ HRegionWALFileSystem getRegionWALFileSystem() throws IOException { return new HRegionWALFileSystem(conf, getWalFileSystem(), - CommonFSUtils.getWALTableDir(conf, htableDescriptor.getTableName()), fs.getRegionInfo()); + CommonFSUtils.getWALTableDir(conf, htableDescriptor.getTableName()), fs.getRegionInfo()); } /** Returns the WAL {@link FileSystem} being used by this region */ @@ -2286,7 +2177,7 @@ FileSystem getWalFileSystem() throws IOException { public Path getWALRegionDir() throws IOException { if (regionWalDir == null) { regionWalDir = CommonFSUtils.getWALRegionDir(conf, getRegionInfo().getTable(), - getRegionInfo().getEncodedName()); + getRegionInfo().getEncodedName()); } return regionWalDir; } @@ -2331,14 +2222,12 @@ RegionLoad.Builder setCompleteSequenceId(RegionLoad.Builder regionLoadBldr) { regionLoadBldr.clearStoreCompleteSequenceId(); for (byte[] familyName : this.stores.keySet()) { long earliest = this.wal.getEarliestMemStoreSeqNum(encodedRegionName, familyName); - // Subtract - 1 to go earlier than the current oldest, unflushed edit in - // memstore; this will - // give us a sequence id that is for sure flushed. We want edit replay to start - // after this + // Subtract - 1 to go earlier than the current oldest, unflushed edit in memstore; this will + // give us a sequence id that is for sure flushed. We want edit replay to start after this // sequence id in this region. If NO_SEQNUM, use the regions maximum flush id. long csid = (earliest == HConstants.NO_SEQNUM) ? lastFlushOpSeqIdLocal : earliest - 1; regionLoadBldr.addStoreCompleteSequenceId(StoreSequenceId.newBuilder() - .setFamilyName(UnsafeByteOperations.unsafeWrap(familyName)).setSequenceId(csid).build()); + .setFamilyName(UnsafeByteOperations.unsafeWrap(familyName)).setSequenceId(csid).build()); } return regionLoadBldr.setCompleteSequenceId(getMaxFlushedSeqId()); } @@ -2358,19 +2247,13 @@ protected void doRegionCompactionPrep() throws IOException { /** * Synchronously compact all stores in the region. *

      - * This operation could block for a long time, so don't call it from a - * time-sensitive thread. + * This operation could block for a long time, so don't call it from a time-sensitive thread. *

      - * Note that no locks are taken to prevent possible conflicts between compaction - * and splitting - * activities. The regionserver does not normally compact and split in parallel. - * However by - * calling this method you may introduce unexpected and unhandled concurrency. - * Don't do this + * Note that no locks are taken to prevent possible conflicts between compaction and splitting + * activities. The regionserver does not normally compact and split in parallel. However by + * calling this method you may introduce unexpected and unhandled concurrency. Don't do this * unless you know what you are doing. - * - * @param majorCompaction True to force a major compaction regardless of - * thresholds + * @param majorCompaction True to force a major compaction regardless of thresholds */ public void compact(boolean majorCompaction) throws IOException { if (majorCompaction) { @@ -2419,96 +2302,63 @@ void compactStore(byte[] family, ThroughputController throughputController) thro } /** - * Called by compaction thread and after region is opened to compact the HStores - * if necessary. + * Called by compaction thread and after region is opened to compact the HStores if necessary. *

      - * This operation could block for a long time, so don't call it from a - * time-sensitive thread. Note - * that no locking is necessary at this level because compaction only conflicts - * with a region - * split, and that cannot happen because the region server does them - * sequentially and not in + * This operation could block for a long time, so don't call it from a time-sensitive thread. Note + * that no locking is necessary at this level because compaction only conflicts with a region + * split, and that cannot happen because the region server does them sequentially and not in * parallel. - * * @param compaction Compaction details, obtained by requestCompaction() * @return whether the compaction completed */ public boolean compact(CompactionContext compaction, HStore store, - ThroughputController throughputController) throws IOException { + ThroughputController throughputController) throws IOException { return compact(compaction, store, throughputController, null); } private boolean shouldForbidMajorCompaction() { if (rsServices != null && rsServices.getReplicationSourceService() != null) { return rsServices.getReplicationSourceService().getSyncReplicationPeerInfoProvider() - .checkState(getRegionInfo().getTable(), ForbidMajorCompactionChecker.get()); + .checkState(getRegionInfo().getTable(), ForbidMajorCompactionChecker.get()); } return false; } /** - * We are trying to remove / relax the region read lock for compaction. Let's - * see what are the - * potential race conditions among the operations (user scan, region split, - * region close and - * region bulk load). user scan ---> region read lock region split --> region - * close first --> - * region write lock region close --> region write lock region bulk load --> - * region write lock - * read lock is compatible with read lock. ---> no problem with user scan/read - * region bulk load - * does not cause problem for compaction (no consistency problem, store lock - * will help the store - * file accounting). They can run almost concurrently at the region level. The - * only remaining race - * condition is between the region close and compaction. So we will evaluate, - * below, how region - * close intervenes with compaction if compaction does not acquire region read - * lock. Here are the - * steps for compaction: 1. obtain list of StoreFile's 2. create - * StoreFileScanner's based on list - * from #1 3. perform compaction and save resulting files under tmp dir 4. swap - * in compacted files - * #1 is guarded by store lock. This patch does not change this --> no worse or - * better For #2, we - * obtain smallest read point (for region) across all the Scanners (for both - * default compactor and - * stripe compactor). The read points are for user scans. Region keeps the read - * points for all - * currently open user scanners. Compaction needs to know the smallest read - * point so that during - * re-write of the hfiles, it can remove the mvcc points for the cells if their - * mvccs are older - * than the smallest since they are not needed anymore. This will not conflict - * with compaction. - * For #3, it can be performed in parallel to other operations. For #4 bulk load - * and compaction - * don't conflict with each other on the region level (for multi-family - * atomicy). Region close and - * compaction are guarded pretty well by the 'writestate'. In HRegion#doClose(), - * we have : - * synchronized (writestate) { // Disable compacting and flushing by background - * threads for this + * We are trying to remove / relax the region read lock for compaction. Let's see what are the + * potential race conditions among the operations (user scan, region split, region close and + * region bulk load). user scan ---> region read lock region split --> region close first --> + * region write lock region close --> region write lock region bulk load --> region write lock + * read lock is compatible with read lock. ---> no problem with user scan/read region bulk load + * does not cause problem for compaction (no consistency problem, store lock will help the store + * file accounting). They can run almost concurrently at the region level. The only remaining race + * condition is between the region close and compaction. So we will evaluate, below, how region + * close intervenes with compaction if compaction does not acquire region read lock. Here are the + * steps for compaction: 1. obtain list of StoreFile's 2. create StoreFileScanner's based on list + * from #1 3. perform compaction and save resulting files under tmp dir 4. swap in compacted files + * #1 is guarded by store lock. This patch does not change this --> no worse or better For #2, we + * obtain smallest read point (for region) across all the Scanners (for both default compactor and + * stripe compactor). The read points are for user scans. Region keeps the read points for all + * currently open user scanners. Compaction needs to know the smallest read point so that during + * re-write of the hfiles, it can remove the mvcc points for the cells if their mvccs are older + * than the smallest since they are not needed anymore. This will not conflict with compaction. + * For #3, it can be performed in parallel to other operations. For #4 bulk load and compaction + * don't conflict with each other on the region level (for multi-family atomicy). Region close and + * compaction are guarded pretty well by the 'writestate'. In HRegion#doClose(), we have : + * synchronized (writestate) { // Disable compacting and flushing by background threads for this * // region. canFlush = !writestate.readOnly; writestate.writesEnabled = false; * LOG.debug("Closing " + this + ": disabling compactions & flushes"); - * waitForFlushesAndCompactions(); } waitForFlushesAndCompactions() would wait - * for - * writestate.compacting to come down to 0. and in HRegion.compact() try { - * synchronized - * (writestate) { if (writestate.writesEnabled) { wasStateSet = true; - * ++writestate.compacting; } - * else { String msg = "NOT compacting region " + this + ". Writes disabled."; - * LOG.info(msg); - * status.abort(msg); return false; } } Also in compactor.performCompaction(): - * check periodically + * waitForFlushesAndCompactions(); } waitForFlushesAndCompactions() would wait for + * writestate.compacting to come down to 0. and in HRegion.compact() try { synchronized + * (writestate) { if (writestate.writesEnabled) { wasStateSet = true; ++writestate.compacting; } + * else { String msg = "NOT compacting region " + this + ". Writes disabled."; LOG.info(msg); + * status.abort(msg); return false; } } Also in compactor.performCompaction(): check periodically * to see if a system stop is requested if (closeChecker != null && - * closeChecker.isTimeLimit(store, now)) { progress.cancel(); return false; } if - * (closeChecker != - * null && closeChecker.isSizeLimit(store, len)) { progress.cancel(); return - * false; } + * closeChecker.isTimeLimit(store, now)) { progress.cancel(); return false; } if (closeChecker != + * null && closeChecker.isSizeLimit(store, len)) { progress.cancel(); return false; } */ public boolean compact(CompactionContext compaction, HStore store, - ThroughputController throughputController, User user) throws IOException { + ThroughputController throughputController, User user) throws IOException { assert compaction != null && compaction.hasSelection(); assert !compaction.getRequest().getFiles().isEmpty(); if (this.closing.get() || this.closed.get()) { @@ -2519,8 +2369,8 @@ public boolean compact(CompactionContext compaction, HStore store, if (compaction.getRequest().isAllFiles() && shouldForbidMajorCompaction()) { LOG.warn("Skipping major compaction on " + this - + " because this cluster is transiting sync replication state" - + " from STANDBY to DOWNGRADE_ACTIVE"); + + " because this cluster is transiting sync replication state" + + " from STANDBY to DOWNGRADE_ACTIVE"); store.cancelRequestedCompaction(compaction); return false; } @@ -2531,8 +2381,8 @@ public boolean compact(CompactionContext compaction, HStore store, byte[] cf = Bytes.toBytes(store.getColumnFamilyName()); if (stores.get(cf) != store) { LOG.warn("Store " + store.getColumnFamilyName() + " on region " + this - + " has been re-instantiated, cancel this compaction request. " - + " It may be caused by the roll back of split transaction"); + + " has been re-instantiated, cancel this compaction request. " + + " It may be caused by the roll back of split transaction"); return false; } @@ -2557,7 +2407,7 @@ public boolean compact(CompactionContext compaction, HStore store, } } LOG.info("Starting compaction of {} in {}{}", store, this, - (compaction.getRequest().isOffPeak() ? " as an off-peak compaction" : "")); + (compaction.getRequest().isOffPeak() ? " as an off-peak compaction" : "")); doRegionCompactionPrep(); try { status.setStatus("Compacting store " + store); @@ -2584,11 +2434,10 @@ public boolean compact(CompactionContext compaction, HStore store, status.markComplete("Compaction complete"); return true; } finally { - if (requestNeedsCancellation) - store.cancelRequestedCompaction(compaction); + if (requestNeedsCancellation) store.cancelRequestedCompaction(compaction); if (status != null) { LOG.debug("Compaction status journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); status.cleanup(); } } @@ -2605,15 +2454,11 @@ public boolean compact(CompactionContext compaction, HStore store, *

    11. writes are disabled
    12. *
    *

    - * This method may block for some time, so it should not be called from a - * time-sensitive thread. - * + * This method may block for some time, so it should not be called from a time-sensitive thread. * @param flushAllStores whether we want to force a flush of all stores - * @return FlushResult indicating whether the flush was successful or not and if - * the region needs + * @return FlushResult indicating whether the flush was successful or not and if the region needs * compacting - * @throws IOException general io exceptions because a snapshot was not properly - * persisted. + * @throws IOException general io exceptions because a snapshot was not properly persisted. */ // TODO HBASE-18905. We might have to expose a requestFlush API for CPs public FlushResult flush(boolean flushAllStores) throws IOException { @@ -2624,8 +2469,7 @@ public interface FlushResult { enum Result { FLUSHED_NO_COMPACTION_NEEDED, FLUSHED_COMPACTION_NEEDED, - // Special case where a flush didn't run because there's nothing in the - // memstores. Used when + // Special case where a flush didn't run because there's nothing in the memstores. Used when // bulk loading to know when we can still load even if a flush didn't happen. CANNOT_FLUSH_MEMSTORE_EMPTY, CANNOT_FLUSH @@ -2642,7 +2486,7 @@ enum Result { } public FlushResultImpl flushcache(boolean flushAllStores, boolean writeFlushRequestWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + FlushLifeCycleTracker tracker) throws IOException { List families = null; if (flushAllStores) { families = new ArrayList<>(); @@ -2660,23 +2504,18 @@ public FlushResultImpl flushcache(boolean flushAllStores, boolean writeFlushRequ *

  • writes are disabled
  • * *

    - * This method may block for some time, so it should not be called from a - * time-sensitive thread. - * + * This method may block for some time, so it should not be called from a time-sensitive thread. * @param families stores of region to flush. - * @param writeFlushRequestWalMarker whether to write the flush request marker - * to WAL + * @param writeFlushRequestWalMarker whether to write the flush request marker to WAL * @param tracker used to track the life cycle of this flush * @return whether the flush is success and whether the region needs compacting * @throws IOException general io exceptions - * @throws DroppedSnapshotException Thrown when replay of wal is required - * because a Snapshot was - * not properly persisted. The region is put in - * closing mode, and + * @throws DroppedSnapshotException Thrown when replay of wal is required because a Snapshot was + * not properly persisted. The region is put in closing mode, and * the caller MUST abort after this. */ public FlushResultImpl flushcache(List families, boolean writeFlushRequestWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + FlushLifeCycleTracker tracker) throws IOException { // fail-fast instead of waiting on the lock if (this.closing.get()) { String msg = "Skipping flush on " + this + " because closing"; @@ -2700,8 +2539,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque status.setStatus("Running coprocessor pre-flush hooks"); coprocessorHost.preFlush(tracker); } - // TODO: this should be managed within memstore with the snapshot, updated only - // after flush + // TODO: this should be managed within memstore with the snapshot, updated only after flush // successful if (numMutationsWithoutWAL.sum() > 0) { numMutationsWithoutWAL.reset(); @@ -2712,7 +2550,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque this.writestate.flushing = true; } else { String msg = "NOT flushing " + this + " as " - + (writestate.flushing ? "already flushing" : "writes are not enabled"); + + (writestate.flushing ? "already flushing" : "writes are not enabled"); LOG.debug(msg); status.abort(msg); flushed = false; @@ -2730,7 +2568,8 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque } else { specificStoresToFlush = flushPolicy.selectStoresToFlush(); } - FlushResultImpl fs = internalFlushcache(specificStoresToFlush, status, writeFlushRequestWalMarker, tracker); + FlushResultImpl fs = + internalFlushcache(specificStoresToFlush, status, writeFlushRequestWalMarker, tracker); if (coprocessorHost != null) { status.setStatus("Running post-flush coprocessor hooks"); @@ -2755,7 +2594,7 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque if (flushed) { // Don't log this journal stuff if no flush -- confusing. LOG.debug("Flush status journal for {}:\n{}", this.getRegionInfo().getEncodedName(), - status.prettyPrintJournal()); + status.prettyPrintJournal()); } status.cleanup(); } @@ -2763,7 +2602,6 @@ public FlushResultImpl flushcache(List families, boolean writeFlushReque /** * get stores which matches the specified families - * * @return the stores need to be flushed. */ private Collection getSpecificStores(List families) { @@ -2777,20 +2615,18 @@ private Collection getSpecificStores(List families) { /** * Should the store be flushed because it is old enough. *

    - * Every FlushPolicy should call this to determine whether a store is old enough - * to flush (except - * that you always flush all stores). Otherwise the method will always returns - * true which will + * Every FlushPolicy should call this to determine whether a store is old enough to flush (except + * that you always flush all stores). Otherwise the method will always returns true which will * make a lot of flush requests. */ boolean shouldFlushStore(HStore store) { long earliest = this.wal.getEarliestMemStoreSeqNum(getRegionInfo().getEncodedNameAsBytes(), - store.getColumnFamilyDescriptor().getName()) - 1; + store.getColumnFamilyDescriptor().getName()) - 1; if (earliest > 0 && earliest + flushPerChanges < mvcc.getReadPoint()) { if (LOG.isDebugEnabled()) { LOG.debug("Flush column family " + store.getColumnFamilyName() + " of " - + getRegionInfo().getEncodedName() + " because unflushed sequenceid=" + earliest - + " is > " + this.flushPerChanges + " from current=" + mvcc.getReadPoint()); + + getRegionInfo().getEncodedName() + " because unflushed sequenceid=" + earliest + + " is > " + this.flushPerChanges + " from current=" + mvcc.getReadPoint()); } return true; } @@ -2801,8 +2637,8 @@ boolean shouldFlushStore(HStore store) { if (store.timeOfOldestEdit() < now - this.flushCheckInterval) { if (LOG.isDebugEnabled()) { LOG.debug("Flush column family: " + store.getColumnFamilyName() + " of " - + getRegionInfo().getEncodedName() + " because time of oldest edit=" - + store.timeOfOldestEdit() + " is > " + this.flushCheckInterval + " from now =" + now); + + getRegionInfo().getEncodedName() + " because time of oldest edit=" + + store.timeOfOldestEdit() + " is > " + this.flushCheckInterval + " from now =" + now); } return true; } @@ -2815,14 +2651,18 @@ boolean shouldFlushStore(HStore store) { boolean shouldFlush(final StringBuilder whyFlush) { whyFlush.setLength(0); // This is a rough measure. - if (this.maxFlushedSeqId > 0 - && (this.maxFlushedSeqId + this.flushPerChanges < this.mvcc.getReadPoint())) { + if ( + this.maxFlushedSeqId > 0 + && (this.maxFlushedSeqId + this.flushPerChanges < this.mvcc.getReadPoint()) + ) { whyFlush.append("more than max edits, " + this.flushPerChanges + ", since last flush"); return true; } long modifiedFlushCheckInterval = flushCheckInterval; - if (getRegionInfo().getTable().isSystemTable() - && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID) { + if ( + getRegionInfo().getTable().isSystemTable() + && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID + ) { modifiedFlushCheckInterval = SYSTEM_CACHE_FLUSH_INTERVAL; } if (modifiedFlushCheckInterval <= 0) { // disabled @@ -2847,9 +2687,7 @@ && getRegionInfo().getReplicaId() == RegionInfo.DEFAULT_REPLICA_ID) { /** * Flushing all stores. - * - * @see #internalFlushcache(Collection, MonitoredTask, boolean, - * FlushLifeCycleTracker) + * @see #internalFlushcache(Collection, MonitoredTask, boolean, FlushLifeCycleTracker) */ private FlushResult internalFlushcache(MonitoredTask status) throws IOException { return internalFlushcache(stores.values(), status, false, FlushLifeCycleTracker.DUMMY); @@ -2857,48 +2695,37 @@ private FlushResult internalFlushcache(MonitoredTask status) throws IOException /** * Flushing given stores. - * - * @see #internalFlushcache(WAL, long, Collection, MonitoredTask, boolean, - * FlushLifeCycleTracker) + * @see #internalFlushcache(WAL, long, Collection, MonitoredTask, boolean, FlushLifeCycleTracker) */ private FlushResultImpl internalFlushcache(Collection storesToFlush, MonitoredTask status, - boolean writeFlushWalMarker, FlushLifeCycleTracker tracker) throws IOException { + boolean writeFlushWalMarker, FlushLifeCycleTracker tracker) throws IOException { return internalFlushcache(this.wal, HConstants.NO_SEQNUM, storesToFlush, status, - writeFlushWalMarker, tracker); + writeFlushWalMarker, tracker); } /** - * Flush the memstore. Flushing the memstore is a little tricky. We have a lot - * of updates in the - * memstore, all of which have also been written to the wal. We need to write - * those updates in the - * memstore out to disk, while being able to process reads/writes as much as - * possible during the + * Flush the memstore. Flushing the memstore is a little tricky. We have a lot of updates in the + * memstore, all of which have also been written to the wal. We need to write those updates in the + * memstore out to disk, while being able to process reads/writes as much as possible during the * flush operation. *

    - * This method may block for some time. Every time you call it, we up the - * regions sequence id even - * if we don't flush; i.e. the returned region id will be at least one larger - * than the last edit - * applied to this region. The returned id does not refer to an actual edit. The - * returned id can - * be used for say installing a bulk loaded file just ahead of the last hfile - * that was the result + * This method may block for some time. Every time you call it, we up the regions sequence id even + * if we don't flush; i.e. the returned region id will be at least one larger than the last edit + * applied to this region. The returned id does not refer to an actual edit. The returned id can + * be used for say installing a bulk loaded file just ahead of the last hfile that was the result * of this flush, etc. - * * @param wal Null if we're NOT to go via wal. - * @param myseqid The seqid to use if wal is null writing out - * flush file. + * @param myseqid The seqid to use if wal is null writing out flush file. * @param storesToFlush The list of stores to flush. * @return object describing the flush's state * @throws IOException general io exceptions * @throws DroppedSnapshotException Thrown when replay of WAL is required. */ protected FlushResultImpl internalFlushcache(WAL wal, long myseqid, - Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, - FlushLifeCycleTracker tracker) throws IOException { - PrepareFlushResult result = internalPrepareFlushCache(wal, myseqid, storesToFlush, status, writeFlushWalMarker, - tracker); + Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, + FlushLifeCycleTracker tracker) throws IOException { + PrepareFlushResult result = + internalPrepareFlushCache(wal, myseqid, storesToFlush, status, writeFlushWalMarker, tracker); if (result.result == null) { return internalFlushCacheAndCommit(wal, status, result, storesToFlush); } else { @@ -2906,22 +2733,20 @@ protected FlushResultImpl internalFlushcache(WAL wal, long myseqid, } } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DLS_DEAD_LOCAL_STORE", justification = "FindBugs seems confused about trxId") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "DLS_DEAD_LOCAL_STORE", + justification = "FindBugs seems confused about trxId") protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, - Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, - FlushLifeCycleTracker tracker) throws IOException { + Collection storesToFlush, MonitoredTask status, boolean writeFlushWalMarker, + FlushLifeCycleTracker tracker) throws IOException { if (this.rsServices != null && this.rsServices.isAborted()) { // Don't flush when server aborting, it's unsafe throw new IOException("Aborting flush because server is aborted..."); } final long startTime = EnvironmentEdgeManager.currentTime(); // If nothing to flush, return, but return with a valid unused sequenceId. - // Its needed by bulk upload IIRC. It flushes until no edits in memory so it can - // insert a - // bulk loaded file between memory and existing hfiles. It wants a good - // seqeunceId that belongs - // to no other that it can use to associate with the bulk load. Hence this - // little dance below + // Its needed by bulk upload IIRC. It flushes until no edits in memory so it can insert a + // bulk loaded file between memory and existing hfiles. It wants a good seqeunceId that belongs + // to no other that it can use to associate with the bulk load. Hence this little dance below // to go get one. if (this.memStoreSizing.getDataSize() <= 0) { // Take an update lock so no edits can come into memory just yet. @@ -2929,34 +2754,29 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, WriteEntry writeEntry = null; try { if (this.memStoreSizing.getDataSize() <= 0) { - // Presume that if there are still no edits in the memstore, then there are no - // edits for - // this region out in the WAL subsystem so no need to do any trickery clearing - // out - // edits in the WAL sub-system. Up the sequence number so the resulting flush id - // is for - // sure just beyond the last appended region edit and not associated with any - // edit + // Presume that if there are still no edits in the memstore, then there are no edits for + // this region out in the WAL subsystem so no need to do any trickery clearing out + // edits in the WAL sub-system. Up the sequence number so the resulting flush id is for + // sure just beyond the last appended region edit and not associated with any edit // (useful as marker when bulk loading, etc.). if (wal != null) { writeEntry = mvcc.begin(); long flushOpSeqId = writeEntry.getWriteNumber(); FlushResultImpl flushResult = new FlushResultImpl( - FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, flushOpSeqId, "Nothing to flush", - writeCanNotFlushMarkerToWAL(writeEntry, wal, writeFlushWalMarker)); + FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, flushOpSeqId, "Nothing to flush", + writeCanNotFlushMarkerToWAL(writeEntry, wal, writeFlushWalMarker)); mvcc.completeAndWait(writeEntry); // Set to null so we don't complete it again down in finally block. writeEntry = null; return new PrepareFlushResult(flushResult, myseqid); } else { return new PrepareFlushResult(new FlushResultImpl( - FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, "Nothing to flush", false), myseqid); + FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY, "Nothing to flush", false), myseqid); } } } finally { if (writeEntry != null) { - // If writeEntry is non-null, this operation failed; the mvcc transaction - // failed... + // If writeEntry is non-null, this operation failed; the mvcc transaction failed... // but complete it anyways so it doesn't block the mvcc queue. mvcc.complete(writeEntry); } @@ -2964,16 +2784,12 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, } } logFatLineOnFlush(storesToFlush, myseqid); - // Stop updates while we snapshot the memstore of all of these regions' stores. - // We only have - // to do this for a moment. It is quick. We also set the memstore size to zero - // here before we - // allow updates again so its value will represent the size of the updates - // received + // Stop updates while we snapshot the memstore of all of these regions' stores. We only have + // to do this for a moment. It is quick. We also set the memstore size to zero here before we + // allow updates again so its value will represent the size of the updates received // during flush - // We have to take an update lock during snapshot, or else a write could end up - // in both snapshot + // We have to take an update lock during snapshot, or else a write could end up in both snapshot // and memstore (makes it difficult to do atomic rows then) status.setStatus("Obtaining lock to block concurrent updates"); // block waiting for the lock for internal flush @@ -2984,41 +2800,36 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, Map flushedFamilyNamesToSeq = new HashMap<>(); for (HStore store : storesToFlush) { flushedFamilyNamesToSeq.put(store.getColumnFamilyDescriptor().getName(), - store.preFlushSeqIDEstimation()); + store.preFlushSeqIDEstimation()); } TreeMap storeFlushCtxs = new TreeMap<>(Bytes.BYTES_COMPARATOR); TreeMap> committedFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR); TreeMap storeFlushableSize = new TreeMap<>(Bytes.BYTES_COMPARATOR); - // The sequence id of this flush operation which is used to log FlushMarker and - // pass to - // createFlushContext to use as the store file's sequence id. It can be in - // advance of edits - // still in the memstore, edits that are in other column families yet to be - // flushed. + // The sequence id of this flush operation which is used to log FlushMarker and pass to + // createFlushContext to use as the store file's sequence id. It can be in advance of edits + // still in the memstore, edits that are in other column families yet to be flushed. long flushOpSeqId = HConstants.NO_SEQNUM; - // The max flushed sequence id after this flush operation completes. All edits - // in memstore + // The max flushed sequence id after this flush operation completes. All edits in memstore // will be in advance of this sequence id. long flushedSeqId = HConstants.NO_SEQNUM; byte[] encodedRegionName = getRegionInfo().getEncodedNameAsBytes(); try { if (wal != null) { - Long earliestUnflushedSequenceIdForTheRegion = wal.startCacheFlush(encodedRegionName, flushedFamilyNamesToSeq); + Long earliestUnflushedSequenceIdForTheRegion = + wal.startCacheFlush(encodedRegionName, flushedFamilyNamesToSeq); if (earliestUnflushedSequenceIdForTheRegion == null) { - // This should never happen. This is how startCacheFlush signals flush cannot - // proceed. + // This should never happen. This is how startCacheFlush signals flush cannot proceed. String msg = this.getRegionInfo().getEncodedName() + " flush aborted; WAL closing."; status.setStatus(msg); return new PrepareFlushResult( - new FlushResultImpl(FlushResult.Result.CANNOT_FLUSH, msg, false), myseqid); + new FlushResultImpl(FlushResult.Result.CANNOT_FLUSH, msg, false), myseqid); } flushOpSeqId = getNextSequenceId(wal); - // Back up 1, minus 1 from oldest sequence id in memstore to get last 'flushed' - // edit + // Back up 1, minus 1 from oldest sequence id in memstore to get last 'flushed' edit flushedSeqId = earliestUnflushedSequenceIdForTheRegion.longValue() == HConstants.NO_SEQNUM - ? flushOpSeqId - : earliestUnflushedSequenceIdForTheRegion.longValue() - 1; + ? flushOpSeqId + : earliestUnflushedSequenceIdForTheRegion.longValue() - 1; } else { // use the provided sequence Id as WAL is not being used for this flush. flushedSeqId = flushOpSeqId = myseqid; @@ -3026,7 +2837,7 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, for (HStore s : storesToFlush) { storeFlushCtxs.put(s.getColumnFamilyDescriptor().getName(), - s.createFlushContext(flushOpSeqId, tracker)); + s.createFlushContext(flushOpSeqId, tracker)); // for writing stores to WAL committedFiles.put(s.getColumnFamilyDescriptor().getName(), null); } @@ -3034,11 +2845,10 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, // write the snapshot start to WAL if (wal != null && !writestate.readOnly) { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.START_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); - // No sync. Sync is below where no updates lock and we do - // FlushAction.COMMIT_FLUSH + getRegionInfo(), flushOpSeqId, committedFiles); + // No sync. Sync is below where no updates lock and we do FlushAction.COMMIT_FLUSH WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, false, - mvcc, regionReplicationSink.orElse(null)); + mvcc, regionReplicationSink.orElse(null)); } // Prepare flush (take a snapshot) @@ -3054,16 +2864,15 @@ protected PrepareFlushResult internalPrepareFlushCache(WAL wal, long myseqid, this.updatesLock.writeLock().unlock(); } String s = "Finished memstore snapshotting " + this + ", syncing WAL and waiting on mvcc, " - + "flushsize=" + totalSizeOfFlushableStores; + + "flushsize=" + totalSizeOfFlushableStores; status.setStatus(s); doSyncOfUnflushedWALChanges(wal, getRegionInfo()); return new PrepareFlushResult(storeFlushCtxs, committedFiles, storeFlushableSize, startTime, - flushOpSeqId, flushedSeqId, totalSizeOfFlushableStores); + flushOpSeqId, flushedSeqId, totalSizeOfFlushableStores); } /** - * Utility method broken out of internalPrepareFlushCache so that method is - * smaller. + * Utility method broken out of internalPrepareFlushCache so that method is smaller. */ private void logFatLineOnFlush(Collection storesToFlush, long sequenceId) { if (!LOG.isInfoEnabled()) { @@ -3084,24 +2893,23 @@ private void logFatLineOnFlush(Collection storesToFlush, long sequenceId } MemStoreSize mss = this.memStoreSizing.getMemStoreSize(); LOG.info("Flushing " + this.getRegionInfo().getEncodedName() + " " + storesToFlush.size() + "/" - + stores.size() + " column families," + " dataSize=" + StringUtils.byteDesc(mss.getDataSize()) - + " heapSize=" + StringUtils.byteDesc(mss.getHeapSize()) - + ((perCfExtras != null && perCfExtras.length() > 0) ? perCfExtras.toString() : "") - + ((wal != null) ? "" : "; WAL is null, using passed sequenceid=" + sequenceId)); + + stores.size() + " column families," + " dataSize=" + StringUtils.byteDesc(mss.getDataSize()) + + " heapSize=" + StringUtils.byteDesc(mss.getHeapSize()) + + ((perCfExtras != null && perCfExtras.length() > 0) ? perCfExtras.toString() : "") + + ((wal != null) ? "" : "; WAL is null, using passed sequenceid=" + sequenceId)); } private void doAbortFlushToWAL(final WAL wal, final long flushOpSeqId, - final Map> committedFiles) { - if (wal == null) - return; + final Map> committedFiles) { + if (wal == null) return; try { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.ABORT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, false, mvcc, - null); + null); } catch (Throwable t) { LOG.warn("Received unexpected exception trying to write ABORT_FLUSH marker to WAL: {} in " - + " region {}", StringUtils.stringifyException(t), this); + + " region {}", StringUtils.stringifyException(t), this); // ignore this since we will be aborting the RS with DSE. } // we have called wal.startCacheFlush(), now we have to abort it @@ -3112,7 +2920,7 @@ private void doAbortFlushToWAL(final WAL wal, final long flushOpSeqId, * Sync unflushed WAL changes. See HBASE-8208 for details */ private static void doSyncOfUnflushedWALChanges(final WAL wal, final RegionInfo hri) - throws IOException { + throws IOException { if (wal == null) { return; } @@ -3130,27 +2938,22 @@ private boolean isAllFamilies(Collection families) { } /** - * This method is only used when we flush but the memstore is empty,if - * writeFlushWalMarker is - * true,we write the {@link FlushAction#CANNOT_FLUSH} flush marker to WAL when - * the memstore is + * This method is only used when we flush but the memstore is empty,if writeFlushWalMarker is + * true,we write the {@link FlushAction#CANNOT_FLUSH} flush marker to WAL when the memstore is * empty. Ignores exceptions from WAL. Returns whether the write succeeded. - * * @return whether WAL write was successful */ private boolean writeCanNotFlushMarkerToWAL(WriteEntry flushOpSeqIdMVCCEntry, WAL wal, - boolean writeFlushWalMarker) { + boolean writeFlushWalMarker) { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.CANNOT_FLUSH, getRegionInfo(), - -1, new TreeMap<>(Bytes.BYTES_COMPARATOR)); + -1, new TreeMap<>(Bytes.BYTES_COMPARATOR)); RegionReplicationSink sink = regionReplicationSink.orElse(null); if (sink != null && !writeFlushWalMarker) { /** - * Here for replication to secondary region replica could use - * {@link FlushAction#CANNOT_FLUSH} + * Here for replication to secondary region replica could use {@link FlushAction#CANNOT_FLUSH} * to recover when writeFlushWalMarker is false, we create {@link WALEdit} for - * {@link FlushDescriptor} and attach the {@link RegionReplicationSink#add} to - * the + * {@link FlushDescriptor} and attach the {@link RegionReplicationSink#add} to the * flushOpSeqIdMVCCEntry,see HBASE-26960 for more details. */ this.attachRegionReplicationToFlushOpSeqIdMVCCEntry(flushOpSeqIdMVCCEntry, desc, sink); @@ -3160,38 +2963,38 @@ private boolean writeCanNotFlushMarkerToWAL(WriteEntry flushOpSeqIdMVCCEntry, WA if (writeFlushWalMarker && wal != null && !writestate.readOnly) { try { WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, true, mvcc, - sink); + sink); return true; } catch (IOException e) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received exception while trying to write the flush request to wal", e); + + "Received exception while trying to write the flush request to wal", e); } } return false; } /** - * Create {@link WALEdit} for {@link FlushDescriptor} and attach - * {@link RegionReplicationSink#add} + * Create {@link WALEdit} for {@link FlushDescriptor} and attach {@link RegionReplicationSink#add} * to the flushOpSeqIdMVCCEntry. */ private void attachRegionReplicationToFlushOpSeqIdMVCCEntry(WriteEntry flushOpSeqIdMVCCEntry, - FlushDescriptor desc, RegionReplicationSink sink) { + FlushDescriptor desc, RegionReplicationSink sink) { assert !flushOpSeqIdMVCCEntry.getCompletionAction().isPresent(); WALEdit flushMarkerWALEdit = WALEdit.createFlushWALEdit(getRegionInfo(), desc); - WALKeyImpl walKey = WALUtil.createWALKey(getRegionInfo(), mvcc, this.getReplicationScope(), null); + WALKeyImpl walKey = + WALUtil.createWALKey(getRegionInfo(), mvcc, this.getReplicationScope(), null); walKey.setWriteEntry(flushOpSeqIdMVCCEntry); /** - * Here the {@link ServerCall} is null for {@link RegionReplicationSink#add} - * because the + * Here the {@link ServerCall} is null for {@link RegionReplicationSink#add} because the * flushMarkerWALEdit is created by ourselves, not from rpc. */ flushOpSeqIdMVCCEntry.attachCompletionAction(() -> sink.add(walKey, flushMarkerWALEdit, null)); } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; notify is about completed flush") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", + justification = "Intentional; notify is about completed flush") FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, - PrepareFlushResult prepareResult, Collection storesToFlush) throws IOException { + PrepareFlushResult prepareResult, Collection storesToFlush) throws IOException { // prepare flush context is carried via PrepareFlushResult TreeMap storeFlushCtxs = prepareResult.storeFlushCtxs; TreeMap> committedFiles = prepareResult.committedFiles; @@ -3201,8 +3004,7 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, String s = "Flushing stores of " + this; status.setStatus(s); - if (LOG.isTraceEnabled()) - LOG.trace(s); + if (LOG.isTraceEnabled()) LOG.trace(s); // Any failure from here on out will be catastrophic requiring server // restart so wal content can be replayed and put back into the memstore. @@ -3244,23 +3046,22 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, MemStoreSize mss = prepareResult.totalFlushableSize.getMemStoreSize(); this.decrMemStoreSize(mss); - // Increase the size of this Region for the purposes of quota. Noop if quotas - // are disabled. + // Increase the size of this Region for the purposes of quota. Noop if quotas are disabled. // During startup, quota manager may not be initialized yet. if (rsServices != null) { RegionServerSpaceQuotaManager quotaManager = rsServices.getRegionServerSpaceQuotaManager(); if (quotaManager != null) { quotaManager.getRegionSizeStore().incrementRegionSize(this.getRegionInfo(), - flushedOutputFileSize); + flushedOutputFileSize); } } if (wal != null) { // write flush marker to WAL. If fail, we should throw DroppedSnapshotException FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.COMMIT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.getReplicationScope(), getRegionInfo(), desc, true, mvcc, - regionReplicationSink.orElse(null)); + regionReplicationSink.orElse(null)); } } catch (Throwable t) { // An exception here means that the snapshot was not persisted. @@ -3272,33 +3073,29 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, if (wal != null) { try { FlushDescriptor desc = ProtobufUtil.toFlushDescriptor(FlushAction.ABORT_FLUSH, - getRegionInfo(), flushOpSeqId, committedFiles); + getRegionInfo(), flushOpSeqId, committedFiles); WALUtil.writeFlushMarker(wal, this.replicationScope, getRegionInfo(), desc, false, mvcc, - null); + null); } catch (Throwable ex) { LOG.warn( - getRegionInfo().getEncodedName() + " : " + "failed writing ABORT_FLUSH marker to WAL", - ex); + getRegionInfo().getEncodedName() + " : " + "failed writing ABORT_FLUSH marker to WAL", + ex); // ignore this since we will be aborting the RS with DSE. } wal.abortCacheFlush(this.getRegionInfo().getEncodedNameAsBytes()); } DroppedSnapshotException dse = new DroppedSnapshotException( - "region: " + Bytes.toStringBinary(getRegionInfo().getRegionName()), t); + "region: " + Bytes.toStringBinary(getRegionInfo().getRegionName()), t); status.abort("Flush failed: " + StringUtils.stringifyException(t)); - // Callers for flushcache() should catch DroppedSnapshotException and abort the - // region server. - // However, since we may have the region read lock, we cannot call close(true) - // here since - // we cannot promote to a write lock. Instead we are setting closing so that all - // other region + // Callers for flushcache() should catch DroppedSnapshotException and abort the region server. + // However, since we may have the region read lock, we cannot call close(true) here since + // we cannot promote to a write lock. Instead we are setting closing so that all other region // operations except for close will be rejected. this.closing.set(true); if (rsServices != null) { - // This is a safeguard against the case where the caller fails to explicitly - // handle aborting + // This is a safeguard against the case where the caller fails to explicitly handle aborting rsServices.abort("Replay of WAL required. Forcing server shutdown", dse); } @@ -3328,27 +3125,26 @@ FlushResultImpl internalFlushCacheAndCommit(WAL wal, MonitoredTask status, MemStoreSize mss = prepareResult.totalFlushableSize.getMemStoreSize(); long memstoresize = this.memStoreSizing.getMemStoreSize().getDataSize(); String msg = "Finished flush of" + " dataSize ~" + StringUtils.byteDesc(mss.getDataSize()) + "/" - + mss.getDataSize() + ", heapSize ~" + StringUtils.byteDesc(mss.getHeapSize()) + "/" - + mss.getHeapSize() + ", currentSize=" + StringUtils.byteDesc(memstoresize) + "/" - + memstoresize + " for " + this.getRegionInfo().getEncodedName() + " in " + time - + "ms, sequenceid=" + flushOpSeqId + ", compaction requested=" + compactionRequested - + ((wal == null) ? "; wal=null" : ""); + + mss.getDataSize() + ", heapSize ~" + StringUtils.byteDesc(mss.getHeapSize()) + "/" + + mss.getHeapSize() + ", currentSize=" + StringUtils.byteDesc(memstoresize) + "/" + + memstoresize + " for " + this.getRegionInfo().getEncodedName() + " in " + time + + "ms, sequenceid=" + flushOpSeqId + ", compaction requested=" + compactionRequested + + ((wal == null) ? "; wal=null" : ""); LOG.info(msg); status.setStatus(msg); if (rsServices != null && rsServices.getMetrics() != null) { rsServices.getMetrics().updateFlush(getTableDescriptor().getTableName().getNameAsString(), - time, mss.getDataSize(), flushedOutputFileSize); + time, mss.getDataSize(), flushedOutputFileSize); } return new FlushResultImpl(compactionRequested - ? FlushResult.Result.FLUSHED_COMPACTION_NEEDED - : FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, flushOpSeqId); + ? FlushResult.Result.FLUSHED_COMPACTION_NEEDED + : FlushResult.Result.FLUSHED_NO_COMPACTION_NEEDED, flushOpSeqId); } /** * Method to safely get the next sequence number. - * * @return Next sequence number unassociated with any actual edit. */ protected long getNextSequenceId(final WAL wal) throws IOException { @@ -3368,12 +3164,12 @@ public RegionScannerImpl getScanner(Scan scan) throws IOException { @Override public RegionScannerImpl getScanner(Scan scan, List additionalScanners) - throws IOException { + throws IOException { return getScanner(scan, additionalScanners, HConstants.NO_NONCE, HConstants.NO_NONCE); } private RegionScannerImpl getScanner(Scan scan, List additionalScanners, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { return TraceUtil.trace(() -> { startRegionOperation(Operation.SCAN); try { @@ -3396,7 +3192,7 @@ private RegionScannerImpl getScanner(Scan scan, List additional } protected RegionScannerImpl instantiateRegionScanner(Scan scan, - List additionalScanners, long nonceGroup, long nonce) throws IOException { + List additionalScanners, long nonceGroup, long nonce) throws IOException { if (scan.isReversed()) { if (scan.getFilter() != null) { scan.getFilter().setReversed(true); @@ -3408,7 +3204,6 @@ protected RegionScannerImpl instantiateRegionScanner(Scan scan, /** * Prepare a delete for a row mutation processor - * * @param delete The passed delete is modified by this method. WARNING! */ private void prepareDelete(Delete delete) throws IOException { @@ -3435,8 +3230,7 @@ public void delete(Delete delete) throws IOException { checkResources(); startRegionOperation(Operation.DELETE); try { - // All edits for the given row (across all column families) must happen - // atomically. + // All edits for the given row (across all column families) must happen atomically. return mutate(delete); } finally { closeRegionOperation(Operation.DELETE); @@ -3450,7 +3244,7 @@ public void delete(Delete delete) throws IOException { * Caller should have the row and region locks. */ private void prepareDeleteTimestamps(Mutation mutation, Map> familyMap, - byte[] byteNow) throws IOException { + byte[] byteNow) throws IOException { for (Map.Entry> e : familyMap.entrySet()) { byte[] family = e.getKey(); @@ -3463,7 +3257,9 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> Cell cell = cells.get(i); // Check if time is LATEST, change to time of most recent addition if so // This is expensive. - if (cell.getTimestamp() == HConstants.LATEST_TIMESTAMP && PrivateCellUtil.isDeleteType(cell)) { + if ( + cell.getTimestamp() == HConstants.LATEST_TIMESTAMP && PrivateCellUtil.isDeleteType(cell) + ) { byte[] qual = CellUtil.cloneQualifier(cell); Integer count = kvCount.get(qual); @@ -3478,7 +3274,9 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> get.readVersions(count); get.addColumn(family, qual); if (coprocessorHost != null) { - if (!coprocessorHost.prePrepareTimeStampForDeleteVersion(mutation, cell, byteNow, get)) { + if ( + !coprocessorHost.prePrepareTimeStampForDeleteVersion(mutation, cell, byteNow, get) + ) { updateDeleteLatestVersionTimestamp(cell, get, count, byteNow); } } else { @@ -3492,7 +3290,7 @@ private void prepareDeleteTimestamps(Mutation mutation, Map> } private void updateDeleteLatestVersionTimestamp(Cell cell, Get get, int count, byte[] byteNow) - throws IOException { + throws IOException { try (RegionScanner scanner = getScanner(new Scan(get))) { // NOTE: Please don't use HRegion.get() instead, // because it will copy cells to heap. See HBASE-26036 @@ -3524,8 +3322,7 @@ public void put(Put put) throws IOException { checkResources(); startRegionOperation(Operation.PUT); try { - // All edits for the given row (across all column families) must happen - // atomically. + // All edits for the given row (across all column families) must happen atomically. return mutate(put); } finally { closeRegionOperation(Operation.PUT); @@ -3534,18 +3331,15 @@ public void put(Put put) throws IOException { } /** - * Class that tracks the progress of a batch operations, accumulating status - * codes and tracking - * the index at which processing is proceeding. These batch operations may get - * split into + * Class that tracks the progress of a batch operations, accumulating status codes and tracking + * the index at which processing is proceeding. These batch operations may get split into * mini-batches for processing. */ private abstract static class BatchOperation { protected final T[] operations; protected final OperationStatus[] retCodeDetails; protected final WALEdit[] walEditsFromCoprocessors; - // reference family cell maps directly so coprocessors can mutate them if - // desired + // reference family cell maps directly so coprocessors can mutate them if desired protected final Map>[] familyCellMaps; // For Increment/Append operations protected final Result[] results; @@ -3586,7 +3380,7 @@ interface Visitor { * Helper method for visiting pending/ all batch operations */ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Visitor visitor) - throws IOException { + throws IOException { assert lastIndexExclusive <= this.size(); for (int i = nextIndexToProcess; i < lastIndexExclusive; i++) { if (!pendingOnly || isOperationPending(i)) { @@ -3604,8 +3398,7 @@ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Vi public abstract long getNonce(int index); /** - * This method is potentially expensive and useful mostly for non-replay CP - * path. + * This method is potentially expensive and useful mostly for non-replay CP path. */ public abstract Mutation[] getMutationsForCoprocs(); @@ -3618,48 +3411,42 @@ public void visitBatchOperations(boolean pendingOnly, int lastIndexExclusive, Vi public abstract void closeRegionOperation() throws IOException; /** - * Validates each mutation and prepares a batch for write. If necessary - * (non-replay case), runs - * CP prePut()/preDelete()/preIncrement()/preAppend() hooks for all mutations in - * a batch. This - * is intended to operate on entire batch and will be called from outside of - * class to check and + * Validates each mutation and prepares a batch for write. If necessary (non-replay case), runs + * CP prePut()/preDelete()/preIncrement()/preAppend() hooks for all mutations in a batch. This + * is intended to operate on entire batch and will be called from outside of class to check and * prepare batch. This can be implemented by calling helper method * {@link #checkAndPrepareMutation(int, long)} in a 'for' loop over mutations. */ public abstract void checkAndPrepare() throws IOException; /** - * Implement any Put request specific check and prepare logic here. Please refer - * to + * Implement any Put request specific check and prepare logic here. Please refer to * {@link #checkAndPrepareMutation(Mutation, long)} for how its used. */ protected abstract void checkAndPreparePut(final Put p) throws IOException; /** - * If necessary, calls preBatchMutate() CP hook for a mini-batch and updates - * metrics, cell + * If necessary, calls preBatchMutate() CP hook for a mini-batch and updates metrics, cell * count, tags and timestamp for all cells of all operations in a mini-batch. */ public abstract void prepareMiniBatchOperations( - MiniBatchOperationInProgress miniBatchOp, long timestamp, - final List acquiredRowLocks) throws IOException; + MiniBatchOperationInProgress miniBatchOp, long timestamp, + final List acquiredRowLocks) throws IOException; /** * Write mini-batch operations to MemStore */ public abstract WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, - long now) throws IOException; + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, + long now) throws IOException; protected void writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final long writeNumber) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final long writeNumber) + throws IOException { MemStoreSizing memStoreAccounting = new NonThreadSafeMemStoreSizing(); visitBatchOperations(true, miniBatchOp.getLastIndexExclusive(), (int index) -> { // We need to update the sequence id for following reasons. - // 1) If the op is in replay mode, FSWALEntry#stampRegionSequenceId won't stamp - // sequence id. + // 1) If the op is in replay mode, FSWALEntry#stampRegionSequenceId won't stamp sequence id. // 2) If no WAL, FSWALEntry won't be used // we use durability of the original mutation for the mutation passed by CP. if (isInReplay() || getMutation(index).getDurability() == Durability.SKIP_WAL) { @@ -3670,7 +3457,7 @@ protected void writeMiniBatchOperationsToMemStore( }); // update memStore size region.incMemStoreSize(memStoreAccounting.getDataSize(), memStoreAccounting.getHeapSize(), - memStoreAccounting.getOffHeapSize(), memStoreAccounting.getCellsCount()); + memStoreAccounting.getOffHeapSize(), memStoreAccounting.getCellsCount()); } public boolean isDone() { @@ -3695,17 +3482,14 @@ boolean isAtomic() { } /** - * Helper method that checks and prepares only one mutation. This can be used to - * implement + * Helper method that checks and prepares only one mutation. This can be used to implement * {@link #checkAndPrepare()} for entire Batch. NOTE: As CP - * prePut()/preDelete()/preIncrement()/preAppend() hooks may modify mutations, - * this method - * should be called after prePut()/preDelete()/preIncrement()/preAppend() CP - * hooks are run for + * prePut()/preDelete()/preIncrement()/preAppend() hooks may modify mutations, this method + * should be called after prePut()/preDelete()/preIncrement()/preAppend() CP hooks are run for * the mutation */ protected void checkAndPrepareMutation(Mutation mutation, final long timestamp) - throws IOException { + throws IOException { region.checkRow(mutation.getRow(), "batchMutate"); if (mutation instanceof Put) { // Check the families in the put. If bad, skip this one. @@ -3728,8 +3512,7 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep familyCellMaps[index] = mutation.getFamilyCellMap(); } - // store durability for the batch (highest durability of all operations in the - // batch) + // store durability for the batch (highest durability of all operations in the batch) Durability tmpDur = region.getEffectiveDurability(mutation.getDurability()); if (tmpDur.ordinal() > durability.ordinal()) { durability = tmpDur; @@ -3742,7 +3525,8 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, nscfe); observedExceptions.sawNoSuchFamily(); } - retCodeDetails[index] = new OperationStatus(OperationStatusCode.BAD_FAMILY, nscfe.getMessage()); + retCodeDetails[index] = + new OperationStatus(OperationStatusCode.BAD_FAMILY, nscfe.getMessage()); if (isAtomic()) { // fail, atomic means all or none throw nscfe; } @@ -3754,7 +3538,8 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, fsce); observedExceptions.sawFailedSanityCheck(); } - retCodeDetails[index] = new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, fsce.getMessage()); + retCodeDetails[index] = + new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, fsce.getMessage()); if (isAtomic()) { throw fsce; } @@ -3766,7 +3551,8 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep LOG.warn(msg, we); observedExceptions.sawWrongRegion(); } - retCodeDetails[index] = new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, we.getMessage()); + retCodeDetails[index] = + new OperationStatus(OperationStatusCode.SANITY_CHECK_FAILURE, we.getMessage()); if (isAtomic()) { throw we; } @@ -3774,18 +3560,14 @@ protected void checkAndPrepareMutation(int index, long timestamp) throws IOExcep } /** - * Creates Mini-batch of all operations [nextIndexToProcess, lastIndexExclusive) - * for which a row - * lock can be acquired. All mutations with locked rows are considered to be - * In-progress - * operations and hence the name {@link MiniBatchOperationInProgress}. Mini - * batch is window over + * Creates Mini-batch of all operations [nextIndexToProcess, lastIndexExclusive) for which a row + * lock can be acquired. All mutations with locked rows are considered to be In-progress + * operations and hence the name {@link MiniBatchOperationInProgress}. Mini batch is window over * {@link BatchOperation} and contains contiguous pending operations. - * * @param acquiredRowLocks keeps track of rowLocks acquired. */ - public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List acquiredRowLocks) - throws IOException { + public MiniBatchOperationInProgress + lockRowsAndBuildMiniBatch(List acquiredRowLocks) throws IOException { int readyToWriteCount = 0; int lastIndexExclusive = 0; RowLock prevRowLock = null; @@ -3800,16 +3582,14 @@ public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List> curFamilyCellMap = getMutation(lastIndexExclusive).getFamilyCellMap(); + Map> curFamilyCellMap = + getMutation(lastIndexExclusive).getFamilyCellMap(); try { - // start the protector before acquiring row lock considering performance, and - // will finish + // start the protector before acquiring row lock considering performance, and will finish // it when encountering exception region.storeHotnessProtector.start(curFamilyCellMap); } catch (RegionTooBusyException rtbe) { @@ -3817,8 +3597,8 @@ public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List lockRowsAndBuildMiniBatch(List lockRowsAndBuildMiniBatch(List createMiniBatch(final int lastIndexExclusive, - final int readyToWriteCount) { + final int readyToWriteCount) { return new MiniBatchOperationInProgress<>(getMutationsForCoprocs(), retCodeDetails, - walEditsFromCoprocessors, nextIndexToProcess, lastIndexExclusive, readyToWriteCount); + walEditsFromCoprocessors, nextIndexToProcess, lastIndexExclusive, readyToWriteCount); } protected WALEdit createWALEdit(final MiniBatchOperationInProgress miniBatchOp) { @@ -3882,12 +3662,11 @@ protected WALEdit createWALEdit(final MiniBatchOperationInProgress min } /** - * Builds separate WALEdit per nonce by applying input mutations. If WALEdits - * from CP are + * Builds separate WALEdit per nonce by applying input mutations. If WALEdits from CP are * present, they are merged to result WALEdit. */ - public List> buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) - throws IOException { + public List> + buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) throws IOException { List> walEdits = new ArrayList<>(); visitBatchOperations(true, nextIndexToProcess + miniBatchOp.size(), new Visitor() { @@ -3900,8 +3679,7 @@ public boolean visit(int index) throws IOException { if (region.getEffectiveDurability(m.getDurability()) == Durability.SKIP_WAL) { region.recordMutationWithoutWal(m.getFamilyCellMap()); /** - * Here is for HBASE-26993,in order to make the new framework for region - * replication + * Here is for HBASE-26993,in order to make the new framework for region replication * could work for SKIP_WAL, we save the {@link Mutation} which * {@link Mutation#getDurability} is {@link Durability#SKIP_WAL} in miniBatchOp. */ @@ -3909,17 +3687,18 @@ public boolean visit(int index) throws IOException { return true; } - // the batch may contain multiple nonce keys (replay case). If so, write WALEdit - // for each. + // the batch may contain multiple nonce keys (replay case). If so, write WALEdit for each. // Given how nonce keys are originally written, these should be contiguous. - // They don't have to be, it will still work, just write more WALEdits than - // needed. + // They don't have to be, it will still work, just write more WALEdits than needed. long nonceGroup = getNonceGroup(index); long nonce = getNonce(index); - if (curWALEditForNonce == null + if ( + curWALEditForNonce == null || curWALEditForNonce.getFirst().getNonceGroup() != nonceGroup - || curWALEditForNonce.getFirst().getNonce() != nonce) { - curWALEditForNonce = new Pair<>(new NonceKey(nonceGroup, nonce), createWALEdit(miniBatchOp)); + || curWALEditForNonce.getFirst().getNonce() != nonce + ) { + curWALEditForNonce = + new Pair<>(new NonceKey(nonceGroup, nonce), createWALEdit(miniBatchOp)); walEdits.add(curWALEditForNonce); } WALEdit walEdit = curWALEditForNonce.getSecond(); @@ -3935,47 +3714,46 @@ public boolean visit(int index) throws IOException { } protected void addNonSkipWALMutationsToWALEdit( - final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, - List cellsFromCP, Map> familyCellMap) { + final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, + List cellsFromCP, Map> familyCellMap) { doAddCellsToWALEdit(walEdit, cellsFromCP, familyCellMap); } protected static void doAddCellsToWALEdit(WALEdit walEdit, List cellsFromCP, - Map> familyCellMap) { + Map> familyCellMap) { walEdit.add(cellsFromCP); walEdit.add(familyCellMap); } protected abstract void cacheSkipWALMutationForRegionReplication( - final MiniBatchOperationInProgress miniBatchOp, - List> walEdits, Map> familyCellMap); + final MiniBatchOperationInProgress miniBatchOp, + List> walEdits, Map> familyCellMap); /** - * This method completes mini-batch operations by calling postBatchMutate() CP - * hook (if + * This method completes mini-batch operations by calling postBatchMutate() CP hook (if * required) and completing mvcc. */ public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { if (writeEntry != null) { region.mvcc.completeAndWait(writeEntry); } } public void doPostOpCleanupForMiniBatch( - final MiniBatchOperationInProgress miniBatchOp, final WALEdit walEdit, - boolean success) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WALEdit walEdit, + boolean success) throws IOException { doFinishHotnessProtector(miniBatchOp); } - private void doFinishHotnessProtector(final MiniBatchOperationInProgress miniBatchOp) { + private void + doFinishHotnessProtector(final MiniBatchOperationInProgress miniBatchOp) { // check and return if the protector is not enabled if (!region.storeHotnessProtector.isEnable()) { return; } - // miniBatchOp is null, if and only if lockRowsAndBuildMiniBatch throwing - // exception. + // miniBatchOp is null, if and only if lockRowsAndBuildMiniBatch throwing exception. // This case was handled. if (miniBatchOp == null) { return; @@ -3991,8 +3769,7 @@ private void doFinishHotnessProtector(final MiniBatchOperationInProgressedits to the memstore. This handles - * the consistency - * control on its own, but the caller should already have locked - * updatesLock.readLock(). This + * Atomically apply the given map of family->edits to the memstore. This handles the consistency + * control on its own, but the caller should already have locked updatesLock.readLock(). This * also does not check the families for validity. - * * @param familyMap Map of Cells by family */ protected void applyFamilyMapToMemStore(Map> familyMap, - MemStoreSizing memstoreAccounting) { + MemStoreSizing memstoreAccounting) { for (Map.Entry> e : familyMap.entrySet()) { byte[] family = e.getKey(); List cells = e.getValue(); @@ -4020,8 +3794,7 @@ protected void applyFamilyMapToMemStore(Map> familyMap, } /** - * Batch of mutation operations. Base class is shared with - * {@link ReplayBatchOperation} as most of + * Batch of mutation operations. Base class is shared with {@link ReplayBatchOperation} as most of * the logic is same. */ private static class MutationBatchOperation extends BatchOperation { @@ -4033,7 +3806,7 @@ private static class MutationBatchOperation extends BatchOperation { private boolean regionReplicateEnable; public MutationBatchOperation(final HRegion region, Mutation[] operations, boolean atomic, - long nonceGroup, long nonce) { + long nonceGroup, long nonce) { super(region, operations); this.atomic = atomic; this.nonceGroup = nonceGroup; @@ -4109,10 +3882,8 @@ public boolean visit(int index) throws IOException { } } if (isOperationPending(index)) { - // TODO: Currently validation is done with current time before acquiring locks - // and - // updates are done with different timestamps after acquiring locks. This - // behavior is + // TODO: Currently validation is done with current time before acquiring locks and + // updates are done with different timestamps after acquiring locks. This behavior is // inherited from the code prior to this change. Can this be changed? checkAndPrepareMutation(index, now); } @@ -4120,11 +3891,9 @@ public boolean visit(int index) throws IOException { } }); - // FIXME: we may update metrics twice! here for all operations bypassed by CP - // and later in + // FIXME: we may update metrics twice! here for all operations bypassed by CP and later in // normal processing. - // Update metrics in same way as it is done when we go the normal processing - // route (we now + // Update metrics in same way as it is done when we go the normal processing route (we now // update general metrics though a Coprocessor did the work). if (region.metricsRegion != null) { if (metrics[0] > 0) { @@ -4148,7 +3917,7 @@ public boolean visit(int index) throws IOException { @Override public void prepareMiniBatchOperations(MiniBatchOperationInProgress miniBatchOp, - long timestamp, final List acquiredRowLocks) throws IOException { + long timestamp, final List acquiredRowLocks) throws IOException { // For nonce operations canProceed = startNonceOperation(); @@ -4192,7 +3961,7 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi } if (result != null) { retCodeDetails[index] = new OperationStatus(OperationStatusCode.SUCCESS, - returnResults ? result : Result.EMPTY_RESULT); + returnResults ? result : Result.EMPTY_RESULT); return true; } @@ -4231,17 +4000,19 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi /** * Starts the nonce operation for a mutation, if needed. - * * @return whether to proceed this mutation. */ private boolean startNonceOperation() throws IOException { - if (region.rsServices == null || region.rsServices.getNonceManager() == null - || nonce == HConstants.NO_NONCE) { + if ( + region.rsServices == null || region.rsServices.getNonceManager() == null + || nonce == HConstants.NO_NONCE + ) { return true; } boolean canProceed; try { - canProceed = region.rsServices.getNonceManager().startOperation(nonceGroup, nonce, region.rsServices); + canProceed = + region.rsServices.getNonceManager().startOperation(nonceGroup, nonce, region.rsServices); } catch (InterruptedException ex) { throw new InterruptedIOException("Nonce start operation interrupted"); } @@ -4250,12 +4021,13 @@ private boolean startNonceOperation() throws IOException { /** * Ends nonce operation for a mutation, if needed. - * * @param success Whether the operation for this nonce has succeeded. */ private void endNonceOperation(boolean success) { - if (region.rsServices != null && region.rsServices.getNonceManager() != null - && nonce != HConstants.NO_NONCE) { + if ( + region.rsServices != null && region.rsServices.getNonceManager() != null + && nonce != HConstants.NO_NONCE + ) { region.rsServices.getNonceManager().endOperation(nonceGroup, nonce, success); } } @@ -4269,6 +4041,8 @@ private static Get toGet(final Mutation mutation) throws IOException { get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } if (mutation instanceof Increment) { + Cell cell = cellScanner.current(); + get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); // Increment Increment increment = (Increment) mutation; get.setTimeRange(increment.getTimeRange().getMin(), increment.getTimeRange().getMax()); @@ -4284,7 +4058,7 @@ private static Get toGet(final Mutation mutation) throws IOException { } private Map> reckonDeltas(Mutation mutation, List results, long now) - throws IOException { + throws IOException { assert mutation instanceof Increment || mutation instanceof Append; Map> ret = new TreeMap<>(Bytes.BYTES_COMPARATOR); // Process a Store/family at a time. @@ -4292,7 +4066,8 @@ private Map> reckonDeltas(Mutation mutation, List resul final byte[] columnFamilyName = entry.getKey(); List deltas = entry.getValue(); // Reckon for the Store what to apply to WAL and MemStore. - List toApply = reckonDeltasByStore(region.stores.get(columnFamilyName), mutation, now, deltas, results); + List toApply = + reckonDeltasByStore(region.stores.get(columnFamilyName), mutation, now, deltas, results); if (!toApply.isEmpty()) { for (Cell cell : toApply) { HStore store = region.getStore(cell); @@ -4300,7 +4075,7 @@ private Map> reckonDeltas(Mutation mutation, List resul region.checkFamily(CellUtil.cloneFamily(cell)); } else { ret.computeIfAbsent(store.getColumnFamilyDescriptor().getName(), - key -> new ArrayList<>()).add(cell); + key -> new ArrayList<>()).add(cell); } } } @@ -4309,32 +4084,24 @@ private Map> reckonDeltas(Mutation mutation, List resul } /** - * Reckon the Cells to apply to WAL, memstore, and to return to the Client in - * passed column - * family/Store. Does Get of current value and then adds passed in deltas for - * this Store + * Reckon the Cells to apply to WAL, memstore, and to return to the Client in passed column + * family/Store. Does Get of current value and then adds passed in deltas for this Store * returning the result. - * * @param mutation The encompassing Mutation object - * @param deltas Changes to apply to this Store; either increment amount or - * data to append - * @param results In here we accumulate all the Cells we are to return to the - * client. If null, + * @param deltas Changes to apply to this Store; either increment amount or data to append + * @param results In here we accumulate all the Cells we are to return to the client. If null, * client doesn't want results returned. - * @return Resulting Cells after deltas have been applied to - * current values. Side + * @return Resulting Cells after deltas have been applied to current values. Side * effect is our filling out of the results List. */ private List reckonDeltasByStore(HStore store, Mutation mutation, long now, - List deltas, List results) throws IOException { + List deltas, List results) throws IOException { assert mutation instanceof Increment || mutation instanceof Append; byte[] columnFamily = store.getColumnFamilyDescriptor().getName(); List> cellPairs = new ArrayList<>(deltas.size()); - // Sort the cells so that they match the order that they appear in the Get - // results. - // Otherwise, we won't be able to find the existing values if the cells are not - // specified + // Sort the cells so that they match the order that they appear in the Get results. + // Otherwise, we won't be able to find the existing values if the cells are not specified // in order by the client since cells are in an array list. deltas.sort(store.getComparator()); @@ -4359,67 +4126,66 @@ private List reckonDeltasByStore(HStore store, Mutation mutation, long now // because it will copy cells to heap. See HBASE-26036 List currentValues = new ArrayList<>(); scanner.next(currentValues); - // Iterate the input columns and update existing values if they were found, - // otherwise + // Iterate the input columns and update existing values if they were found, otherwise // add new column initialized to the delta amount int currentValuesIndex = 0; for (int i = 0; i < deltas.size(); i++) { Cell delta = deltas.get(i); Cell currentValue = null; - if (currentValuesIndex < currentValues.size() - && CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta)) { + if ( + currentValuesIndex < currentValues.size() + && CellUtil.matchingQualifier(currentValues.get(currentValuesIndex), delta) + ) { currentValue = currentValues.get(currentValuesIndex); if (i < (deltas.size() - 1) && !CellUtil.matchingQualifier(delta, deltas.get(i + 1))) { currentValuesIndex++; } } - // Switch on whether this an increment or an append building the new Cell to - // apply. + // Switch on whether this an increment or an append building the new Cell to apply. Cell newCell; if (mutation instanceof Increment) { long deltaAmount = getLongValue(delta); - final long newValue = currentValue == null ? deltaAmount : getLongValue(currentValue) + deltaAmount; + final long newValue = + currentValue == null ? deltaAmount : getLongValue(currentValue) + deltaAmount; newCell = reckonDelta(delta, currentValue, columnFamily, now, mutation, - (oldCell) -> Bytes.toBytes(newValue)); + (oldCell) -> Bytes.toBytes(newValue)); } else { newCell = reckonDelta(delta, currentValue, columnFamily, now, mutation, - (oldCell) -> ByteBuffer - .wrap(new byte[delta.getValueLength() + oldCell.getValueLength()]) - .put(oldCell.getValueArray(), oldCell.getValueOffset(), oldCell.getValueLength()) - .put(delta.getValueArray(), delta.getValueOffset(), delta.getValueLength()) - .array()); + (oldCell) -> ByteBuffer + .wrap(new byte[delta.getValueLength() + oldCell.getValueLength()]) + .put(oldCell.getValueArray(), oldCell.getValueOffset(), oldCell.getValueLength()) + .put(delta.getValueArray(), delta.getValueOffset(), delta.getValueLength()) + .array()); } if (region.maxCellSize > 0) { int newCellSize = PrivateCellUtil.estimatedSerializedSizeOf(newCell); if (newCellSize > region.maxCellSize) { String msg = "Cell with size " + newCellSize + " exceeds limit of " - + region.maxCellSize + " bytes in region " + this; + + region.maxCellSize + " bytes in region " + this; LOG.debug(msg); throw new DoNotRetryIOException(msg); } } cellPairs.add(new Pair<>(currentValue, newCell)); - // Add to results to get returned to the Client. If null, cilent does not want - // results. + // Add to results to get returned to the Client. If null, cilent does not want results. if (results != null) { results.add(newCell); } } - // Give coprocessors a chance to update the new cells before apply to WAL or - // memstore + // Give coprocessors a chance to update the new cells before apply to WAL or memstore if (region.coprocessorHost != null) { // Here the operation must be increment or append. cellPairs = mutation instanceof Increment - ? region.coprocessorHost.postIncrementBeforeWAL(mutation, cellPairs) - : region.coprocessorHost.postAppendBeforeWAL(mutation, cellPairs); + ? region.coprocessorHost.postIncrementBeforeWAL(mutation, cellPairs) + : region.coprocessorHost.postAppendBeforeWAL(mutation, cellPairs); } } return cellPairs.stream().map(Pair::getSecond).collect(Collectors.toList()); } private static Cell reckonDelta(final Cell delta, final Cell currentCell, - final byte[] columnFamily, final long now, Mutation mutation, Function supplier) - throws IOException { + final byte[] columnFamily, final long now, Mutation mutation, Function supplier) + throws IOException { // Forward any tags found on the delta. List tags = TagUtil.carryForwardTags(delta); if (currentCell != null) { @@ -4427,13 +4193,13 @@ private static Cell reckonDelta(final Cell delta, final Cell currentCell, tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); byte[] newValue = supplier.apply(currentCell); return ExtendedCellBuilderFactory.create(CellBuilderType.SHALLOW_COPY) - .setRow(mutation.getRow(), 0, mutation.getRow().length) - .setFamily(columnFamily, 0, columnFamily.length) - // copy the qualifier if the cell is located in shared memory. - .setQualifier(CellUtil.cloneQualifier(delta)) - .setTimestamp(Math.max(currentCell.getTimestamp() + 1, now)) - .setType(KeyValue.Type.Put.getCode()).setValue(newValue, 0, newValue.length) - .setTags(TagUtil.fromList(tags)).build(); + .setRow(mutation.getRow(), 0, mutation.getRow().length) + .setFamily(columnFamily, 0, columnFamily.length) + // copy the qualifier if the cell is located in shared memory. + .setQualifier(CellUtil.cloneQualifier(delta)) + .setTimestamp(Math.max(currentCell.getTimestamp() + 1, now)) + .setType(KeyValue.Type.Put.getCode()).setValue(newValue, 0, newValue.length) + .setTags(TagUtil.fromList(tags)).build(); } else { tags = TagUtil.carryForwardTTLTag(tags, mutation.getTTL()); PrivateCellUtil.updateLatestStamp(delta, now); @@ -4452,8 +4218,8 @@ private static long getLongValue(final Cell cell) throws DoNotRetryIOException { } @Override - public List> buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) - throws IOException { + public List> + buildWALEdits(final MiniBatchOperationInProgress miniBatchOp) throws IOException { List> walEdits = super.buildWALEdits(miniBatchOp); // for MutationBatchOperation, more than one nonce is not allowed if (walEdits.size() > 1) { @@ -4463,30 +4229,28 @@ public List> buildWALEdits(final MiniBatchOperationInPro } /** - * Here is for HBASE-26993,in order to make the new framework for region - * replication could work - * for SKIP_WAL, we save the {@link Mutation} which - * {@link Mutation#getDurability} is + * Here is for HBASE-26993,in order to make the new framework for region replication could work + * for SKIP_WAL, we save the {@link Mutation} which {@link Mutation#getDurability} is * {@link Durability#SKIP_WAL} in miniBatchOp. */ @Override protected void cacheSkipWALMutationForRegionReplication( - MiniBatchOperationInProgress miniBatchOp, - List> nonceKeyAndWALEdits, Map> familyCellMap) { + MiniBatchOperationInProgress miniBatchOp, + List> nonceKeyAndWALEdits, Map> familyCellMap) { if (!this.regionReplicateEnable) { return; } - WALEdit walEditForReplicateIfExistsSkipWAL = miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); + WALEdit walEditForReplicateIfExistsSkipWAL = + miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); /** - * When there is a SKIP_WAL {@link Mutation},we create a new {@link WALEdit} for - * replicating - * to region replica,first we fill the existing {@link WALEdit} to it and then - * add the + * When there is a SKIP_WAL {@link Mutation},we create a new {@link WALEdit} for replicating + * to region replica,first we fill the existing {@link WALEdit} to it and then add the * {@link Mutation} which is SKIP_WAL to it. */ if (walEditForReplicateIfExistsSkipWAL == null) { - walEditForReplicateIfExistsSkipWAL = this.createWALEditForReplicateSkipWAL(miniBatchOp, nonceKeyAndWALEdits); + walEditForReplicateIfExistsSkipWAL = + this.createWALEditForReplicateSkipWAL(miniBatchOp, nonceKeyAndWALEdits); miniBatchOp.setWalEditForReplicateIfExistsSkipWAL(walEditForReplicateIfExistsSkipWAL); } walEditForReplicateIfExistsSkipWAL.add(familyCellMap); @@ -4494,8 +4258,8 @@ protected void cacheSkipWALMutationForRegionReplication( } private WALEdit createWALEditForReplicateSkipWAL( - MiniBatchOperationInProgress miniBatchOp, - List> nonceKeyAndWALEdits) { + MiniBatchOperationInProgress miniBatchOp, + List> nonceKeyAndWALEdits) { if (nonceKeyAndWALEdits.isEmpty()) { return this.createWALEdit(miniBatchOp); } @@ -4507,22 +4271,20 @@ private WALEdit createWALEditForReplicateSkipWAL( @Override protected void addNonSkipWALMutationsToWALEdit( - final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, - List cellsFromCP, Map> familyCellMap) { + final MiniBatchOperationInProgress miniBatchOp, WALEdit walEdit, + List cellsFromCP, Map> familyCellMap) { super.addNonSkipWALMutationsToWALEdit(miniBatchOp, walEdit, cellsFromCP, familyCellMap); - WALEdit walEditForReplicateIfExistsSkipWAL = miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); + WALEdit walEditForReplicateIfExistsSkipWAL = + miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(); if (walEditForReplicateIfExistsSkipWAL == null) { return; } /** - * When walEditForReplicateIfExistsSkipWAL is not null,it means there exists - * SKIP_WAL + * When walEditForReplicateIfExistsSkipWAL is not null,it means there exists SKIP_WAL * {@link Mutation} and we create a new {@link WALEdit} in - * {@link MutationBatchOperation#cacheSkipWALMutationForReplicateRegionReplica} - * for - * replicating to region replica, so here we also add non - * SKIP_WAL{@link Mutation}s to + * {@link MutationBatchOperation#cacheSkipWALMutationForReplicateRegionReplica} for + * replicating to region replica, so here we also add non SKIP_WAL{@link Mutation}s to * walEditForReplicateIfExistsSkipWAL. */ doAddCellsToWALEdit(walEditForReplicateIfExistsSkipWAL, cellsFromCP, familyCellMap); @@ -4530,8 +4292,8 @@ protected void addNonSkipWALMutationsToWALEdit( @Override public WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, @Nullable WriteEntry writeEntry, - long now) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, @Nullable WriteEntry writeEntry, + long now) throws IOException { boolean newWriteEntry = false; if (writeEntry == null) { writeEntry = region.mvcc.begin(); @@ -4540,15 +4302,11 @@ public WriteEntry writeMiniBatchOperationsToMemStore( super.writeMiniBatchOperationsToMemStore(miniBatchOp, writeEntry.getWriteNumber()); if (newWriteEntry) { /** - * Here is for HBASE-26993 case 2,all {@link Mutation}s are - * {@link Durability#SKIP_WAL}. In - * order to make the new framework for region replication could work for - * SKIP_WAL,because - * there is no {@link RegionReplicationSink#add} attached in - * {@link HRegion#doWALAppend},so + * Here is for HBASE-26993 case 2,all {@link Mutation}s are {@link Durability#SKIP_WAL}. In + * order to make the new framework for region replication could work for SKIP_WAL,because + * there is no {@link RegionReplicationSink#add} attached in {@link HRegion#doWALAppend},so * here we get {@link WALEdit} from - * {@link MiniBatchOperationInProgress#getWalEditForReplicateIfExistsSkipWAL} - * and attach + * {@link MiniBatchOperationInProgress#getWalEditForReplicateIfExistsSkipWAL} and attach * {@link RegionReplicationSink#add} to the new mvcc writeEntry. */ attachRegionReplicationToMVCCEntry(miniBatchOp, writeEntry, now); @@ -4566,8 +4324,8 @@ private WALKeyImpl createWALKey(long now) { * {@link RegionReplicationSink#add} to the mvccWriteEntry. */ private void attachRegionReplicationToMVCCEntry( - final MiniBatchOperationInProgress miniBatchOp, WriteEntry mvccWriteEntry, long now) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, WriteEntry mvccWriteEntry, long now) + throws IOException { if (!this.regionReplicateEnable) { return; } @@ -4576,13 +4334,13 @@ private void attachRegionReplicationToMVCCEntry( final WALKeyImpl walKey = this.createWALKey(now); walKey.setWriteEntry(mvccWriteEntry); region.doAttachReplicateRegionReplicaAction(walKey, - miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(), mvccWriteEntry); + miniBatchOp.getWalEditForReplicateIfExistsSkipWAL(), mvccWriteEntry); } @Override public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { // TODO: can it be done after completing mvcc? // calling the post CP hook for batch mutation if (region.coprocessorHost != null) { @@ -4593,14 +4351,14 @@ public void completeMiniBatchOperations( if (nonce != HConstants.NO_NONCE) { if (region.rsServices != null && region.rsServices.getNonceManager() != null) { region.rsServices.getNonceManager().addMvccToOperationContext(nonceGroup, nonce, - writeEntry.getWriteNumber()); + writeEntry.getWriteNumber()); } } } @Override public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress miniBatchOp, - final WALEdit walEdit, boolean success) throws IOException { + final WALEdit walEdit, boolean success) throws IOException { super.doPostOpCleanupForMiniBatch(miniBatchOp, walEdit, success); if (miniBatchOp != null) { @@ -4615,14 +4373,18 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m } else if (m instanceof Delete) { region.coprocessorHost.postDelete((Delete) m, walEdit); } else if (m instanceof Increment) { - Result result = region.getCoprocessorHost().postIncrement((Increment) m, results[i], walEdit); + Result result = + region.getCoprocessorHost().postIncrement((Increment) m, results[i], walEdit); if (result != results[i]) { - retCodeDetails[i] = new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); + retCodeDetails[i] = + new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); } } else if (m instanceof Append) { - Result result = region.getCoprocessorHost().postAppend((Append) m, results[i], walEdit); + Result result = + region.getCoprocessorHost().postAppend((Append) m, results[i], walEdit); if (result != results[i]) { - retCodeDetails[i] = new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); + retCodeDetails[i] = + new OperationStatus(retCodeDetails[i].getOperationStatusCode(), result); } } } @@ -4650,8 +4412,7 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m // if they were then keep them. If they were not then pass a null. // null will be treated as unknown. // Total time taken might be involving Puts, Deletes, Increments and Appends. - // Split the time for puts and deletes based on the total number of Puts, - // Deletes, + // Split the time for puts and deletes based on the total number of Puts, Deletes, // Increments and Appends. if (region.metricsRegion != null) { if (miniBatchOp.getNumOfPuts() > 0) { @@ -4676,20 +4437,17 @@ public void doPostOpCleanupForMiniBatch(MiniBatchOperationInProgress m if (region.coprocessorHost != null) { // call the coprocessor hook to do any finalization steps after the put is done region.coprocessorHost.postBatchMutateIndispensably( - miniBatchOp != null ? miniBatchOp : createMiniBatch(size(), 0), success); + miniBatchOp != null ? miniBatchOp : createMiniBatch(size(), 0), success); } } /** - * Runs prePut/preDelete/preIncrement/preAppend coprocessor hook for input - * mutation in a batch - * - * @param metrics Array of 2 ints. index 0: count of puts, index 1: count of - * deletes, index 2: + * Runs prePut/preDelete/preIncrement/preAppend coprocessor hook for input mutation in a batch + * @param metrics Array of 2 ints. index 0: count of puts, index 1: count of deletes, index 2: * count of increments and 3: count of appends */ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] metrics) - throws IOException { + throws IOException { Mutation m = getMutation(index); if (m instanceof Put) { if (region.coprocessorHost.prePut((Put) m, walEdit)) { @@ -4702,8 +4460,7 @@ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] m Delete curDel = (Delete) m; if (curDel.getFamilyCellMap().isEmpty()) { // handle deleting a row case - // TODO: prepareDelete() has been called twice, before and after preDelete() CP - // hook. + // TODO: prepareDelete() has been called twice, before and after preDelete() CP hook. // Can this be avoided? region.prepareDelete(curDel); } @@ -4742,15 +4499,14 @@ private void callPreMutateCPHook(int index, final WALEdit walEdit, final int[] m // TODO Support Increment/Append operations private void checkAndMergeCPMutations(final MiniBatchOperationInProgress miniBatchOp, - final List acquiredRowLocks, final long timestamp) throws IOException { + final List acquiredRowLocks, final long timestamp) throws IOException { visitBatchOperations(true, nextIndexToProcess + miniBatchOp.size(), (int i) -> { // we pass (i - firstIndex) below since the call expects a relative index Mutation[] cpMutations = miniBatchOp.getOperationsFromCoprocessors(i - nextIndexToProcess); if (cpMutations == null) { return true; } - // Else Coprocessor added more Mutations corresponding to the Mutation at this - // index. + // Else Coprocessor added more Mutations corresponding to the Mutation at this index. Mutation mutation = getMutation(i); for (Mutation cpMutation : cpMutations) { this.checkAndPrepareMutation(cpMutation, timestamp); @@ -4758,17 +4514,14 @@ private void checkAndMergeCPMutations(final MiniBatchOperationInProgress> cpFamilyMap = cpMutation.getFamilyCellMap(); region.rewriteCellTags(cpFamilyMap, mutation); // will get added to the memStore later mergeFamilyMaps(familyCellMaps[i], cpFamilyMap); - // The durability of returned mutation is replaced by the corresponding - // mutation. + // The durability of returned mutation is replaced by the corresponding mutation. // If the corresponding mutation contains the SKIP_WAL, we shouldn't count the // cells of returned mutation. if (region.getEffectiveDurability(mutation.getDurability()) != Durability.SKIP_WAL) { @@ -4782,7 +4535,7 @@ private void checkAndMergeCPMutations(final MiniBatchOperationInProgress> familyMap, - Map> toBeMerged) { + Map> toBeMerged) { for (Map.Entry> entry : toBeMerged.entrySet()) { List cells = familyMap.get(entry.getKey()); if (cells == null) { @@ -4795,12 +4548,9 @@ private void mergeFamilyMaps(Map> familyMap, } /** - * Batch of mutations for replay. Base class is shared with - * {@link MutationBatchOperation} as most + * Batch of mutations for replay. Base class is shared with {@link MutationBatchOperation} as most * of the logic is same. - * - * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we will not use this - * operation to apply + * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we will not use this operation to apply * edits at secondary replica side. */ @Deprecated @@ -4809,7 +4559,7 @@ private static final class ReplayBatchOperation extends BatchOperation miniBatchOp, - long timestamp, final List acquiredRowLocks) throws IOException { + long timestamp, final List acquiredRowLocks) throws IOException { visitBatchOperations(true, miniBatchOp.getLastIndexExclusive(), (int index) -> { // update cell count for (List cells : getMutation(index).getFamilyCellMap().values()) { @@ -4903,71 +4652,70 @@ public void prepareMiniBatchOperations(MiniBatchOperationInProgress mi @Override public WriteEntry writeMiniBatchOperationsToMemStore( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, - long now) throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry, + long now) throws IOException { super.writeMiniBatchOperationsToMemStore(miniBatchOp, getOrigLogSeqNum()); return writeEntry; } @Override public void completeMiniBatchOperations( - final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) - throws IOException { + final MiniBatchOperationInProgress miniBatchOp, final WriteEntry writeEntry) + throws IOException { super.completeMiniBatchOperations(miniBatchOp, writeEntry); region.mvcc.advanceTo(getOrigLogSeqNum()); } @Override protected void cacheSkipWALMutationForRegionReplication( - MiniBatchOperationInProgress miniBatchOp, List> walEdits, - Map> familyCellMap) { + MiniBatchOperationInProgress miniBatchOp, List> walEdits, + Map> familyCellMap) { // There is no action to do if current region is secondary replica } } public OperationStatus[] batchMutate(Mutation[] mutations, boolean atomic, long nonceGroup, - long nonce) throws IOException { + long nonce) throws IOException { // As it stands, this is used for 3 things - // * batchMutate with single mutation - put/delete/increment/append, separate or - // from + // * batchMutate with single mutation - put/delete/increment/append, separate or from // checkAndMutate. // * coprocessor calls (see ex. BulkDeleteEndpoint). - // So nonces are not really ever used by HBase. They could be by coprocs, and - // checkAnd... + // So nonces are not really ever used by HBase. They could be by coprocs, and checkAnd... return batchMutate(new MutationBatchOperation(this, mutations, atomic, nonceGroup, nonce)); } @Override public OperationStatus[] batchMutate(Mutation[] mutations) throws IOException { - // If the mutations has any Increment/Append operations, we need to do - // batchMutate atomically - boolean atomic = Arrays.stream(mutations).anyMatch(m -> m instanceof Increment || m instanceof Append); + // If the mutations has any Increment/Append operations, we need to do batchMutate atomically + boolean atomic = + Arrays.stream(mutations).anyMatch(m -> m instanceof Increment || m instanceof Append); return batchMutate(mutations, atomic); } OperationStatus[] batchMutate(Mutation[] mutations, boolean atomic) throws IOException { return TraceUtil.trace( - () -> batchMutate(mutations, atomic, HConstants.NO_NONCE, HConstants.NO_NONCE), - () -> createRegionSpan("Region.batchMutate")); + () -> batchMutate(mutations, atomic, HConstants.NO_NONCE, HConstants.NO_NONCE), + () -> createRegionSpan("Region.batchMutate")); } /** * @deprecated Since 3.0.0, will be removed in 4.0.0. Now we use - * {@link #replayWALEntry(WALEntry, CellScanner)} for replaying - * edits at secondary + * {@link #replayWALEntry(WALEntry, CellScanner)} for replaying edits at secondary * replica side. */ @Deprecated OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) throws IOException { - if (!RegionReplicaUtil.isDefaultReplica(getRegionInfo()) - && replaySeqId < lastReplayedOpenRegionSeqId) { + if ( + !RegionReplicaUtil.isDefaultReplica(getRegionInfo()) + && replaySeqId < lastReplayedOpenRegionSeqId + ) { // if it is a secondary replica we should ignore these entries silently // since they are coming out of order if (LOG.isTraceEnabled()) { LOG.trace(getRegionInfo().getEncodedName() + " : " + "Skipping " + mutations.length - + " mutations with replaySeqId=" + replaySeqId - + " which is < than lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); + + " mutations with replaySeqId=" + replaySeqId + + " which is < than lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); for (MutationReplay mut : mutations) { LOG.trace(getRegionInfo().getEncodedName() + " : Skipping : " + mut.mutation); } @@ -4985,26 +4733,18 @@ OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) thro /** * Perform a batch of mutations. *

    - * Operations in a batch are stored with highest durability specified of for all - * operations in a + * Operations in a batch are stored with highest durability specified of for all operations in a * batch, except for {@link Durability#SKIP_WAL}. *

    - * This function is called from - * {@link #batchReplay(WALSplitUtil.MutationReplay[], long)} with - * {@link ReplayBatchOperation} instance and {@link #batchMutate(Mutation[])} - * with - * {@link MutationBatchOperation} instance as an argument. As the processing of - * replay batch and - * mutation batch is very similar, lot of code is shared by providing generic - * methods in base + * This function is called from {@link #batchReplay(WALSplitUtil.MutationReplay[], long)} with + * {@link ReplayBatchOperation} instance and {@link #batchMutate(Mutation[])} with + * {@link MutationBatchOperation} instance as an argument. As the processing of replay batch and + * mutation batch is very similar, lot of code is shared by providing generic methods in base * class {@link BatchOperation}. The logic for this method and - * {@link #doMiniBatchMutate(BatchOperation)} is implemented using methods in - * base class which are + * {@link #doMiniBatchMutate(BatchOperation)} is implemented using methods in base class which are * overridden by derived classes to implement special behavior. - * * @param batchOp contains the list of mutations - * @return an array of OperationStatus which internally contains the - * OperationStatusCode and the + * @return an array of OperationStatus which internally contains the OperationStatusCode and the * exceptionMessage if any. * @throws IOException if an IO problem is encountered */ @@ -5020,8 +4760,7 @@ private OperationStatus[] batchMutate(BatchOperation batchOp) throws IOExcept if (!initialized) { this.writeRequestsCount.add(batchOp.size()); - // validate and prepare batch for write, for MutationBatchOperation it also - // calls CP + // validate and prepare batch for write, for MutationBatchOperation it also calls CP // prePut()/preDelete()/preIncrement()/preAppend() hooks batchOp.checkAndPrepare(); initialized = true; @@ -5039,10 +4778,8 @@ private OperationStatus[] batchMutate(BatchOperation batchOp) throws IOExcept } /** - * Called to do a piece of the batch that came in to - * {@link #batchMutate(Mutation[])} In here we - * also handle replay of edits on region recover. Also gets change in size - * brought about by + * Called to do a piece of the batch that came in to {@link #batchMutate(Mutation[])} In here we + * also handle replay of edits on region recover. Also gets change in size brought about by * applying {@code batchOp}. */ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { @@ -5050,8 +4787,7 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { WALEdit walEdit = null; WriteEntry writeEntry = null; boolean locked = false; - // We try to set up a batch in the range - // [batchOp.nextIndexToProcess,lastIndexExclusive) + // We try to set up a batch in the range [batchOp.nextIndexToProcess,lastIndexExclusive) MiniBatchOperationInProgress miniBatchOp = null; /** Keep track of the locks we hold so we can release them in finally clause */ List acquiredRowLocks = Lists.newArrayListWithCapacity(batchOp.size()); @@ -5061,8 +4797,7 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { checkInterrupt(); try { - // STEP 1. Try to acquire as many locks as we can and build mini-batch of - // operations with + // STEP 1. Try to acquire as many locks as we can and build mini-batch of operations with // locked rows miniBatchOp = batchOp.lockRowsAndBuildMiniBatch(acquiredRowLocks); @@ -5075,23 +4810,19 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { } // Check for thread interrupt status in case we have been signaled from - // #interruptRegionOperation. Do it before we take the lock and disable - // interrupts for + // #interruptRegionOperation. Do it before we take the lock and disable interrupts for // the WAL append. checkInterrupt(); lock(this.updatesLock.readLock(), miniBatchOp.getReadyToWriteCount()); locked = true; - // From this point until memstore update this operation should not be - // interrupted. + // From this point until memstore update this operation should not be interrupted. disableInterrupts(); - // STEP 2. Update mini batch of all operations in progress with LATEST_TIMESTAMP - // timestamp + // STEP 2. Update mini batch of all operations in progress with LATEST_TIMESTAMP timestamp // We should record the timestamp only after we have acquired the rowLock, - // otherwise, newer puts/deletes/increment/append are not guaranteed to have a - // newer + // otherwise, newer puts/deletes/increment/append are not guaranteed to have a newer // timestamp long now = EnvironmentEdgeManager.currentTime(); @@ -5123,17 +4854,14 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { // NOTE: writeEntry can be null here writeEntry = batchOp.writeMiniBatchOperationsToMemStore(miniBatchOp, writeEntry, now); - // STEP 6. Complete MiniBatchOperations: If required calls postBatchMutate() CP - // hook and + // STEP 6. Complete MiniBatchOperations: If required calls postBatchMutate() CP hook and // complete mvcc for last writeEntry batchOp.completeMiniBatchOperations(miniBatchOp, writeEntry); writeEntry = null; success = true; } finally { - // Call complete rather than completeAndWait because we probably had error if - // walKey != null - if (writeEntry != null) - mvcc.complete(writeEntry); + // Call complete rather than completeAndWait because we probably had error if walKey != null + if (writeEntry != null) mvcc.complete(writeEntry); if (locked) { this.updatesLock.readLock().unlock(); @@ -5142,18 +4870,21 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { enableInterrupts(); - final int finalLastIndexExclusive = miniBatchOp != null ? miniBatchOp.getLastIndexExclusive() : batchOp.size(); + final int finalLastIndexExclusive = + miniBatchOp != null ? miniBatchOp.getLastIndexExclusive() : batchOp.size(); final boolean finalSuccess = success; batchOp.visitBatchOperations(true, finalLastIndexExclusive, (int i) -> { Mutation mutation = batchOp.getMutation(i); if (mutation instanceof Increment || mutation instanceof Append) { if (finalSuccess) { - batchOp.retCodeDetails[i] = new OperationStatus(OperationStatusCode.SUCCESS, batchOp.results[i]); + batchOp.retCodeDetails[i] = + new OperationStatus(OperationStatusCode.SUCCESS, batchOp.results[i]); } else { batchOp.retCodeDetails[i] = OperationStatus.FAILURE; } } else { - batchOp.retCodeDetails[i] = finalSuccess ? OperationStatus.SUCCESS : OperationStatus.FAILURE; + batchOp.retCodeDetails[i] = + finalSuccess ? OperationStatus.SUCCESS : OperationStatus.FAILURE; } return true; }); @@ -5165,8 +4896,7 @@ private void doMiniBatchMutate(BatchOperation batchOp) throws IOException { } /** - * Returns effective durability from the passed durability and the table - * descriptor. + * Returns effective durability from the passed durability and the table descriptor. */ private Durability getEffectiveDurability(Durability d) { return d == Durability.USE_DEFAULT ? this.regionDurability : d; @@ -5175,18 +4905,18 @@ private Durability getEffectiveDurability(Durability d) { @Override @Deprecated public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator op, - ByteArrayComparable comparator, TimeRange timeRange, Mutation mutation) throws IOException { + ByteArrayComparable comparator, TimeRange timeRange, Mutation mutation) throws IOException { CheckAndMutate checkAndMutate; try { CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row) - .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange); + .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange); if (mutation instanceof Put) { checkAndMutate = builder.build((Put) mutation); } else if (mutation instanceof Delete) { checkAndMutate = builder.build((Delete) mutation); } else { throw new DoNotRetryIOException( - "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); + "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); } } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); @@ -5197,17 +4927,18 @@ public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, Compa @Override @Deprecated public boolean checkAndMutate(byte[] row, Filter filter, TimeRange timeRange, Mutation mutation) - throws IOException { + throws IOException { CheckAndMutate checkAndMutate; try { - CheckAndMutate.Builder builder = CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange); + CheckAndMutate.Builder builder = + CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange); if (mutation instanceof Put) { checkAndMutate = builder.build((Put) mutation); } else if (mutation instanceof Delete) { checkAndMutate = builder.build((Delete) mutation); } else { throw new DoNotRetryIOException( - "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); + "Unsupported mutate type: " + mutation.getClass().getSimpleName().toUpperCase()); } } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); @@ -5218,11 +4949,11 @@ public boolean checkAndMutate(byte[] row, Filter filter, TimeRange timeRange, Mu @Override @Deprecated public boolean checkAndRowMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator op, - ByteArrayComparable comparator, TimeRange timeRange, RowMutations rm) throws IOException { + ByteArrayComparable comparator, TimeRange timeRange, RowMutations rm) throws IOException { CheckAndMutate checkAndMutate; try { checkAndMutate = CheckAndMutate.newBuilder(row) - .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange).build(rm); + .ifMatches(family, qualifier, op, comparator.getValue()).timeRange(timeRange).build(rm); } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); } @@ -5232,10 +4963,11 @@ public boolean checkAndRowMutate(byte[] row, byte[] family, byte[] qualifier, Co @Override @Deprecated public boolean checkAndRowMutate(byte[] row, Filter filter, TimeRange timeRange, RowMutations rm) - throws IOException { + throws IOException { CheckAndMutate checkAndMutate; try { - checkAndMutate = CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange).build(rm); + checkAndMutate = + CheckAndMutate.newBuilder(row).ifMatches(filter).timeRange(timeRange).build(rm); } catch (IllegalArgumentException e) { throw new DoNotRetryIOException(e.getMessage()); } @@ -5248,13 +4980,13 @@ public CheckAndMutateResult checkAndMutate(CheckAndMutate checkAndMutate) throws } public CheckAndMutateResult checkAndMutate(CheckAndMutate checkAndMutate, long nonceGroup, - long nonce) throws IOException { + long nonce) throws IOException { return TraceUtil.trace(() -> checkAndMutateInternal(checkAndMutate, nonceGroup, nonce), - () -> createRegionSpan("Region.checkAndMutate")); + () -> createRegionSpan("Region.checkAndMutate")); } private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutate, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { byte[] row = checkAndMutate.getRow(); Filter filter = null; byte[] family = null; @@ -5306,15 +5038,15 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat RowLock rowLock = getRowLock(get.getRow(), false, null); try { if (this.getCoprocessorHost() != null) { - CheckAndMutateResult result = getCoprocessorHost().preCheckAndMutateAfterRowLock(checkAndMutate); + CheckAndMutateResult result = + getCoprocessorHost().preCheckAndMutateAfterRowLock(checkAndMutate); if (result != null) { return result; } } // NOTE: We used to wait here until mvcc caught up: mvcc.await(); - // Supposition is that now all changes are done under row locks, then when we go - // to read, + // Supposition is that now all changes are done under row locks, then when we go to read, // we'll get the latest on this row. boolean matches = false; long cellTs = 0; @@ -5329,7 +5061,8 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat cellTs = result.get(0).getTimestamp(); } } else { - boolean valueIsNull = comparator.getValue() == null || comparator.getValue().length == 0; + boolean valueIsNull = + comparator.getValue() == null || comparator.getValue().length == 0; if (result.isEmpty() && valueIsNull) { matches = op != CompareOperator.NOT_EQUAL; } else if (result.size() > 0 && valueIsNull) { @@ -5346,11 +5079,9 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat // If matches, perform the mutation or the rowMutations if (matches) { - // We have acquired the row lock already. If the system clock is NOT - // monotonically + // We have acquired the row lock already. If the system clock is NOT monotonically // non-decreasing (see HBASE-14070) we should make sure that the mutation has a - // larger timestamp than what was observed via Get. doBatchMutate already does - // this, but + // larger timestamp than what was observed via Get. doBatchMutate already does this, but // there is no way to pass the cellTs. See HBASE-14054. long now = EnvironmentEdgeManager.currentTime(); long ts = Math.max(now, cellTs); // ensure write is not eclipsed @@ -5359,8 +5090,7 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat if (mutation instanceof Put) { updateCellTimestamps(mutation.getFamilyCellMap().values(), byteTs); } - // And else 'delete' is not needed since it already does a second get, and sets - // the + // And else 'delete' is not needed since it already does a second get, and sets the // timestamp from get (see prepareDeleteTimestamps). } else { for (Mutation m : rowMutations.getMutations()) { @@ -5368,12 +5098,10 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat updateCellTimestamps(m.getFamilyCellMap().values(), byteTs); } } - // And else 'delete' is not needed since it already does a second get, and sets - // the + // And else 'delete' is not needed since it already does a second get, and sets the // timestamp from get (see prepareDeleteTimestamps). } - // All edits for the given row (across all column families) must happen - // atomically. + // All edits for the given row (across all column families) must happen atomically. Result r; if (mutation != null) { r = mutate(mutation, true, nonceGroup, nonce).getResult(); @@ -5394,10 +5122,12 @@ private CheckAndMutateResult checkAndMutateInternal(CheckAndMutate checkAndMutat } private void checkMutationType(final Mutation mutation) throws DoNotRetryIOException { - if (!(mutation instanceof Put) && !(mutation instanceof Delete) - && !(mutation instanceof Increment) && !(mutation instanceof Append)) { + if ( + !(mutation instanceof Put) && !(mutation instanceof Delete) + && !(mutation instanceof Increment) && !(mutation instanceof Append) + ) { throw new org.apache.hadoop.hbase.DoNotRetryIOException( - "Action must be Put or Delete or Increment or Delete"); + "Action must be Put or Delete or Increment or Delete"); } } @@ -5443,8 +5173,9 @@ private OperationStatus mutate(Mutation mutation, boolean atomic) throws IOExcep } private OperationStatus mutate(Mutation mutation, boolean atomic, long nonceGroup, long nonce) - throws IOException { - OperationStatus[] status = this.batchMutate(new Mutation[] { mutation }, atomic, nonceGroup, nonce); + throws IOException { + OperationStatus[] status = + this.batchMutate(new Mutation[] { mutation }, atomic, nonceGroup, nonce); if (status[0].getOperationStatusCode().equals(OperationStatusCode.SANITY_CHECK_FAILURE)) { throw new FailedSanityCheckException(status[0].getExceptionMsg()); } else if (status[0].getOperationStatusCode().equals(OperationStatusCode.BAD_FAMILY)) { @@ -5456,37 +5187,29 @@ private OperationStatus mutate(Mutation mutation, boolean atomic, long nonceGrou } /** - * Complete taking the snapshot on the region. Writes the region info and adds - * references to the - * working snapshot directory. TODO for api consistency, consider adding another - * version with no - * {@link ForeignExceptionSnare} arg. (In the future other cancellable HRegion - * methods could - * eventually add a {@link ForeignExceptionSnare}, or we could do something - * fancier). - * + * Complete taking the snapshot on the region. Writes the region info and adds references to the + * working snapshot directory. TODO for api consistency, consider adding another version with no + * {@link ForeignExceptionSnare} arg. (In the future other cancellable HRegion methods could + * eventually add a {@link ForeignExceptionSnare}, or we could do something fancier). * @param desc snapshot description object - * @param exnSnare ForeignExceptionSnare that captures external exceptions in - * case we need to bail - * out. This is allowed to be null and will just be ignored in - * that case. - * @throws IOException if there is an external or internal error causing the - * snapshot to fail + * @param exnSnare ForeignExceptionSnare that captures external exceptions in case we need to bail + * out. This is allowed to be null and will just be ignored in that case. + * @throws IOException if there is an external or internal error causing the snapshot to fail */ public void addRegionToSnapshot(SnapshotDescription desc, ForeignExceptionSnare exnSnare) - throws IOException { + throws IOException { Path rootDir = CommonFSUtils.getRootDir(conf); Path snapshotDir = SnapshotDescriptionUtils.getWorkingSnapshotDir(desc, rootDir, conf); - SnapshotManifest manifest = SnapshotManifest.create(conf, getFilesystem(), snapshotDir, desc, exnSnare); + SnapshotManifest manifest = + SnapshotManifest.create(conf, getFilesystem(), snapshotDir, desc, exnSnare); manifest.addRegion(this); } private void updateSequenceId(final Iterable> cellItr, final long sequenceId) - throws IOException { + throws IOException { for (List cells : cellItr) { - if (cells == null) - return; + if (cells == null) return; for (Cell cell : cells) { PrivateCellUtil.setSequenceId(cell, sequenceId); } @@ -5494,18 +5217,15 @@ private void updateSequenceId(final Iterable> cellItr, final long seq } /** - * Replace any cell timestamps set to - * {@link org.apache.hadoop.hbase.HConstants#LATEST_TIMESTAMP} + * Replace any cell timestamps set to {@link org.apache.hadoop.hbase.HConstants#LATEST_TIMESTAMP} * provided current timestamp. */ private static void updateCellTimestamps(final Iterable> cellItr, final byte[] now) - throws IOException { + throws IOException { for (List cells : cellItr) { - if (cells == null) - continue; + if (cells == null) continue; // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator - // objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects assert cells instanceof RandomAccess; int listSize = cells.size(); for (int i = 0; i < listSize; i++) { @@ -5542,8 +5262,7 @@ private void rewriteCellTags(Map> familyMap, final Mutation m /** * Check if resources to support an update. *

    - * We throw RegionTooBusyException if above memstore limit and expect client to - * retry using some + * We throw RegionTooBusyException if above memstore limit and expect client to retry using some * kind of backoff */ private void checkResources() throws RegionTooBusyException { @@ -5556,18 +5275,18 @@ private void checkResources() throws RegionTooBusyException { if (mss.getHeapSize() + mss.getOffHeapSize() > this.blockingMemStoreSize) { blockedRequestsCount.increment(); requestFlush(); - // Don't print current limit because it will vary too much. The message is used - // as a key + // Don't print current limit because it will vary too much. The message is used as a key // over in RetriesExhaustedWithDetailsException processing. - final String regionName = this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getEncodedName(); + final String regionName = + this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getEncodedName(); final String serverName = this.getRegionServerServices() == null + ? "unknown" + : (this.getRegionServerServices().getServerName() == null ? "unknown" - : (this.getRegionServerServices().getServerName() == null - ? "unknown" - : this.getRegionServerServices().getServerName().toString()); + : this.getRegionServerServices().getServerName().toString()); RegionTooBusyException rtbe = new RegionTooBusyException("Over memstore limit=" - + org.apache.hadoop.hbase.procedure2.util.StringUtils.humanSize(this.blockingMemStoreSize) - + ", regionName=" + regionName + ", server=" + serverName); + + org.apache.hadoop.hbase.procedure2.util.StringUtils.humanSize(this.blockingMemStoreSize) + + ", regionName=" + regionName + ", server=" + serverName); LOG.warn("Region is too busy due to exceeding memstore size limit.", rtbe); throw rtbe; } @@ -5585,7 +5304,7 @@ private void checkReadOnly() throws IOException { private void checkReadsEnabled() throws IOException { if (!this.writestate.readsEnabled) { throw new IOException(getRegionInfo().getEncodedName() - + ": The region's reads are disabled. Cannot serve the request"); + + ": The region's reads are disabled. Cannot serve the request"); } } @@ -5597,16 +5316,13 @@ public void setReadsEnabled(boolean readsEnabled) { } /** - * @param delta If we are doing delta changes -- e.g. increment/append -- then - * this flag will be - * set; when set we will run operations that make sense in the - * increment/append + * @param delta If we are doing delta changes -- e.g. increment/append -- then this flag will be + * set; when set we will run operations that make sense in the increment/append * scenario but that do not make sense otherwise. */ private void applyToMemStore(HStore store, List cells, boolean delta, - MemStoreSizing memstoreAccounting) { - // Any change in how we update Store/MemStore needs to also be done in other - // applyToMemStore!!!! + MemStoreSizing memstoreAccounting) { + // Any change in how we update Store/MemStore needs to also be done in other applyToMemStore!!!! boolean upsert = delta && store.getColumnFamilyDescriptor().getMaxVersions() == 1; if (upsert) { store.upsert(cells, getSmallestReadPoint(), memstoreAccounting); @@ -5616,45 +5332,45 @@ private void applyToMemStore(HStore store, List cells, boolean delta, } private void checkFamilies(Collection families, Durability durability) - throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { + throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { for (byte[] family : families) { checkFamily(family, durability); } } private void checkFamily(final byte[] family, Durability durability) - throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { + throws NoSuchColumnFamilyException, InvalidMutationDurabilityException { checkFamily(family); - if (durability.equals(Durability.SKIP_WAL) - && htableDescriptor.getColumnFamily(family).getScope() != HConstants.REPLICATION_SCOPE_LOCAL) { + if ( + durability.equals(Durability.SKIP_WAL) + && htableDescriptor.getColumnFamily(family).getScope() != HConstants.REPLICATION_SCOPE_LOCAL + ) { throw new InvalidMutationDurabilityException( - "Mutation's durability is SKIP_WAL but table's column family " + Bytes.toString(family) - + " need replication"); + "Mutation's durability is SKIP_WAL but table's column family " + Bytes.toString(family) + + " need replication"); } } private void checkFamily(final byte[] family) throws NoSuchColumnFamilyException { if (!this.htableDescriptor.hasColumnFamily(family)) { throw new NoSuchColumnFamilyException("Column family " + Bytes.toString(family) - + " does not exist in region " + this + " in table " + this.htableDescriptor); + + " does not exist in region " + this + " in table " + this.htableDescriptor); } } /** * Check the collection of families for valid timestamps - * * @param now current timestamp */ public void checkTimestamps(final Map> familyMap, long now) - throws FailedSanityCheckException { + throws FailedSanityCheckException { if (timestampSlop == HConstants.LATEST_TIMESTAMP) { return; } long maxTs = now + timestampSlop; for (List kvs : familyMap.values()) { // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator - // objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects assert kvs instanceof RandomAccess; int listSize = kvs.size(); for (int i = 0; i < listSize; i++) { @@ -5663,7 +5379,7 @@ public void checkTimestamps(final Map> familyMap, long now) long ts = cell.getTimestamp(); if (ts != HConstants.LATEST_TIMESTAMP && ts > maxTs) { throw new FailedSanityCheckException( - "Timestamp for KV out of range " + cell + " (too.new=" + timestampSlop + ")"); + "Timestamp for KV out of range " + cell + " (too.new=" + timestampSlop + ")"); } } } @@ -5687,51 +5403,34 @@ private void deleteRecoveredEdits(FileSystem fs, Iterable files) throws IO } /** - * Read the edits put under this region by wal splitting process. Put the - * recovered edits back up + * Read the edits put under this region by wal splitting process. Put the recovered edits back up * into this region. *

    - * We can ignore any wal message that has a sequence ID that's equal to or lower - * than minSeqId. + * We can ignore any wal message that has a sequence ID that's equal to or lower than minSeqId. * (Because we know such messages are already reflected in the HFiles.) *

    - * While this is running we are putting pressure on memory yet we are outside of - * our usual - * accounting because we are not yet an onlined region (this stuff is being run - * as part of Region - * initialization). This means that if we're up against global memory limits, - * we'll not be flagged - * to flush because we are not online. We can't be flushed by usual mechanisms - * anyways; we're not - * yet online so our relative sequenceids are not yet aligned with WAL - * sequenceids -- not till we + * While this is running we are putting pressure on memory yet we are outside of our usual + * accounting because we are not yet an onlined region (this stuff is being run as part of Region + * initialization). This means that if we're up against global memory limits, we'll not be flagged + * to flush because we are not online. We can't be flushed by usual mechanisms anyways; we're not + * yet online so our relative sequenceids are not yet aligned with WAL sequenceids -- not till we * come up online, post processing of split edits. *

    - * But to help relieve memory pressure, at least manage our own heap size - * flushing if are in - * excess of per-region limits. Flushing, though, we have to be careful and - * avoid using the - * regionserver/wal sequenceid. Its running on a different line to whats going - * on in here in this - * region context so if we crashed replaying these edits, but in the midst had a - * flush that used - * the regionserver wal with a sequenceid in excess of whats going on in here in - * this region and - * with its split editlogs, then we could miss edits the next time we go to - * recover. So, we have - * to flush inline, using seqids that make sense in a this single region context - * only -- until we + * But to help relieve memory pressure, at least manage our own heap size flushing if are in + * excess of per-region limits. Flushing, though, we have to be careful and avoid using the + * regionserver/wal sequenceid. Its running on a different line to whats going on in here in this + * region context so if we crashed replaying these edits, but in the midst had a flush that used + * the regionserver wal with a sequenceid in excess of whats going on in here in this region and + * with its split editlogs, then we could miss edits the next time we go to recover. So, we have + * to flush inline, using seqids that make sense in a this single region context only -- until we * online. - * - * @param maxSeqIdInStores Any edit found in split editlogs needs to be in - * excess of the maxSeqId + * @param maxSeqIdInStores Any edit found in split editlogs needs to be in excess of the maxSeqId * for the store to be applied, else its skipped. - * @return the sequence id of the last edit added to this region out of the - * recovered edits log or + * @return the sequence id of the last edit added to this region out of the recovered edits log or * minSeqId if nothing added from editlogs. */ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, - final CancelableProgressable reporter, final MonitoredTask status) throws IOException { + final CancelableProgressable reporter, final MonitoredTask status) throws IOException { long minSeqIdForTheRegion = -1; for (Long maxSeqIdInStore : maxSeqIdInStores.values()) { if (maxSeqIdInStore < minSeqIdForTheRegion || minSeqIdForTheRegion == -1) { @@ -5744,39 +5443,38 @@ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, FileSystem walFS = getWalFileSystem(); FileSystem rootFS = getFilesystem(); Path wrongRegionWALDir = CommonFSUtils.getWrongWALRegionDir(conf, getRegionInfo().getTable(), - getRegionInfo().getEncodedName()); + getRegionInfo().getEncodedName()); Path regionWALDir = getWALRegionDir(); - Path regionDir = FSUtils.getRegionDirFromRootDir(CommonFSUtils.getRootDir(conf), getRegionInfo()); + Path regionDir = + FSUtils.getRegionDirFromRootDir(CommonFSUtils.getRootDir(conf), getRegionInfo()); // We made a mistake in HBASE-20734 so we need to do this dirty hack... - NavigableSet filesUnderWrongRegionWALDir = WALSplitUtil.getSplitEditFilesSorted(walFS, wrongRegionWALDir); + NavigableSet filesUnderWrongRegionWALDir = + WALSplitUtil.getSplitEditFilesSorted(walFS, wrongRegionWALDir); seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, - filesUnderWrongRegionWALDir, reporter, regionDir)); - // This is to ensure backwards compatability with HBASE-20723 where recovered - // edits can appear + filesUnderWrongRegionWALDir, reporter, regionDir)); + // This is to ensure backwards compatability with HBASE-20723 where recovered edits can appear // under the root dir even if walDir is set. NavigableSet filesUnderRootDir = Collections.emptyNavigableSet(); if (!regionWALDir.equals(regionDir)) { filesUnderRootDir = WALSplitUtil.getSplitEditFilesSorted(rootFS, regionDir); seqId = Math.max(seqId, replayRecoveredEditsForPaths(minSeqIdForTheRegion, rootFS, - filesUnderRootDir, reporter, regionDir)); + filesUnderRootDir, reporter, regionDir)); } NavigableSet files = WALSplitUtil.getSplitEditFilesSorted(walFS, regionWALDir); seqId = Math.max(seqId, - replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, files, reporter, regionWALDir)); + replayRecoveredEditsForPaths(minSeqIdForTheRegion, walFS, files, reporter, regionWALDir)); if (seqId > minSeqIdForTheRegion) { // Then we added some edits to memory. Flush and cleanup split edit files. internalFlushcache(null, seqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } // Now delete the content of recovered edits. We're done w/ them. if (files.size() > 0 && this.conf.getBoolean("hbase.region.archive.recovered.edits", false)) { // For debugging data loss issues! - // If this flag is set, make use of the hfile archiving by making - // recovered.edits a fake - // column family. Have to fake out file type too by casting our recovered.edits - // as + // If this flag is set, make use of the hfile archiving by making recovered.edits a fake + // column family. Have to fake out file type too by casting our recovered.edits as // storefiles String fakeFamilyName = WALSplitUtil.getRegionDirRecoveredEditsDir(regionWALDir).getName(); Set fakeStoreFiles = new HashSet<>(files.size()); @@ -5793,37 +5491,37 @@ long replayRecoveredEditsIfAny(Map maxSeqIdInStores, FileSystem fs = recoveredEditsDir.getFileSystem(conf); FileStatus[] files = fs.listStatus(recoveredEditsDir); LOG.debug("Found {} recovered edits file(s) under {}", files == null ? 0 : files.length, - recoveredEditsDir); + recoveredEditsDir); if (files != null) { for (FileStatus file : files) { - // it is safe to trust the zero-length in this case because we've been through - // rename and + // it is safe to trust the zero-length in this case because we've been through rename and // lease recovery in the above. if (isZeroLengthThenDelete(fs, file, file.getPath())) { continue; } - seqId = Math.max(seqId, replayRecoveredEdits(file.getPath(), maxSeqIdInStores, reporter, fs)); + seqId = + Math.max(seqId, replayRecoveredEdits(file.getPath(), maxSeqIdInStores, reporter, fs)); } } if (seqId > minSeqIdForTheRegion) { // Then we added some edits to memory. Flush and cleanup split edit files. internalFlushcache(null, seqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } deleteRecoveredEdits(fs, - Stream.of(files).map(FileStatus::getPath).collect(Collectors.toList())); + Stream.of(files).map(FileStatus::getPath).collect(Collectors.toList())); } return seqId; } private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem fs, - final NavigableSet files, final CancelableProgressable reporter, final Path regionDir) - throws IOException { + final NavigableSet files, final CancelableProgressable reporter, final Path regionDir) + throws IOException { long seqid = minSeqIdForTheRegion; if (LOG.isDebugEnabled()) { LOG.debug("Found " + (files == null ? 0 : files.size()) + " recovered edits file(s) under " - + regionDir); + + regionDir); } if (files == null || files.isEmpty()) { @@ -5845,8 +5543,8 @@ private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem if (maxSeqId <= minSeqIdForTheRegion) { if (LOG.isDebugEnabled()) { String msg = "Maximum sequenceid for this wal is " + maxSeqId - + " and minimum sequenceid for the region " + this + " is " + minSeqIdForTheRegion - + ", skipped the whole file, path=" + edits; + + " and minimum sequenceid for the region " + this + " is " + minSeqIdForTheRegion + + ", skipped the whole file, path=" + edits; LOG.debug(msg); } continue; @@ -5865,15 +5563,15 @@ private long replayRecoveredEditsForPaths(long minSeqIdForTheRegion, FileSystem private void handleException(FileSystem fs, Path edits, IOException e) throws IOException { boolean skipErrors = conf.getBoolean(HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS, - conf.getBoolean("hbase.skip.errors", HConstants.DEFAULT_HREGION_EDITS_REPLAY_SKIP_ERRORS)); + conf.getBoolean("hbase.skip.errors", HConstants.DEFAULT_HREGION_EDITS_REPLAY_SKIP_ERRORS)); if (conf.get("hbase.skip.errors") != null) { LOG.warn("The property 'hbase.skip.errors' has been deprecated. Please use " - + HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + " instead."); + + HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + " instead."); } if (skipErrors) { Path p = WALSplitUtil.moveAsideBadEditsFile(fs, edits); LOG.error(HConstants.HREGION_EDITS_REPLAY_SKIP_ERRORS + "=true so continuing. Renamed " - + edits + " as " + p, e); + + edits + " as " + p, e); } else { throw e; } @@ -5881,15 +5579,13 @@ private void handleException(FileSystem fs, Path edits, IOException e) throws IO /** * @param edits File of recovered edits. - * @param maxSeqIdInStores Maximum sequenceid found in each store. Edits in wal - * must be larger + * @param maxSeqIdInStores Maximum sequenceid found in each store. Edits in wal must be larger * than this to be replayed for each store. - * @return the sequence id of the last edit added to this region out of the - * recovered edits log or + * @return the sequence id of the last edit added to this region out of the recovered edits log or * minSeqId if nothing added from editlogs. */ private long replayRecoveredEdits(final Path edits, Map maxSeqIdInStores, - final CancelableProgressable reporter, FileSystem fs) throws IOException { + final CancelableProgressable reporter, FileSystem fs) throws IOException { String msg = "Replaying edits from " + edits; LOG.info(msg); MonitoredTask status = TaskMonitor.get().createStatus(msg); @@ -5934,7 +5630,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn long cur = EnvironmentEdgeManager.currentTime(); if (lastReport + period <= cur) { status.setStatus( - "Replaying edits..." + " skipped=" + skippedEdits + " edits=" + editsCount); + "Replaying edits..." + " skipped=" + skippedEdits + " edits=" + editsCount); // Timeout reached if (!reporter.progress()) { msg = "Progressable reporter failed, stopping replay for region " + this; @@ -5952,19 +5648,21 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn firstSeqIdInLog = key.getSequenceId(); } if (currentEditSeqId > key.getSequenceId()) { - // when this condition is true, it means we have a serious defect because we - // need to + // when this condition is true, it means we have a serious defect because we need to // maintain increasing SeqId for WAL edits per region LOG.error(getRegionInfo().getEncodedName() + " : " + "Found decreasing SeqId. PreId=" - + currentEditSeqId + " key=" + key + "; edit=" + val); + + currentEditSeqId + " key=" + key + "; edit=" + val); } else { currentEditSeqId = key.getSequenceId(); } - currentReplaySeqId = (key.getOrigLogSeqNum() > 0) ? key.getOrigLogSeqNum() : currentEditSeqId; + currentReplaySeqId = + (key.getOrigLogSeqNum() > 0) ? key.getOrigLogSeqNum() : currentEditSeqId; boolean checkRowWithinBoundary = false; // Check this edit is for this region. - if (!Bytes.equals(key.getEncodedRegionName(), this.getRegionInfo().getEncodedNameAsBytes())) { + if ( + !Bytes.equals(key.getEncodedRegionName(), this.getRegionInfo().getEncodedNameAsBytes()) + ) { checkRowWithinBoundary = true; } @@ -5987,8 +5685,10 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn continue; } // Figure which store the edit is meant for. - if (store == null - || !CellUtil.matchingFamily(cell, store.getColumnFamilyDescriptor().getName())) { + if ( + store == null + || !CellUtil.matchingFamily(cell, store.getColumnFamilyDescriptor().getName()) + ) { store = getStore(cell); } if (store == null) { @@ -5998,14 +5698,19 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn skippedEdits++; continue; } - if (checkRowWithinBoundary && !rowIsInRange(this.getRegionInfo(), cell.getRowArray(), - cell.getRowOffset(), cell.getRowLength())) { + if ( + checkRowWithinBoundary && !rowIsInRange(this.getRegionInfo(), cell.getRowArray(), + cell.getRowOffset(), cell.getRowLength()) + ) { LOG.warn("Row of {} is not within region boundary for region {}", cell, this); skippedEdits++; continue; } // Now, figure if we should skip this edit. - if (key.getSequenceId() <= maxSeqIdInStores.get(store.getColumnFamilyDescriptor().getName())) { + if ( + key.getSequenceId() + <= maxSeqIdInStores.get(store.getColumnFamilyDescriptor().getName()) + ) { skippedEdits++; continue; } @@ -6019,7 +5724,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn flush = isFlushSize(this.memStoreSizing.getMemStoreSize()); if (flush) { internalFlushcache(null, currentEditSeqId, stores.values(), status, false, - FlushLifeCycleTracker.DUMMY); + FlushLifeCycleTracker.DUMMY); } } @@ -6030,20 +5735,21 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn if (!conf.getBoolean(RECOVERED_EDITS_IGNORE_EOF, false)) { Path p = WALSplitUtil.moveAsideBadEditsFile(walFS, edits); msg = "EnLongAddered EOF. Most likely due to Master failure during " - + "wal splitting, so we have this data in another edit. Continuing, but renaming " - + edits + " as " + p + " for region " + this; + + "wal splitting, so we have this data in another edit. Continuing, but renaming " + + edits + " as " + p + " for region " + this; LOG.warn(msg, eof); status.abort(msg); } else { LOG.warn("EOF while replaying recover edits and config '{}' is true so " - + "we will ignore it and continue", RECOVERED_EDITS_IGNORE_EOF, eof); + + "we will ignore it and continue", RECOVERED_EDITS_IGNORE_EOF, eof); } } catch (IOException ioe) { // If the IOE resulted from bad file format, // then this problem is idempotent and retrying won't help if (ioe.getCause() instanceof ParseException) { Path p = WALSplitUtil.moveAsideBadEditsFile(walFS, edits); - msg = "File corruption enLongAddered! " + "Continuing, but renaming " + edits + " as " + p; + msg = + "File corruption enLongAddered! " + "Continuing, but renaming " + edits + " as " + p; LOG.warn(msg, ioe); status.setStatus(msg); } else { @@ -6057,7 +5763,7 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn reporter.progress(); } msg = "Applied " + editsCount + ", skipped " + skippedEdits + ", firstSequenceIdInLog=" - + firstSeqIdInLog + ", maxSequenceIdInLog=" + currentEditSeqId + ", path=" + edits; + + firstSeqIdInLog + ", maxSequenceIdInLog=" + currentEditSeqId + ", path=" + edits; status.markComplete(msg); LOG.debug(msg); return currentEditSeqId; @@ -6067,16 +5773,14 @@ private long replayRecoveredEdits(final Path edits, Map maxSeqIdIn } /** - * Call to complete a compaction. Its for the case where we find in the WAL a - * compaction that was - * not finished. We could find one recovering a WAL after a regionserver crash. - * See HBASE-2331. + * Call to complete a compaction. Its for the case where we find in the WAL a compaction that was + * not finished. We could find one recovering a WAL after a regionserver crash. See HBASE-2331. */ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickCompactionFiles, - boolean removeFiles, long replaySeqId) throws IOException { + boolean removeFiles, long replaySeqId) throws IOException { try { checkTargetRegion(compaction.getEncodedRegionName().toByteArray(), - "Compaction marker from WAL ", compaction); + "Compaction marker from WAL ", compaction); } catch (WrongRegionException wre) { if (RegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { // skip the compaction marker since it is not for this region @@ -6088,16 +5792,16 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp synchronized (writestate) { if (replaySeqId < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying compaction event :" - + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " - + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " + + lastReplayedOpenRegionSeqId); return; } if (replaySeqId < lastReplayedCompactionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying compaction event :" - + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedCompactionSeqId of " - + lastReplayedCompactionSeqId); + + TextFormat.shortDebugString(compaction) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedCompactionSeqId of " + + lastReplayedCompactionSeqId); return; } else { lastReplayedCompactionSeqId = replaySeqId; @@ -6105,8 +5809,8 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying compaction marker " - + TextFormat.shortDebugString(compaction) + " with seqId=" + replaySeqId - + " and lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(compaction) + " with seqId=" + replaySeqId + + " and lastReplayedOpenRegionSeqId=" + lastReplayedOpenRegionSeqId); } startRegionOperation(Operation.REPLAY_EVENT); @@ -6114,17 +5818,17 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp HStore store = this.getStore(compaction.getFamilyName().toByteArray()); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Found Compaction WAL edit for deleted family:" - + Bytes.toString(compaction.getFamilyName().toByteArray())); + + "Found Compaction WAL edit for deleted family:" + + Bytes.toString(compaction.getFamilyName().toByteArray())); return; } store.replayCompactionMarker(compaction, pickCompactionFiles, removeFiles); logRegionFiles(); } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "At least one of the store files in compaction: " - + TextFormat.shortDebugString(compaction) - + " doesn't exist any more. Skip loading the file(s)", ex); + + "At least one of the store files in compaction: " + + TextFormat.shortDebugString(compaction) + + " doesn't exist any more. Skip loading the file(s)", ex); } finally { closeRegionOperation(Operation.REPLAY_EVENT); } @@ -6132,8 +5836,7 @@ void replayWALCompactionMarker(CompactionDescriptor compaction, boolean pickComp } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated @@ -6146,7 +5849,7 @@ void replayWALFlushMarker(FlushDescriptor flush, long replaySeqId) throws IOExce if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying flush marker " - + TextFormat.shortDebugString(flush)); + + TextFormat.shortDebugString(flush)); } startRegionOperation(Operation.REPLAY_EVENT); // use region close lock to guard against close @@ -6167,8 +5870,8 @@ void replayWALFlushMarker(FlushDescriptor flush, long replaySeqId) throws IOExce break; default: LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush event with unknown action, ignoring. " - + TextFormat.shortDebugString(flush)); + + "Received a flush event with unknown action, ignoring. " + + TextFormat.shortDebugString(flush)); break; } @@ -6185,8 +5888,8 @@ private Collection getStoresToFlush(FlushDescriptor flushDesc) { HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush start marker from primary, but the family is not found. Ignoring" - + " StoreFlushDescriptor:" + TextFormat.shortDebugString(storeFlush)); + + "Received a flush start marker from primary, but the family is not found. Ignoring" + + " StoreFlushDescriptor:" + TextFormat.shortDebugString(storeFlush)); continue; } storesToFlush.add(store); @@ -6195,14 +5898,10 @@ private Collection getStoresToFlush(FlushDescriptor flushDesc) { } /** - * Replay the flush marker from primary region by creating a corresponding - * snapshot of the store - * memstores, only if the memstores do not have a higher seqId from an earlier - * wal edit (because + * Replay the flush marker from primary region by creating a corresponding snapshot of the store + * memstores, only if the memstores do not have a higher seqId from an earlier wal edit (because * the events may be coming out of order). - * - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated @@ -6219,9 +5918,9 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc try { if (flush.getFlushSequenceNumber() < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return null; } if (numMutationsWithoutWAL.sum() > 0) { @@ -6230,14 +5929,12 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc } if (!writestate.flushing) { - // we do not have an active snapshot and corresponding this.prepareResult. This - // means + // we do not have an active snapshot and corresponding this.prepareResult. This means // we can just snapshot our memstores and continue as normal. - // invoke prepareFlushCache. Send null as wal since we do not want the flush - // events in wal + // invoke prepareFlushCache. Send null as wal since we do not want the flush events in wal PrepareFlushResult prepareResult = internalPrepareFlushCache(null, flushSeqId, - storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); + storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); if (prepareResult.result == null) { // save the PrepareFlushResult so that we can use it later from commit flush this.writestate.flushing = true; @@ -6245,18 +5942,20 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc status.markComplete("Flush prepare successful"); if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + " Prepared flush with seqId:" - + flush.getFlushSequenceNumber()); + + flush.getFlushSequenceNumber()); } } else { - // special case empty memstore. We will still save the flush result in this - // case, since + // special case empty memstore. We will still save the flush result in this case, since // our memstore ie empty, but the primary is still flushing - if (prepareResult.getResult().getResult() == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY) { + if ( + prepareResult.getResult().getResult() + == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY + ) { this.writestate.flushing = true; this.prepareFlushResult = prepareResult; if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + " Prepared empty flush with seqId:" + flush.getFlushSequenceNumber()); + + " Prepared empty flush with seqId:" + flush.getFlushSequenceNumber()); } } status.abort("Flush prepare failed with " + prepareResult.result); @@ -6268,42 +5967,34 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc if (flush.getFlushSequenceNumber() == this.prepareFlushResult.flushOpSeqId) { // They define the same flush. Log and continue. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with the same seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); + + "Received a flush prepare marker with the same seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); // ignore } else if (flush.getFlushSequenceNumber() < this.prepareFlushResult.flushOpSeqId) { - // We received a flush with a smaller seqNum than what we have prepared. We can - // only + // We received a flush with a smaller seqNum than what we have prepared. We can only // ignore this prepare flush request. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with a smaller seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); + + "Received a flush prepare marker with a smaller seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); // ignore } else { // We received a flush with a larger seqNum than what we have prepared LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush prepare marker with a larger seqId: " - + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " - + prepareFlushResult.flushOpSeqId + ". Ignoring"); - // We do not have multiple active snapshots in the memstore or a way to merge - // current + + "Received a flush prepare marker with a larger seqId: " + + +flush.getFlushSequenceNumber() + " before clearing the previous one with seqId: " + + prepareFlushResult.flushOpSeqId + ". Ignoring"); + // We do not have multiple active snapshots in the memstore or a way to merge current // memstore snapshot with the contents and resnapshot for now. We cannot take // another snapshot and drop the previous one because that will cause temporary - // data loss in the secondary. So we ignore this for now, deferring the - // resolution - // to happen when we see the corresponding flush commit marker. If we have a - // memstore - // snapshot with x, and later received another prepare snapshot with y (where x - // < y), - // when we see flush commit for y, we will drop snapshot for x, and can also - // drop all - // the memstore edits if everything in memstore is < y. This is the usual case - // for + // data loss in the secondary. So we ignore this for now, deferring the resolution + // to happen when we see the corresponding flush commit marker. If we have a memstore + // snapshot with x, and later received another prepare snapshot with y (where x < y), + // when we see flush commit for y, we will drop snapshot for x, and can also drop all + // the memstore edits if everything in memstore is < y. This is the usual case for // RS crash + recovery where we might see consequtive prepare flush wal markers. - // Otherwise, this will cause more memory to be used in secondary replica until - // a + // Otherwise, this will cause more memory to be used in secondary replica until a // further prapare + commit flush is seen and replayed. } } @@ -6316,29 +6007,26 @@ PrepareFlushResult replayWALFlushStartMarker(FlushDescriptor flush) throws IOExc } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; post memstore flush") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", + justification = "Intentional; post memstore flush") void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { MonitoredTask status = TaskMonitor.get().createStatus("Committing flush " + this); - // check whether we have the memstore snapshot with the corresponding seqId. - // Replay to - // secondary region replicas are in order, except for when the region moves or - // then the - // region server crashes. In those cases, we may receive replay requests out of - // order from + // check whether we have the memstore snapshot with the corresponding seqId. Replay to + // secondary region replicas are in order, except for when the region moves or then the + // region server crashes. In those cases, we may receive replay requests out of order from // the original seqIds. synchronized (writestate) { try { if (flush.getFlushSequenceNumber() < lastReplayedOpenRegionSeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return; } @@ -6347,8 +6035,8 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { if (flush.getFlushSequenceNumber() == prepareFlushResult.flushOpSeqId) { if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with seqId:" + flush.getFlushSequenceNumber() - + " and a previous prepared snapshot was found"); + + "Received a flush commit marker with seqId:" + flush.getFlushSequenceNumber() + + " and a previous prepared snapshot was found"); } // This is the regular case where we received commit flush after prepare flush // corresponding to the same seqId. @@ -6359,35 +6047,30 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { this.prepareFlushResult = null; writestate.flushing = false; } else if (flush.getFlushSequenceNumber() < prepareFlushResult.flushOpSeqId) { - // This should not happen normally. However, lets be safe and guard against - // these cases + // This should not happen normally. However, lets be safe and guard against these cases // we received a flush commit with a smaller seqId than what we have prepared - // we will pick the flush file up from this commit (if we have not seen it), but - // we + // we will pick the flush file up from this commit (if we have not seen it), but we // will not drop the memstore LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with smaller seqId: " - + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " - + prepareFlushResult.flushOpSeqId + ". Picking up new file, but not dropping" - + " prepared memstore snapshot"); + + "Received a flush commit marker with smaller seqId: " + + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " + + prepareFlushResult.flushOpSeqId + ". Picking up new file, but not dropping" + + " prepared memstore snapshot"); replayFlushInStores(flush, prepareFlushResult, false); // snapshot is not dropped, so memstore sizes should not be decremented // we still have the prepared snapshot, flushing should still be true } else { - // This should not happen normally. However, lets be safe and guard against - // these cases + // This should not happen normally. However, lets be safe and guard against these cases // we received a flush commit with a larger seqId than what we have prepared - // we will pick the flush file for this. We will also obtain the updates lock - // and - // look for contents of the memstore to see whether we have edits after this - // seqId. + // we will pick the flush file for this. We will also obtain the updates lock and + // look for contents of the memstore to see whether we have edits after this seqId. // If not, we will drop all the memstore edits and the snapshot as well. LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker with larger seqId: " - + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " - + prepareFlushResult.flushOpSeqId + ". Picking up new file and dropping prepared" - + " memstore snapshot"); + + "Received a flush commit marker with larger seqId: " + + flush.getFlushSequenceNumber() + " than what we have prepared with seqId: " + + prepareFlushResult.flushOpSeqId + ". Picking up new file and dropping prepared" + + " memstore snapshot"); replayFlushInStores(flush, prepareFlushResult, true); @@ -6401,20 +6084,16 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { this.prepareFlushResult = null; writestate.flushing = false; } - // If we were waiting for observing a flush or region opening event for not - // showing - // partial data after a secondary region crash, we can allow reads now. We can - // only make - // sure that we are not showing partial data (for example skipping some previous - // edits) - // until we observe a full flush start and flush commit. So if we were not able - // to find + // If we were waiting for observing a flush or region opening event for not showing + // partial data after a secondary region crash, we can allow reads now. We can only make + // sure that we are not showing partial data (for example skipping some previous edits) + // until we observe a full flush start and flush commit. So if we were not able to find // a previous flush we will not enable reads now. this.setReadsEnabled(true); } else { LOG.warn( - getRegionInfo().getEncodedName() + " : " + "Received a flush commit marker with seqId:" - + flush.getFlushSequenceNumber() + ", but no previous prepared snapshot was found"); + getRegionInfo().getEncodedName() + " : " + "Received a flush commit marker with seqId:" + + flush.getFlushSequenceNumber() + ", but no previous prepared snapshot was found"); // There is no corresponding prepare snapshot from before. // We will pick up the new flushed file replayFlushInStores(flush, null, false); @@ -6434,8 +6113,8 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "At least one of the store files in flush: " + TextFormat.shortDebugString(flush) - + " doesn't exist any more. Skip loading the file(s)", ex); + + "At least one of the store files in flush: " + TextFormat.shortDebugString(flush) + + " doesn't exist any more. Skip loading the file(s)", ex); } finally { status.cleanup(); writestate.notifyAll(); @@ -6450,24 +6129,21 @@ void replayWALFlushCommitMarker(FlushDescriptor flush) throws IOException { } /** - * Replays the given flush descriptor by opening the flush files in stores and - * dropping the + * Replays the given flush descriptor by opening the flush files in stores and dropping the * memstore snapshots if requested. - * - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated private void replayFlushInStores(FlushDescriptor flush, PrepareFlushResult prepareFlushResult, - boolean dropMemstoreSnapshot) throws IOException { + boolean dropMemstoreSnapshot) throws IOException { for (StoreFlushDescriptor storeFlush : flush.getStoreFlushesList()) { byte[] family = storeFlush.getFamilyName().toByteArray(); HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a flush commit marker from primary, but the family is not found." - + "Ignoring StoreFlushDescriptor:" + storeFlush); + + "Received a flush commit marker from primary, but the family is not found." + + "Ignoring StoreFlushDescriptor:" + storeFlush); continue; } List flushFiles = storeFlush.getFlushOutputList(); @@ -6482,8 +6158,8 @@ private void replayFlushInStores(FlushDescriptor flush, PrepareFlushResult prepa if (ctx == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Unexpected: flush commit marker received from store " + Bytes.toString(family) - + " but no associated flush context. Ignoring"); + + "Unexpected: flush commit marker received from store " + Bytes.toString(family) + + " but no associated flush context. Ignoring"); continue; } @@ -6499,7 +6175,8 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept long maxSeqId = -1; for (HStore store : stores) { String familyName = store.getColumnFamilyName(); - FileStatus[] files = WALSplitUtil.getRecoveredHFiles(fs.getFileSystem(), regionDir, familyName); + FileStatus[] files = + WALSplitUtil.getRecoveredHFiles(fs.getFileSystem(), regionDir, familyName); if (files != null && files.length != 0) { for (FileStatus file : files) { Path filePath = file.getPath(); @@ -6517,8 +6194,8 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept } if (this.rsServices != null && store.needsCompaction()) { this.rsServices.getCompactionRequestor().requestCompaction(this, store, - "load recovered hfiles request compaction", Store.PRIORITY_USER + 1, - CompactionLifeCycleTracker.DUMMY, null); + "load recovered hfiles request compaction", Store.PRIORITY_USER + 1, + CompactionLifeCycleTracker.DUMMY, null); } } } @@ -6526,10 +6203,8 @@ private long loadRecoveredHFilesIfAny(Collection stores) throws IOExcept } /** - * Be careful, this method will drop all data in the memstore of this region. - * Currently, this - * method is used to drop memstore to prevent memory leak when replaying - * recovered.edits while + * Be careful, this method will drop all data in the memstore of this region. Currently, this + * method is used to drop memstore to prevent memory leak when replaying recovered.edits while * opening region. */ private MemStoreSize dropMemStoreContents() throws IOException { @@ -6539,8 +6214,8 @@ private MemStoreSize dropMemStoreContents() throws IOException { for (HStore s : stores.values()) { MemStoreSize memStoreSize = doDropStoreMemStoreContentsForSeqId(s, HConstants.NO_SEQNUM); LOG.info("Drop memstore for Store " + s.getColumnFamilyName() + " in region " - + this.getRegionInfo().getRegionNameAsString() + " , dropped memstoresize: [" - + memStoreSize + " }"); + + this.getRegionInfo().getRegionNameAsString() + " , dropped memstoresize: [" + + memStoreSize + " }"); totalFreedSize.incMemStoreSize(memStoreSize); } return totalFreedSize.getMemStoreSize(); @@ -6550,8 +6225,7 @@ private MemStoreSize dropMemStoreContents() throws IOException { } /** - * Drops the memstore contents after replaying a flush descriptor or region open - * event replay if + * Drops the memstore contents after replaying a flush descriptor or region open event replay if * the memstore edits have seqNums smaller than the given seq id */ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) throws IOException { @@ -6563,8 +6237,8 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro if (seqId >= currentSeqId) { // then we can drop the memstore contents since everything is below this seqId LOG.info(getRegionInfo().getEncodedName() + " : " - + "Dropping memstore contents as well since replayed flush seqId: " + seqId - + " is greater than current seqId:" + currentSeqId); + + "Dropping memstore contents as well since replayed flush seqId: " + seqId + + " is greater than current seqId:" + currentSeqId); // Prepare flush (take a snapshot) and then abort (drop the snapshot) if (store == null) { @@ -6576,8 +6250,8 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro } } else { LOG.info(getRegionInfo().getEncodedName() + " : " - + "Not dropping memstore contents since replayed flush seqId: " + seqId - + " is smaller than current seqId:" + currentSeqId); + + "Not dropping memstore contents since replayed flush seqId: " + seqId + + " is smaller than current seqId:" + currentSeqId); } } finally { this.updatesLock.writeLock().unlock(); @@ -6586,7 +6260,7 @@ private MemStoreSize dropMemStoreContentsForSeqId(long seqId, HStore store) thro } private MemStoreSize doDropStoreMemStoreContentsForSeqId(HStore s, long currentSeqId) - throws IOException { + throws IOException { MemStoreSize flushableSize = s.getFlushableSize(); this.decrMemStoreSize(flushableSize); StoreFlushContext ctx = s.createFlushContext(currentSeqId, FlushLifeCycleTracker.DUMMY); @@ -6596,10 +6270,8 @@ private MemStoreSize doDropStoreMemStoreContentsForSeqId(HStore s, long currentS } private void replayWALFlushAbortMarker(FlushDescriptor flush) { - // nothing to do for now. A flush abort will cause a RS abort which means that - // the region - // will be opened somewhere else later. We will see the region open event soon, - // and replaying + // nothing to do for now. A flush abort will cause a RS abort which means that the region + // will be opened somewhere else later. We will see the region open event soon, and replaying // that will drop the snapshot } @@ -6607,20 +6279,16 @@ private void replayWALFlushCannotFlushMarker(FlushDescriptor flush, long replayS synchronized (writestate) { if (this.lastReplayedOpenRegionSeqId > replaySeqId) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying flush event :" - + TextFormat.shortDebugString(flush) + " because its sequence id " + replaySeqId - + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " - + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(flush) + " because its sequence id " + replaySeqId + + " is smaller than this regions " + "lastReplayedOpenRegionSeqId of " + + lastReplayedOpenRegionSeqId); return; } - // If we were waiting for observing a flush or region opening event for not - // showing partial - // data after a secondary region crash, we can allow reads now. This event means - // that the - // primary was not able to flush because memstore is empty when we requested - // flush. By the - // time we observe this, we are guaranteed to have up to date seqId with our - // previous + // If we were waiting for observing a flush or region opening event for not showing partial + // data after a secondary region crash, we can allow reads now. This event means that the + // primary was not able to flush because memstore is empty when we requested flush. By the + // time we observe this, we are guaranteed to have up to date seqId with our previous // assignment. this.setReadsEnabled(true); } @@ -6631,15 +6299,15 @@ PrepareFlushResult getPrepareFlushResult() { } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Intentional; cleared the memstore") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", + justification = "Intentional; cleared the memstore") void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOException { checkTargetRegion(regionEvent.getEncodedRegionName().toByteArray(), - "RegionEvent marker from WAL ", regionEvent); + "RegionEvent marker from WAL ", regionEvent); startRegionOperation(Operation.REPLAY_EVENT); try { @@ -6653,40 +6321,34 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } if (regionEvent.getEventType() != EventType.REGION_OPEN) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Unknown region event received, ignoring :" + TextFormat.shortDebugString(regionEvent)); + + "Unknown region event received, ignoring :" + TextFormat.shortDebugString(regionEvent)); return; } if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying region open event marker " - + TextFormat.shortDebugString(regionEvent)); + + TextFormat.shortDebugString(regionEvent)); } // we will use writestate as a coarse-grain lock for all the replay events synchronized (writestate) { - // Replication can deliver events out of order when primary region moves or the - // region - // server crashes, since there is no coordination between replication of - // different wal files - // belonging to different region servers. We have to safe guard against this - // case by using - // region open event's seqid. Since this is the first event that the region puts - // (after - // possibly flushing recovered.edits), after seeing this event, we can ignore - // every edit + // Replication can deliver events out of order when primary region moves or the region + // server crashes, since there is no coordination between replication of different wal files + // belonging to different region servers. We have to safe guard against this case by using + // region open event's seqid. Since this is the first event that the region puts (after + // possibly flushing recovered.edits), after seeing this event, we can ignore every edit // smaller than this seqId if (this.lastReplayedOpenRegionSeqId <= regionEvent.getLogSequenceNumber()) { this.lastReplayedOpenRegionSeqId = regionEvent.getLogSequenceNumber(); } else { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying region event :" - + TextFormat.shortDebugString(regionEvent) - + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " - + " of " + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(regionEvent) + + " because its sequence id is smaller than this regions lastReplayedOpenRegionSeqId " + + " of " + lastReplayedOpenRegionSeqId); return; } - // region open lists all the files that the region has at the time of the - // opening. Just pick + // region open lists all the files that the region has at the time of the opening. Just pick // all the files and drop prepared flushes and empty memstores for (StoreDescriptor storeDescriptor : regionEvent.getStoresList()) { // stores of primary may be different now @@ -6694,8 +6356,8 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a region open marker from primary, but the family is not found. " - + "Ignoring. StoreDescriptor:" + storeDescriptor); + + "Received a region open marker from primary, but the family is not found. " + + "Ignoring. StoreDescriptor:" + storeDescriptor); continue; } @@ -6705,7 +6367,7 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce store.refreshStoreFiles(storeFiles); // replace the files with the new ones } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "At least one of the store files: " - + storeFiles + " doesn't exist any more. Skip loading the file(s)", ex); + + storeFiles + " doesn't exist any more. Skip loading the file(s)", ex); continue; } if (store.getMaxSequenceId().orElse(0L) != storeSeqId) { @@ -6714,12 +6376,11 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } if (writestate.flushing) { - // only drop memstore snapshots if they are smaller than last flush for the - // store + // only drop memstore snapshots if they are smaller than last flush for the store if (this.prepareFlushResult.flushOpSeqId <= regionEvent.getLogSequenceNumber()) { StoreFlushContext ctx = this.prepareFlushResult.storeFlushCtxs == null - ? null - : this.prepareFlushResult.storeFlushCtxs.get(family); + ? null + : this.prepareFlushResult.storeFlushCtxs.get(family); if (ctx != null) { MemStoreSize mss = store.getFlushableSize(); ctx.abort(); @@ -6729,8 +6390,7 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } } - // Drop the memstore contents if they are now smaller than the latest seen - // flushed file + // Drop the memstore contents if they are now smaller than the latest seen flushed file dropMemStoreContentsForSeqId(regionEvent.getLogSequenceNumber(), store); if (storeSeqId > this.maxFlushedSeqId) { this.maxFlushedSeqId = storeSeqId; @@ -6744,8 +6404,7 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce // advance the mvcc read point so that the new flushed file is visible. mvcc.await(); - // If we were waiting for observing a flush or region opening event for not - // showing partial + // If we were waiting for observing a flush or region opening event for not showing partial // data after a secondary region crash, we can allow reads now. this.setReadsEnabled(true); @@ -6762,14 +6421,13 @@ void replayWALRegionEventMarker(RegionEventDescriptor regionEvent) throws IOExce } /** - * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep - * compatibility for old region + * @deprecated Since 3.0.0, will be removed in 4.0.0. Only for keep compatibility for old region * replica implementation. */ @Deprecated void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) throws IOException { checkTargetRegion(bulkLoadEvent.getEncodedRegionName().toByteArray(), - "BulkLoad marker from WAL ", bulkLoadEvent); + "BulkLoad marker from WAL ", bulkLoadEvent); if (ServerRegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { return; // if primary nothing to do @@ -6777,7 +6435,7 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " + "Replaying bulkload event marker " - + TextFormat.shortDebugString(bulkLoadEvent)); + + TextFormat.shortDebugString(bulkLoadEvent)); } // check if multiple families involved boolean multipleFamilies = false; @@ -6796,23 +6454,20 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th try { // we will use writestate as a coarse-grain lock for all the replay events synchronized (writestate) { - // Replication can deliver events out of order when primary region moves or the - // region - // server crashes, since there is no coordination between replication of - // different wal files - // belonging to different region servers. We have to safe guard against this - // case by using - // region open event's seqid. Since this is the first event that the region puts - // (after - // possibly flushing recovered.edits), after seeing this event, we can ignore - // every edit + // Replication can deliver events out of order when primary region moves or the region + // server crashes, since there is no coordination between replication of different wal files + // belonging to different region servers. We have to safe guard against this case by using + // region open event's seqid. Since this is the first event that the region puts (after + // possibly flushing recovered.edits), after seeing this event, we can ignore every edit // smaller than this seqId - if (bulkLoadEvent.getBulkloadSeqNum() >= 0 - && this.lastReplayedOpenRegionSeqId >= bulkLoadEvent.getBulkloadSeqNum()) { + if ( + bulkLoadEvent.getBulkloadSeqNum() >= 0 + && this.lastReplayedOpenRegionSeqId >= bulkLoadEvent.getBulkloadSeqNum() + ) { LOG.warn(getRegionInfo().getEncodedName() + " : " + "Skipping replaying bulkload event :" - + TextFormat.shortDebugString(bulkLoadEvent) - + " because its sequence id is smaller than this region's lastReplayedOpenRegionSeqId" - + " =" + lastReplayedOpenRegionSeqId); + + TextFormat.shortDebugString(bulkLoadEvent) + + " because its sequence id is smaller than this region's lastReplayedOpenRegionSeqId" + + " =" + lastReplayedOpenRegionSeqId); return; } @@ -6823,8 +6478,8 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th HStore store = getStore(family); if (store == null) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + "Received a bulk load marker from primary, but the family is not found. " - + "Ignoring. StoreDescriptor:" + storeDescriptor); + + "Received a bulk load marker from primary, but the family is not found. " + + "Ignoring. StoreDescriptor:" + storeDescriptor); continue; } @@ -6836,10 +6491,10 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th store.bulkLoadHFile(storeFileInfo); } catch (FileNotFoundException ex) { LOG.warn(getRegionInfo().getEncodedName() + " : " - + ((storeFileInfo != null) - ? storeFileInfo.toString() - : (new Path(Bytes.toString(family), storeFile)).toString()) - + " doesn't exist any more. Skip loading the file"); + + ((storeFileInfo != null) + ? storeFileInfo.toString() + : (new Path(Bytes.toString(family), storeFile)).toString()) + + " doesn't exist any more. Skip loading the file"); } } } @@ -6857,11 +6512,9 @@ void replayWALBulkLoadEventMarker(WALProtos.BulkLoadDescriptor bulkLoadEvent) th *

    * We will directly apply the cells to the memstore. This is because: *

      - *
    1. All the cells are gotten from {@link WALEdit}, so we only have - * {@link Put} and + *
    2. All the cells are gotten from {@link WALEdit}, so we only have {@link Put} and * {@link Delete} here
    3. - *
    4. The replay is single threaded, we do not need to acquire row lock, as the - * region is read + *
    5. The replay is single threaded, we do not need to acquire row lock, as the region is read * only so no one else can write it.
    6. *
    7. We do not need to write WAL.
    8. *
    9. We will advance MVCC in the caller directly.
    10. @@ -6879,16 +6532,12 @@ private void replayWALBatchMutate(Map> family2Cells) throws I } /** - * Replay the meta edits, i.e, flush marker, compaction marker, bulk load - * marker, region event + * Replay the meta edits, i.e, flush marker, compaction marker, bulk load marker, region event * marker, etc. *

      - * For all events other than start flush, we will just call - * {@link #refreshStoreFiles()} as the - * logic is straight-forward and robust. For start flush, we need to snapshot - * the memstore, so - * later {@link #refreshStoreFiles()} call could drop the snapshot, otherwise we - * may run out of + * For all events other than start flush, we will just call {@link #refreshStoreFiles()} as the + * logic is straight-forward and robust. For start flush, we need to snapshot the memstore, so + * later {@link #refreshStoreFiles()} call could drop the snapshot, otherwise we may run out of * memory. */ private void replayWALMetaEdit(Cell cell) throws IOException { @@ -6903,20 +6552,19 @@ private void replayWALMetaEdit(Cell cell) throws IOException { if (!writestate.flushing) { this.writestate.flushing = true; } else { - // usually this should not happen but let's make the code more robust, it is not - // a - // big deal to just ignore it, the refreshStoreFiles call should have the - // ability to + // usually this should not happen but let's make the code more robust, it is not a + // big deal to just ignore it, the refreshStoreFiles call should have the ability to // clean up the inconsistent state. LOG.debug("NOT flushing {} as already flushing", getRegionInfo()); break; } } - MonitoredTask status = TaskMonitor.get().createStatus("Preparing flush " + getRegionInfo()); + MonitoredTask status = + TaskMonitor.get().createStatus("Preparing flush " + getRegionInfo()); Collection storesToFlush = getStoresToFlush(flushDesc); try { - PrepareFlushResult prepareResult = internalPrepareFlushCache(null, flushDesc.getFlushSequenceNumber(), - storesToFlush, + PrepareFlushResult prepareResult = + internalPrepareFlushCache(null, flushDesc.getFlushSequenceNumber(), storesToFlush, status, false, FlushLifeCycleTracker.DUMMY); if (prepareResult.result == null) { // save the PrepareFlushResult so that we can use it later from commit flush @@ -6924,17 +6572,19 @@ private void replayWALMetaEdit(Cell cell) throws IOException { status.markComplete("Flush prepare successful"); if (LOG.isDebugEnabled()) { LOG.debug("{} prepared flush with seqId: {}", getRegionInfo(), - flushDesc.getFlushSequenceNumber()); + flushDesc.getFlushSequenceNumber()); } } else { - // special case empty memstore. We will still save the flush result in this - // case, + // special case empty memstore. We will still save the flush result in this case, // since our memstore is empty, but the primary is still flushing - if (prepareResult.getResult().getResult() == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY) { + if ( + prepareResult.getResult().getResult() + == FlushResult.Result.CANNOT_FLUSH_MEMSTORE_EMPTY + ) { this.prepareFlushResult = prepareResult; if (LOG.isDebugEnabled()) { LOG.debug("{} prepared empty flush with seqId: {}", getRegionInfo(), - flushDesc.getFlushSequenceNumber()); + flushDesc.getFlushSequenceNumber()); } } status.abort("Flush prepare failed with " + prepareResult.result); @@ -6945,10 +6595,8 @@ private void replayWALMetaEdit(Cell cell) throws IOException { } break; case ABORT_FLUSH: - // do nothing, an abort flush means the source region server will crash itself, - // after - // the primary region online, it will send us an open region marker, then we can - // clean + // do nothing, an abort flush means the source region server will crash itself, after + // the primary region online, it will send us an open region marker, then we can clean // up the memstore. synchronized (writestate) { writestate.flushing = false; @@ -6965,7 +6613,7 @@ private void replayWALMetaEdit(Cell cell) throws IOException { break; default: LOG.warn("{} received a flush event with unknown action: {}", getRegionInfo(), - TextFormat.shortDebugString(flushDesc)); + TextFormat.shortDebugString(flushDesc)); } } else { // for all other region events, we will do a refreshStoreFiles @@ -6998,7 +6646,7 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { try { if (!replayLock.tryLock(timeout, TimeUnit.MILLISECONDS)) { throw new TimeoutIOException( - "Timeout while waiting for lock when replaying edits for " + getRegionInfo()); + "Timeout while waiting for lock when replaying edits for " + getRegionInfo()); } } catch (InterruptedException e) { throw throwOnInterrupt(e); @@ -7011,8 +6659,7 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { long sequenceId = entry.getKey().getLogSequenceNumber(); if (lastReplayedSequenceId >= sequenceId) { // we have already replayed this edit, skip - // remember to advance the CellScanner, as we may have multiple WALEntries, we - // may still + // remember to advance the CellScanner, as we may have multiple WALEntries, we may still // need apply later WALEntries for (int i = 0; i < count; i++) { // Throw index out of bounds if our cell count is off @@ -7030,21 +6677,14 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { } Cell cell = cells.current(); if (WALEdit.isMetaEditFamily(cell)) { - // If there is meta edit, i.e, we have done flush/compaction/open, then we need - // to apply - // the previous cells first, and then replay the special meta edit. The meta - // edit is like - // a barrier, We need to keep the order. For example, the flush marker will - // contain a - // flush sequence number, which makes us possible to drop memstore content, but - // if we - // apply some edits which have greater sequence id first, then we can not drop - // the - // memstore content when replaying the flush marker, which is not good as we - // could run out + // If there is meta edit, i.e, we have done flush/compaction/open, then we need to apply + // the previous cells first, and then replay the special meta edit. The meta edit is like + // a barrier, We need to keep the order. For example, the flush marker will contain a + // flush sequence number, which makes us possible to drop memstore content, but if we + // apply some edits which have greater sequence id first, then we can not drop the + // memstore content when replaying the flush marker, which is not good as we could run out // of memory. - // And usually, a meta edit will have a special WALEntry for it, so this is just - // a safe + // And usually, a meta edit will have a special WALEntry for it, so this is just a safe // guard logic to make sure we do not break things in the worst case. if (!family2Cells.isEmpty()) { replayWALBatchMutate(family2Cells); @@ -7053,7 +6693,7 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { replayWALMetaEdit(cell); } else { family2Cells.computeIfAbsent(CellUtil.cloneFamily(cell), k -> new ArrayList<>()) - .add(cell); + .add(cell); } } // do not forget to apply the remaining cells @@ -7068,15 +6708,14 @@ void replayWALEntry(WALEntry entry, CellScanner cells) throws IOException { } /** - * If all stores ended up dropping their snapshots, we can safely drop the - * prepareFlushResult + * If all stores ended up dropping their snapshots, we can safely drop the prepareFlushResult */ private void dropPrepareFlushIfPossible() { if (writestate.flushing) { boolean canDrop = true; if (prepareFlushResult.storeFlushCtxs != null) { for (Entry entry : prepareFlushResult.storeFlushCtxs - .entrySet()) { + .entrySet()) { HStore store = getStore(entry.getKey()); if (store == null) { continue; @@ -7088,8 +6727,7 @@ private void dropPrepareFlushIfPossible() { } } - // this means that all the stores in the region has finished flushing, but the - // WAL marker + // this means that all the stores in the region has finished flushing, but the WAL marker // may not have been written or we did not receive it yet. if (canDrop) { writestate.flushing = false; @@ -7103,7 +6741,8 @@ public boolean refreshStoreFiles() throws IOException { return refreshStoreFiles(false); } - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", justification = "Notify is about post replay. Intentional") + @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "NN_NAKED_NOTIFY", + justification = "Notify is about post replay. Intentional") protected boolean refreshStoreFiles(boolean force) throws IOException { if (!force && ServerRegionReplicaUtil.isDefaultReplica(this.getRegionInfo())) { return false; // if primary nothing to do @@ -7111,7 +6750,7 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { if (LOG.isDebugEnabled()) { LOG.debug(getRegionInfo().getEncodedName() + " : " - + "Refreshing store files to see whether we can free up memstore"); + + "Refreshing store files to see whether we can free up memstore"); } long totalFreedDataSize = 0; @@ -7127,8 +6766,7 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { // MIGHT break atomic edits across column families. long maxSeqIdBefore = store.getMaxSequenceId().orElse(0L); - // refresh the store files. This is similar to observing a region open wal - // marker. + // refresh the store files. This is similar to observing a region open wal marker. store.refreshStoreFiles(); long storeSeqId = store.getMaxSequenceId().orElse(0L); @@ -7139,19 +6777,18 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { // see whether we can drop the memstore or the snapshot if (storeSeqId > maxSeqIdBefore) { if (writestate.flushing) { - // only drop memstore snapshots if they are smaller than last flush for the - // store + // only drop memstore snapshots if they are smaller than last flush for the store if (this.prepareFlushResult.flushOpSeqId <= storeSeqId) { StoreFlushContext ctx = this.prepareFlushResult.storeFlushCtxs == null - ? null - : this.prepareFlushResult.storeFlushCtxs - .get(store.getColumnFamilyDescriptor().getName()); + ? null + : this.prepareFlushResult.storeFlushCtxs + .get(store.getColumnFamilyDescriptor().getName()); if (ctx != null) { MemStoreSize mss = store.getFlushableSize(); ctx.abort(); this.decrMemStoreSize(mss); this.prepareFlushResult.storeFlushCtxs - .remove(store.getColumnFamilyDescriptor().getName()); + .remove(store.getColumnFamilyDescriptor().getName()); totalFreedDataSize += mss.getDataSize(); } } @@ -7166,18 +6803,14 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { dropPrepareFlushIfPossible(); // advance the mvcc read point so that the new flushed files are visible. - // either greater than flush seq number or they were already picked up via - // flush. + // either greater than flush seq number or they were already picked up via flush. for (HStore s : stores.values()) { mvcc.advanceTo(s.getMaxMemStoreTS().orElse(0L)); } - // smallestSeqIdInStores is the seqId that we have a corresponding hfile for. We - // can safely - // skip all edits that are to be replayed in the future with that has a smaller - // seqId - // than this. We are updating lastReplayedOpenRegionSeqId so that we can skip - // all edits + // smallestSeqIdInStores is the seqId that we have a corresponding hfile for. We can safely + // skip all edits that are to be replayed in the future with that has a smaller seqId + // than this. We are updating lastReplayedOpenRegionSeqId so that we can skip all edits // that we have picked the flush files for if (this.lastReplayedOpenRegionSeqId < smallestSeqIdInStores) { this.lastReplayedOpenRegionSeqId = smallestSeqIdInStores; @@ -7185,9 +6818,9 @@ protected boolean refreshStoreFiles(boolean force) throws IOException { } if (!map.isEmpty()) { for (Map.Entry entry : map.entrySet()) { - // Drop the memstore contents if they are now smaller than the latest seen - // flushed file - totalFreedDataSize += dropMemStoreContentsForSeqId(entry.getValue(), entry.getKey()).getDataSize(); + // Drop the memstore contents if they are now smaller than the latest seen flushed file + totalFreedDataSize += + dropMemStoreContentsForSeqId(entry.getValue(), entry.getKey()).getDataSize(); } } // C. Finally notify anyone waiting on memstore to clear: @@ -7205,35 +6838,35 @@ private void logRegionFiles() { if (LOG.isTraceEnabled()) { LOG.trace(getRegionInfo().getEncodedName() + " : Store files for region: "); stores.values().stream().filter(s -> s.getStorefiles() != null) - .flatMap(s -> s.getStorefiles().stream()) - .forEachOrdered(sf -> LOG.trace(getRegionInfo().getEncodedName() + " : " + sf)); + .flatMap(s -> s.getStorefiles().stream()) + .forEachOrdered(sf -> LOG.trace(getRegionInfo().getEncodedName() + " : " + sf)); } } /** - * Checks whether the given regionName is either equal to our region, or that - * the regionName is + * Checks whether the given regionName is either equal to our region, or that the regionName is * the primary region to our corresponding range for the secondary replica. */ private void checkTargetRegion(byte[] encodedRegionName, String exceptionMsg, Object payload) - throws WrongRegionException { + throws WrongRegionException { if (Bytes.equals(this.getRegionInfo().getEncodedNameAsBytes(), encodedRegionName)) { return; } - if (!RegionReplicaUtil.isDefaultReplica(this.getRegionInfo()) - && Bytes.equals(encodedRegionName, this.fs.getRegionInfoForFS().getEncodedNameAsBytes())) { + if ( + !RegionReplicaUtil.isDefaultReplica(this.getRegionInfo()) + && Bytes.equals(encodedRegionName, this.fs.getRegionInfoForFS().getEncodedNameAsBytes()) + ) { return; } throw new WrongRegionException( - exceptionMsg + payload + " targetted for region " + Bytes.toStringBinary(encodedRegionName) - + " does not match this region: " + this.getRegionInfo()); + exceptionMsg + payload + " targetted for region " + Bytes.toStringBinary(encodedRegionName) + + " does not match this region: " + this.getRegionInfo()); } /** * Used by tests - * * @param s Store to add edit too. * @param cell Cell to add. */ @@ -7242,15 +6875,13 @@ protected void restoreEdit(HStore s, Cell cell, MemStoreSizing memstoreAccountin } /** - * make sure have been through lease recovery before get file status, so the - * file length can be + * make sure have been through lease recovery before get file status, so the file length can be * trusted. - * * @param p File to check. * @return True if file was zero-length (and if so, we'll delete it in here). */ private static boolean isZeroLengthThenDelete(final FileSystem fs, final FileStatus stat, - final Path p) throws IOException { + final Path p) throws IOException { if (stat.getLen() > 0) { return false; } @@ -7260,12 +6891,12 @@ private static boolean isZeroLengthThenDelete(final FileSystem fs, final FileSta } protected HStore instantiateHStore(final ColumnFamilyDescriptor family, boolean warmup) - throws IOException { + throws IOException { if (family.isMobEnabled()) { if (HFile.getFormatVersion(this.conf) < HFile.MIN_FORMAT_VERSION_WITH_TAGS) { throw new IOException("A minimum HFile version of " + HFile.MIN_FORMAT_VERSION_WITH_TAGS - + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY - + " accordingly."); + + " is required for MOB feature. Consider setting " + HFile.FORMAT_VERSION_KEY + + " accordingly."); } return new HMobStore(this, family, this.conf, warmup); } @@ -7278,13 +6909,12 @@ public HStore getStore(byte[] column) { } /** - * Return HStore instance. Does not do any copy: as the number of store is - * limited, we iterate on + * Return HStore instance. Does not do any copy: as the number of store is limited, we iterate on * the list. */ private HStore getStore(Cell cell) { return stores.entrySet().stream().filter(e -> CellUtil.matchingFamily(cell, e.getKey())) - .map(e -> e.getValue()).findFirst().orElse(null); + .map(e -> e.getValue()).findFirst().orElse(null); } @Override @@ -7300,7 +6930,7 @@ public List getStoreFileList(byte[][] columns) throws IllegalArgumentExc HStore store = this.stores.get(column); if (store == null) { throw new IllegalArgumentException( - "No column family : " + new String(column, StandardCharsets.UTF_8) + " available"); + "No column family : " + new String(column, StandardCharsets.UTF_8) + " available"); } Collection storeFiles = store.getStorefiles(); if (storeFiles == null) { @@ -7324,15 +6954,14 @@ public List getStoreFileList(byte[][] columns) throws IllegalArgumentExc void checkRow(byte[] row, String op) throws IOException { if (!rowIsInRange(getRegionInfo(), row)) { throw new WrongRegionException("Requested row out of range for " + op + " on HRegion " + this - + ", startKey='" + Bytes.toStringBinary(getRegionInfo().getStartKey()) + "', getEndKey()='" - + Bytes.toStringBinary(getRegionInfo().getEndKey()) + "', row='" + Bytes.toStringBinary(row) - + "'"); + + ", startKey='" + Bytes.toStringBinary(getRegionInfo().getStartKey()) + "', getEndKey()='" + + Bytes.toStringBinary(getRegionInfo().getEndKey()) + "', row='" + Bytes.toStringBinary(row) + + "'"); } } /** * Get an exclusive ( write lock ) lock on a given row. - * * @param row Which row to lock. * @return A locked RowLock. The lock is exclusive and already aqquired. */ @@ -7348,12 +6977,12 @@ public RowLock getRowLock(byte[] row, boolean readLock) throws IOException { Span createRegionSpan(String name) { return TraceUtil.createSpan(name).setAttribute(REGION_NAMES_KEY, - Collections.singletonList(getRegionInfo().getRegionNameAsString())); + Collections.singletonList(getRegionInfo().getRegionNameAsString())); } // will be override in tests protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevRowLock) - throws IOException { + throws IOException { // create an object to use a a key in the row lock map HashedBytes rowKey = new HashedBytes(row); @@ -7369,12 +6998,13 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR // Now try an get the lock. // This can fail as if (readLock) { - // For read lock, if the caller has locked the same row previously, it will not - // try + // For read lock, if the caller has locked the same row previously, it will not try // to acquire the same read lock. It simply returns the previous row lock. RowLockImpl prevRowLockImpl = (RowLockImpl) prevRowLock; - if ((prevRowLockImpl != null) - && (prevRowLockImpl.getLock() == rowLockContext.readWriteLock.readLock())) { + if ( + (prevRowLockImpl != null) + && (prevRowLockImpl.getLock() == rowLockContext.readWriteLock.readLock()) + ) { success = true; return prevRowLock; } @@ -7400,12 +7030,11 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR if (timeout <= 0 || !result.getLock().tryLock(timeout, TimeUnit.MILLISECONDS)) { String message = "Timed out waiting for lock for row: " + rowKey + " in region " - + getRegionInfo().getEncodedName(); + + getRegionInfo().getEncodedName(); if (reachDeadlineFirst) { throw new TimeoutIOException(message); } else { - // If timeToDeadline is larger than rowLockWaitDuration, we can not drop the - // request. + // If timeToDeadline is larger than rowLockWaitDuration, we can not drop the request. throw new IOException(message); } } @@ -7415,22 +7044,19 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR } catch (InterruptedException ie) { if (LOG.isDebugEnabled()) { LOG.debug("Thread interrupted waiting for lock on row: {}, in region {}", rowKey, - getRegionInfo().getRegionNameAsString()); + getRegionInfo().getRegionNameAsString()); } throw throwOnInterrupt(ie); } catch (Error error) { - // The maximum lock count for read lock is 64K (hardcoded), when this maximum - // count - // is reached, it will throw out an Error. This Error needs to be caught so it - // can + // The maximum lock count for read lock is 64K (hardcoded), when this maximum count + // is reached, it will throw out an Error. This Error needs to be caught so it can // go ahead to process the minibatch with lock acquired. LOG.warn("Error to get row lock for {}, in region {}, cause: {}", Bytes.toStringBinary(row), - getRegionInfo().getRegionNameAsString(), error); + getRegionInfo().getRegionNameAsString(), error); IOException ioe = new IOException(error); throw ioe; } finally { - // Clean up the counts just in case this was the thing keeping the context - // alive. + // Clean up the counts just in case this was the thing keeping the context alive. if (!success && rowLockContext != null) { rowLockContext.cleanUp(); } @@ -7438,9 +7064,9 @@ protected RowLock getRowLockInternal(byte[] row, boolean readLock, RowLock prevR } private RowLock getRowLock(byte[] row, boolean readLock, final RowLock prevRowLock) - throws IOException { + throws IOException { return TraceUtil.trace(() -> getRowLockInternal(row, readLock, prevRowLock), - () -> createRegionSpan("Region.getRowLock").setAttribute(ROW_LOCK_READ_LOCK_KEY, readLock)); + () -> createRegionSpan("Region.getRowLock").setAttribute(ROW_LOCK_READ_LOCK_KEY, readLock)); } private void releaseRowLocks(List rowLocks) { @@ -7513,7 +7139,7 @@ public void setThreadName(String threadName) { @Override public String toString() { return "RowLockContext{" + "row=" + row + ", readWriteLock=" + readWriteLock + ", count=" - + count + ", threadName=" + threadName + '}'; + + count + ", threadName=" + threadName + '}'; } } @@ -7550,9 +7176,7 @@ public String toString() { } /** - * Determines whether multiple column families are present Precondition: - * familyPaths is not null - * + * Determines whether multiple column families are present Precondition: familyPaths is not null * @param familyPaths List of (column family, hfilePath) */ private static boolean hasMultipleColumnFamilies(Collection> familyPaths) { @@ -7571,43 +7195,35 @@ private static boolean hasMultipleColumnFamilies(Collection } /** - * Attempts to atomically load a group of hfiles. This is critical for loading - * rows with multiple + * Attempts to atomically load a group of hfiles. This is critical for loading rows with multiple * column families atomically. - * - * @param familyPaths List of Pair<byte[] column family, String - * hfilePath> - * @param bulkLoadListener Internal hooks enabling massaging/preparation of a - * file about to be + * @param familyPaths List of Pair<byte[] column family, String hfilePath> + * @param bulkLoadListener Internal hooks enabling massaging/preparation of a file about to be * bulk loaded - * @return Map from family to List of store file paths if successful, null if - * failed recoverably + * @return Map from family to List of store file paths if successful, null if failed recoverably * @throws IOException if failed unrecoverably. */ public Map> bulkLoadHFiles(Collection> familyPaths, - boolean assignSeqId, BulkLoadListener bulkLoadListener) throws IOException { + boolean assignSeqId, BulkLoadListener bulkLoadListener) throws IOException { return bulkLoadHFiles(familyPaths, assignSeqId, bulkLoadListener, false, null, true); } /** - * Listener class to enable callers of bulkLoadHFile() to perform any necessary - * pre/post + * Listener class to enable callers of bulkLoadHFile() to perform any necessary pre/post * processing of a given bulkload call */ public interface BulkLoadListener { /** * Called before an HFile is actually loaded - * * @param family family being loaded to * @param srcPath path of HFile * @return final path to be used for actual loading */ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String customStaging) - throws IOException; + throws IOException; /** * Called after a successful HFile load - * * @param family family being loaded to * @param srcPath path of HFile */ @@ -7615,7 +7231,6 @@ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String c /** * Called after a failed HFile load - * * @param family family being loaded to * @param srcPath path of HFile */ @@ -7623,25 +7238,19 @@ String prepareBulkLoad(byte[] family, String srcPath, boolean copyFile, String c } /** - * Attempts to atomically load a group of hfiles. This is critical for loading - * rows with multiple + * Attempts to atomically load a group of hfiles. This is critical for loading rows with multiple * column families atomically. - * - * @param familyPaths List of Pair<byte[] column family, String - * hfilePath> - * @param bulkLoadListener Internal hooks enabling massaging/preparation of a - * file about to be + * @param familyPaths List of Pair<byte[] column family, String hfilePath> + * @param bulkLoadListener Internal hooks enabling massaging/preparation of a file about to be * bulk loaded * @param copyFile always copy hfiles if true - * @param clusterIds ids from clusters that had already handled the given - * bulkload event. - * @return Map from family to List of store file paths if successful, null if - * failed recoverably + * @param clusterIds ids from clusters that had already handled the given bulkload event. + * @return Map from family to List of store file paths if successful, null if failed recoverably * @throws IOException if failed unrecoverably. */ public Map> bulkLoadHFiles(Collection> familyPaths, - boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile, - List clusterIds, boolean replicate) throws IOException { + boolean assignSeqId, BulkLoadListener bulkLoadListener, boolean copyFile, + List clusterIds, boolean replicate) throws IOException { long seqId = -1; Map> storeFiles = new TreeMap<>(Bytes.BYTES_COMPARATOR); Map storeFilesSizes = new HashMap<>(); @@ -7664,7 +7273,7 @@ public Map> bulkLoadHFiles(Collection> f HStore store = getStore(familyName); if (store == null) { ioException = new org.apache.hadoop.hbase.DoNotRetryIOException( - "No such column family " + Bytes.toStringBinary(familyName)); + "No such column family " + Bytes.toStringBinary(familyName)); } else { try { store.assertBulkLoadHFileOk(new Path(path)); @@ -7680,7 +7289,7 @@ public Map> bulkLoadHFiles(Collection> f // validation failed because of some sort of IO problem. if (ioException != null) { LOG.error("There was IO error when checking if the bulk load is ok in region {}.", this, - ioException); + ioException); throw ioException; } } @@ -7689,22 +7298,18 @@ public Map> bulkLoadHFiles(Collection> f StringBuilder list = new StringBuilder(); for (Pair p : failures) { list.append("\n").append(Bytes.toString(p.getFirst())).append(" : ") - .append(p.getSecond()); + .append(p.getSecond()); } // problem when validating LOG.warn("There was a recoverable bulk load failure likely due to a split. These (family," - + " HFile) pairs were not loaded: {}, in region {}", list.toString(), this); + + " HFile) pairs were not loaded: {}, in region {}", list.toString(), this); return null; } - // We need to assign a sequential ID that's in between two memstores in order to - // preserve - // the guarantee that all the edits lower than the highest sequential ID from - // all the - // HFiles are flushed on disk. See HBASE-10958. The sequence id returned when we - // flush is - // guaranteed to be one beyond the file made when we flushed (or if nothing to - // flush, it is + // We need to assign a sequential ID that's in between two memstores in order to preserve + // the guarantee that all the edits lower than the highest sequential ID from all the + // HFiles are flushed on disk. See HBASE-10958. The sequence id returned when we flush is + // guaranteed to be one beyond the file made when we flushed (or if nothing to flush, it is // a sequence id that we can be sure is beyond the last hfile written). if (assignSeqId) { FlushResult fs = flushcache(true, false, FlushLifeCycleTracker.DUMMY); @@ -7718,11 +7323,12 @@ public Map> bulkLoadHFiles(Collection> f waitForFlushes(); } else { throw new IOException("Could not bulk load with an assigned sequential ID because the " - + "flush didn't run. Reason for not flushing: " + ((FlushResultImpl) fs).failureReason); + + "flush didn't run. Reason for not flushing: " + ((FlushResultImpl) fs).failureReason); } } - Map>> familyWithFinalPath = new TreeMap<>(Bytes.BYTES_COMPARATOR); + Map>> familyWithFinalPath = + new TreeMap<>(Bytes.BYTES_COMPARATOR); for (Pair p : familyPaths) { byte[] familyName = p.getFirst(); String path = p.getSecond(); @@ -7736,7 +7342,7 @@ public Map> bulkLoadHFiles(Collection> f boolean reqTmp = store.storeEngine.requireWritingToTmpDirFirst(); if (bulkLoadListener != null) { finalPath = bulkLoadListener.prepareBulkLoad(familyName, path, copyFile, - reqTmp ? null : fs.getRegionDir().toString()); + reqTmp ? null : fs.getRegionDir().toString()); } Pair pair = null; if (reqTmp || !StoreFileInfo.isHFile(finalPath)) { @@ -7751,13 +7357,13 @@ public Map> bulkLoadHFiles(Collection> f // cannot recover from since it is likely a failed HDFS operation. LOG.error("There was a partial failure due to IO when attempting to" + " load " - + Bytes.toString(p.getFirst()) + " : " + p.getSecond(), ioe); + + Bytes.toString(p.getFirst()) + " : " + p.getSecond(), ioe); if (bulkLoadListener != null) { try { bulkLoadListener.failedBulkLoad(familyName, finalPath); } catch (Exception ex) { LOG.error("Error while calling failedBulkLoad for family " - + Bytes.toString(familyName) + " with path " + path, ex); + + Bytes.toString(familyName) + " with path " + path, ex); } } throw ioe; @@ -7781,7 +7387,7 @@ public Map> bulkLoadHFiles(Collection> f try { FileSystem fs = commitedStoreFile.getFileSystem(baseConf); storeFilesSizes.put(commitedStoreFile.getName(), - fs.getFileStatus(commitedStoreFile).getLen()); + fs.getFileStatus(commitedStoreFile).getLen()); } catch (IOException e) { LOG.warn("Failed to find the size of hfile " + commitedStoreFile, e); storeFilesSizes.put(commitedStoreFile.getName(), 0L); @@ -7803,13 +7409,13 @@ public Map> bulkLoadHFiles(Collection> f // TODO Need a better story for reverting partial failures due to HDFS. LOG.error("There was a partial failure due to IO when attempting to" + " load " - + Bytes.toString(familyName) + " : " + p.getSecond(), ioe); + + Bytes.toString(familyName) + " : " + p.getSecond(), ioe); if (bulkLoadListener != null) { try { bulkLoadListener.failedBulkLoad(familyName, path); } catch (Exception ex) { LOG.error("Error while calling failedBulkLoad for family " - + Bytes.toString(familyName) + " with path " + path, ex); + + Bytes.toString(familyName) + " with path " + path, ex); } } throw ioe; @@ -7825,9 +7431,9 @@ public Map> bulkLoadHFiles(Collection> f try { if (this.rsServices != null && store.needsCompaction()) { this.rsServices.getCompactionRequestor().requestSystemCompaction(this, store, - "bulkload hfiles request compaction", true); + "bulkload hfiles request compaction", true); LOG.info("Request compaction for region {} family {} after bulk load", - this.getRegionInfo().getEncodedName(), store.getColumnFamilyName()); + this.getRegionInfo().getEncodedName(), store.getColumnFamilyName()); } } catch (IOException e) { LOG.error("bulkload hfiles request compaction error ", e); @@ -7838,16 +7444,15 @@ public Map> bulkLoadHFiles(Collection> f if (wal != null && !storeFiles.isEmpty()) { // Write a bulk load event for hfiles that are loaded try { - WALProtos.BulkLoadDescriptor loadDescriptor = ProtobufUtil.toBulkLoadDescriptor( - this.getRegionInfo().getTable(), + WALProtos.BulkLoadDescriptor loadDescriptor = + ProtobufUtil.toBulkLoadDescriptor(this.getRegionInfo().getTable(), UnsafeByteOperations.unsafeWrap(this.getRegionInfo().getEncodedNameAsBytes()), storeFiles, storeFilesSizes, seqId, clusterIds, replicate); WALUtil.writeBulkLoadMarkerAndSync(this.wal, this.getReplicationScope(), getRegionInfo(), - loadDescriptor, mvcc, regionReplicationSink.orElse(null)); + loadDescriptor, mvcc, regionReplicationSink.orElse(null)); } catch (IOException ioe) { if (this.rsServices != null) { - // Have to abort region server because some hfiles has been loaded but we can't - // write + // Have to abort region server because some hfiles has been loaded but we can't write // the event into WAL isSuccessful = false; this.rsServices.abort("Failed to write bulk load event into WAL.", ioe); @@ -7863,7 +7468,7 @@ public Map> bulkLoadHFiles(Collection> f @Override public boolean equals(Object o) { return o instanceof HRegion && Bytes.equals(getRegionInfo().getRegionName(), - ((HRegion) o).getRegionInfo().getRegionName()); + ((HRegion) o).getRegionInfo().getRegionName()); } @Override @@ -7878,39 +7483,31 @@ public String toString() { // Utility methods /** - * A utility method to create new instances of HRegion based on the - * {@link HConstants#REGION_IMPL} + * A utility method to create new instances of HRegion based on the {@link HConstants#REGION_IMPL} * configuration property. - * - * @param tableDir qualified path of directory where region should be located, - * usually the table + * @param tableDir qualified path of directory where region should be located, usually the table * directory. - * @param wal The WAL is the outbound log for any updates to the HRegion - * The wal file is a - * logfile from the previous execution that's custom-computed - * for this HRegion. - * The HRegionServer computes and sorts the appropriate wal - * info for this - * HRegion. If there is a previous file (implying that the - * HRegion has been + * @param wal The WAL is the outbound log for any updates to the HRegion The wal file is a + * logfile from the previous execution that's custom-computed for this HRegion. + * The HRegionServer computes and sorts the appropriate wal info for this + * HRegion. If there is a previous file (implying that the HRegion has been * written-to before), then read it from the supplied path. * @param fs is the filesystem. * @param conf is global configuration settings. - * @param regionInfo - RegionInfo that describes the region is new), then read - * them from the + * @param regionInfo - RegionInfo that describes the region is new), then read them from the * supplied path. * @param htd the table descriptor * @return the new instance */ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configuration conf, - RegionInfo regionInfo, final TableDescriptor htd, RegionServerServices rsServices) { + RegionInfo regionInfo, final TableDescriptor htd, RegionServerServices rsServices) { try { @SuppressWarnings("unchecked") - Class regionClass = (Class) conf.getClass(HConstants.REGION_IMPL, - HRegion.class); + Class regionClass = + (Class) conf.getClass(HConstants.REGION_IMPL, HRegion.class); - Constructor c = regionClass.getConstructor(Path.class, WAL.class, FileSystem.class, - Configuration.class, + Constructor c = + regionClass.getConstructor(Path.class, WAL.class, FileSystem.class, Configuration.class, RegionInfo.class, TableDescriptor.class, RegionServerServices.class); return c.newInstance(tableDir, wal, fs, conf, regionInfo, htd, rsServices); @@ -7922,7 +7519,6 @@ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configur /** * Convenience method creating new HRegions. Used by createTable. - * * @param info Info for region to create. * @param rootDir Root directory for HBase instance * @param wal shared WAL @@ -7930,14 +7526,13 @@ public static HRegion newHRegion(Path tableDir, WAL wal, FileSystem fs, Configur * @return new HRegion */ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, - final boolean initialize) throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, + final boolean initialize) throws IOException { return createHRegion(info, rootDir, conf, hTableDescriptor, wal, initialize, null); } /** * Convenience method creating new HRegions. Used by createTable. - * * @param info Info for region to create. * @param rootDir Root directory for HBase instance * @param wal shared WAL @@ -7946,14 +7541,15 @@ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, * @return new HRegion */ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, - final boolean initialize, RegionServerServices rsRpcServices) throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal, + final boolean initialize, RegionServerServices rsRpcServices) throws IOException { LOG.info("creating " + info + ", tableDescriptor=" - + (hTableDescriptor == null ? "null" : hTableDescriptor) + ", regionDir=" + rootDir); + + (hTableDescriptor == null ? "null" : hTableDescriptor) + ", regionDir=" + rootDir); createRegionDir(conf, info, rootDir); FileSystem fs = rootDir.getFileSystem(conf); Path tableDir = CommonFSUtils.getTableDir(rootDir, info.getTable()); - HRegion region = HRegion.newHRegion(tableDir, wal, fs, conf, info, hTableDescriptor, rsRpcServices); + HRegion region = + HRegion.newHRegion(tableDir, wal, fs, conf, info, hTableDescriptor, rsRpcServices); if (initialize) { region.initialize(null); } @@ -7964,9 +7560,9 @@ public static HRegion createHRegion(final RegionInfo info, final Path rootDir, * Create a region under the given table directory. */ public static HRegion createHRegion(Configuration conf, RegionInfo regionInfo, FileSystem fs, - Path tableDir, TableDescriptor tableDesc) throws IOException { + Path tableDir, TableDescriptor tableDesc) throws IOException { LOG.info("Creating {}, tableDescriptor={}, under table dir {}", regionInfo, tableDesc, - tableDir); + tableDir); HRegionFileSystem.createRegionOnFileSystem(conf, fs, tableDir, regionInfo); HRegion region = HRegion.newHRegion(tableDir, null, fs, conf, regionInfo, tableDesc, null); return region; @@ -7976,49 +7572,40 @@ public static HRegion createHRegion(Configuration conf, RegionInfo regionInfo, F * Create the region directory in the filesystem. */ public static HRegionFileSystem createRegionDir(Configuration configuration, RegionInfo ri, - Path rootDir) throws IOException { + Path rootDir) throws IOException { FileSystem fs = rootDir.getFileSystem(configuration); Path tableDir = CommonFSUtils.getTableDir(rootDir, ri.getTable()); - // If directory already exists, will log warning and keep going. Will try to - // create + // If directory already exists, will log warning and keep going. Will try to create // .regioninfo. If one exists, will overwrite. return HRegionFileSystem.createRegionOnFileSystem(configuration, fs, tableDir, ri); } public static HRegion createHRegion(final RegionInfo info, final Path rootDir, - final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal) - throws IOException { + final Configuration conf, final TableDescriptor hTableDescriptor, final WAL wal) + throws IOException { return createHRegion(info, rootDir, conf, hTableDescriptor, wal, true); } /** * Open a Region. - * * @param info Info for region to be opened. - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure - * the wal id is - * properly kept up. HRegionStore does this every time it opens a - * new region. + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is + * properly kept up. HRegionStore does this every time it opens a new region. * @return new HRegion */ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor htd, final WAL wal, - final Configuration conf) throws IOException { + final Configuration conf) throws IOException { return openHRegion(info, htd, wal, conf, null, null); } /** * Open a Region. - * * @param info Info for region to be opened * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) - * passing the result of the call to - * HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every - * time it opens a new + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) + * passing the result of the call to HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every time it opens a new * region. * @param conf The Configuration object to use. * @param rsServices An interface we can request flushes against. @@ -8026,43 +7613,35 @@ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor h * @return new HRegion */ public static HRegion openHRegion(final RegionInfo info, final TableDescriptor htd, final WAL wal, - final Configuration conf, final RegionServerServices rsServices, - final CancelableProgressable reporter) throws IOException { + final Configuration conf, final RegionServerServices rsServices, + final CancelableProgressable reporter) throws IOException { return openHRegion(CommonFSUtils.getRootDir(conf), info, htd, wal, conf, rsServices, reporter); } /** * Open a Region. - * * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure - * the wal id is - * properly kept up. HRegionStore does this every time it opens a - * new region. + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is + * properly kept up. HRegionStore does this every time it opens a new region. * @param conf The Configuration object to use. * @return new HRegion */ public static HRegion openHRegion(Path rootDir, final RegionInfo info, final TableDescriptor htd, - final WAL wal, final Configuration conf) throws IOException { + final WAL wal, final Configuration conf) throws IOException { return openHRegion(rootDir, info, htd, wal, conf, null, null); } /** * Open a Region. - * * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) - * passing the result of the call to - * HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every - * time it opens a new + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) + * passing the result of the call to HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every time it opens a new * region. * @param conf The Configuration object to use. * @param rsServices An interface we can request flushes against. @@ -8070,9 +7649,9 @@ public static HRegion openHRegion(Path rootDir, final RegionInfo info, final Tab * @return new HRegion */ public static HRegion openHRegion(final Path rootDir, final RegionInfo info, - final TableDescriptor htd, final WAL wal, final Configuration conf, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final TableDescriptor htd, final WAL wal, final Configuration conf, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { FileSystem fs = null; if (rsServices != null) { fs = rsServices.getFileSystem(); @@ -8085,66 +7664,54 @@ public static HRegion openHRegion(final Path rootDir, final RegionInfo info, /** * Open a Region. - * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) passing - * the result of the call to HRegion#getMinSequenceId() to ensure - * the wal id is - * properly kept up. HRegionStore does this every time it opens a - * new region. + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) passing + * the result of the call to HRegion#getMinSequenceId() to ensure the wal id is + * properly kept up. HRegionStore does this every time it opens a new region. * @return new HRegion */ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, - final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal) - throws IOException { + final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal) + throws IOException { return openHRegion(conf, fs, rootDir, info, htd, wal, null, null); } /** * Open a Region. - * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param rootDir Root directory for HBase instance * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) - * passing the result of the call to - * HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every - * time it opens a new + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) + * passing the result of the call to HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every time it opens a new * region. * @param rsServices An interface we can request flushes against. * @param reporter An interface we can report progress against. * @return new HRegion */ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, - final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final Path rootDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { Path tableDir = CommonFSUtils.getTableDir(rootDir, info.getTable()); return openHRegionFromTableDir(conf, fs, tableDir, info, htd, wal, rsServices, reporter); } /** * Open a Region. - * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param info Info for region to be opened. * @param htd the table descriptor - * @param wal WAL for region to use. This method will call - * WAL#setSequenceNumber(long) - * passing the result of the call to - * HRegion#getMinSequenceId() to ensure the - * wal id is properly kept up. HRegionStore does this every - * time it opens a new + * @param wal WAL for region to use. This method will call WAL#setSequenceNumber(long) + * passing the result of the call to HRegion#getMinSequenceId() to ensure the + * wal id is properly kept up. HRegionStore does this every time it opens a new * region. * @param rsServices An interface we can request flushes against. * @param reporter An interface we can report progress against. @@ -8152,9 +7719,9 @@ public static HRegion openHRegion(final Configuration conf, final FileSystem fs, * @throws NullPointerException if {@code info} is {@code null} */ public static HRegion openHRegionFromTableDir(final Configuration conf, final FileSystem fs, - final Path tableDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, - final RegionServerServices rsServices, final CancelableProgressable reporter) - throws IOException { + final Path tableDir, final RegionInfo info, final TableDescriptor htd, final WAL wal, + final RegionServerServices rsServices, final CancelableProgressable reporter) + throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); LOG.debug("Opening region: {}", info); HRegion r = HRegion.newHRegion(tableDir, wal, fs, conf, info, htd, rsServices); @@ -8167,21 +7734,20 @@ public NavigableMap getReplicationScope() { /** * Useful when reopening a closed region (normally for unit tests) - * * @param other original object * @param reporter An interface we can report progress against. * @return new HRegion */ public static HRegion openHRegion(final HRegion other, final CancelableProgressable reporter) - throws IOException { + throws IOException { HRegionFileSystem regionFs = other.getRegionFileSystem(); HRegion r = newHRegion(regionFs.getTableDir(), other.getWAL(), regionFs.getFileSystem(), - other.baseConf, other.getRegionInfo(), other.getTableDescriptor(), null); + other.baseConf, other.getRegionInfo(), other.getTableDescriptor(), null); return r.openHRegion(reporter); } public static Region openHRegion(final Region other, final CancelableProgressable reporter) - throws IOException { + throws IOException { return openHRegion((HRegion) other, reporter); } @@ -8189,12 +7755,12 @@ public static Region openHRegion(final Region other, final CancelableProgressabl * Open HRegion. *

      * Calls initialize and sets sequenceId. - * * @return Returns this */ private HRegion openHRegion(final CancelableProgressable reporter) throws IOException { try { - CompoundConfiguration cConfig = new CompoundConfiguration().add(conf).addBytesMap(htableDescriptor.getValues()); + CompoundConfiguration cConfig = + new CompoundConfiguration().add(conf).addBytesMap(htableDescriptor.getValues()); // Refuse to open the region if we are missing local compression support TableDescriptorChecker.checkCompression(cConfig, htableDescriptor); // Refuse to open the region if encryption configuration is incorrect or @@ -8206,13 +7772,13 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce TableDescriptorChecker.checkClassLoading(cConfig, htableDescriptor); this.openSeqNum = initialize(reporter); this.mvcc.advanceTo(openSeqNum); - // The openSeqNum must be increased every time when a region is assigned, as we - // rely on it to - // determine whether a region has been successfully reopened. So here we always - // write open + // The openSeqNum must be increased every time when a region is assigned, as we rely on it to + // determine whether a region has been successfully reopened. So here we always write open // marker, even if the table is read only. - if (wal != null && getRegionServerServices() != null - && RegionReplicaUtil.isDefaultReplica(getRegionInfo())) { + if ( + wal != null && getRegionServerServices() != null + && RegionReplicaUtil.isDefaultReplica(getRegionInfo()) + ) { writeRegionOpenMarker(wal, openSeqNum); } } catch (Throwable t) { @@ -8225,7 +7791,7 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce this.close(true); } catch (Throwable e) { LOG.warn("Open region: {} failed. Try close region but got exception ", - this.getRegionInfo(), e); + this.getRegionInfo(), e); } throw t; } @@ -8234,7 +7800,6 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce /** * Open a Region on a read-only file-system (like hdfs snapshots) - * * @param conf The Configuration object to use. * @param fs Filesystem to use * @param info Info for region to be opened. @@ -8243,7 +7808,7 @@ private HRegion openHRegion(final CancelableProgressable reporter) throws IOExce * @throws NullPointerException if {@code info} is {@code null} */ public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, final FileSystem fs, - final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException { + final Path tableDir, RegionInfo info, final TableDescriptor htd) throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); if (LOG.isDebugEnabled()) { LOG.debug("Opening region (readOnly filesystem): " + info); @@ -8257,8 +7822,8 @@ public static HRegion openReadOnlyFileSystemHRegion(final Configuration conf, fi } public static HRegion warmupHRegion(final RegionInfo info, final TableDescriptor htd, - final WAL wal, final Configuration conf, final RegionServerServices rsServices, - final CancelableProgressable reporter) throws IOException { + final WAL wal, final Configuration conf, final RegionServerServices rsServices, + final CancelableProgressable reporter) throws IOException { Objects.requireNonNull(info, "RegionInfo cannot be null"); LOG.debug("Warmup {}", info); @@ -8279,7 +7844,6 @@ public static HRegion warmupHRegion(final RegionInfo info, final TableDescriptor /** * Computes the Path of the HRegion - * * @param tabledir qualified path for table * @param name ENCODED region name * @return Path of HRegion directory @@ -8291,24 +7855,24 @@ public static Path getRegionDir(final Path tabledir, final String name) { } /** - * Determines if the specified row is within the row range specified by the - * specified RegionInfo - * + * Determines if the specified row is within the row range specified by the specified RegionInfo * @param info RegionInfo that specifies the row range * @param row row to be checked * @return true if the row is within the range specified by the RegionInfo */ public static boolean rowIsInRange(RegionInfo info, final byte[] row) { return ((info.getStartKey().length == 0) || (Bytes.compareTo(info.getStartKey(), row) <= 0)) - && ((info.getEndKey().length == 0) || (Bytes.compareTo(info.getEndKey(), row) > 0)); + && ((info.getEndKey().length == 0) || (Bytes.compareTo(info.getEndKey(), row) > 0)); } public static boolean rowIsInRange(RegionInfo info, final byte[] row, final int offset, - final short length) { + final short length) { return ((info.getStartKey().length == 0) - || (Bytes.compareTo(info.getStartKey(), 0, info.getStartKey().length, row, offset, length) <= 0)) - && ((info.getEndKey().length == 0) - || (Bytes.compareTo(info.getEndKey(), 0, info.getEndKey().length, row, offset, length) > 0)); + || (Bytes.compareTo(info.getStartKey(), 0, info.getStartKey().length, row, offset, length) + <= 0)) + && ((info.getEndKey().length == 0) + || (Bytes.compareTo(info.getEndKey(), 0, info.getEndKey().length, row, offset, length) + > 0)); } @Override @@ -8339,13 +7903,13 @@ public List get(Get get, boolean withCoprocessor) throws IOException { } private List get(Get get, boolean withCoprocessor, long nonceGroup, long nonce) - throws IOException { + throws IOException { return TraceUtil.trace(() -> getInternal(get, withCoprocessor, nonceGroup, nonce), - () -> createRegionSpan("Region.get")); + () -> createRegionSpan("Region.get")); } private List getInternal(Get get, boolean withCoprocessor, long nonceGroup, long nonce) - throws IOException { + throws IOException { List results = new ArrayList<>(); // pre-get CP hook @@ -8363,8 +7927,7 @@ private List getInternal(Get get, boolean withCoprocessor, long nonceGroup List tmp = new ArrayList<>(); scanner.next(tmp); // Copy EC to heap, then close the scanner. - // This can be an EXPENSIVE call. It may make an extra copy from offheap to - // onheap buffers. + // This can be an EXPENSIVE call. It may make an extra copy from offheap to onheap buffers. // See more details in HBASE-26036. for (Cell cell : tmp) { results.add(CellUtil.cloneIfNecessary(cell)); @@ -8423,29 +7986,23 @@ public Result mutateRow(RowMutations rm, long nonceGroup, long nonce) throws IOE /** * Perform atomic (all or none) mutations within the region. - * - * @param mutations The list of mutations to perform. mutations - * can contain - * operations for multiple rows. Caller has to ensure that all - * rows are + * @param mutations The list of mutations to perform. mutations can contain + * operations for multiple rows. Caller has to ensure that all rows are * contained in this region. * @param rowsToLock Rows to lock * @param nonceGroup Optional nonce group of the operation (client Id) - * @param nonce Optional nonce of the operation (unique random id to ensure - * "more - * idempotence") If multiple rows are locked care should be - * taken that - * rowsToLock is sorted in order to avoid - * deadlocks. + * @param nonce Optional nonce of the operation (unique random id to ensure "more + * idempotence") If multiple rows are locked care should be taken that + * rowsToLock is sorted in order to avoid deadlocks. */ @Override public void mutateRowsWithLocks(Collection mutations, Collection rowsToLock, - long nonceGroup, long nonce) throws IOException { + long nonceGroup, long nonce) throws IOException { batchMutate(new MutationBatchOperation(this, mutations.toArray(new Mutation[mutations.size()]), - true, nonceGroup, nonce) { + true, nonceGroup, nonce) { @Override - public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List acquiredRowLocks) - throws IOException { + public MiniBatchOperationInProgress + lockRowsAndBuildMiniBatch(List acquiredRowLocks) throws IOException { RowLock prevRowLock = null; for (byte[] row : rowsToLock) { try { @@ -8456,7 +8013,7 @@ public MiniBatchOperationInProgress lockRowsAndBuildMiniBatch(List 100 - ? 100 - : rsServices.getCompactionPressure() * 100)); + ? 100 + : rsServices.getCompactionPressure() * 100)); return stats.build(); } @@ -8500,8 +8057,7 @@ public Result append(Append append, long nonceGroup, long nonce) throws IOExcept checkResources(); startRegionOperation(Operation.APPEND); try { - // All edits for the given row (across all column families) must happen - // atomically. + // All edits for the given row (across all column families) must happen atomically. return mutate(append, true, nonceGroup, nonce).getResult(); } finally { closeRegionOperation(Operation.APPEND); @@ -8520,8 +8076,7 @@ public Result increment(Increment increment, long nonceGroup, long nonce) throws checkResources(); startRegionOperation(Operation.INCREMENT); try { - // All edits for the given row (across all column families) must happen - // atomically. + // All edits for the given row (across all column families) must happen atomically. return mutate(increment, true, nonceGroup, nonce).getResult(); } finally { closeRegionOperation(Operation.INCREMENT); @@ -8530,14 +8085,14 @@ public Result increment(Increment increment, long nonceGroup, long nonce) throws } private WALKeyImpl createWALKeyForWALAppend(boolean isReplay, BatchOperation batchOp, long now, - long nonceGroup, long nonce) { + long nonceGroup, long nonce) { WALKeyImpl walKey = isReplay - ? new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), - this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, - batchOp.getClusterIds(), nonceGroup, nonce, mvcc) - : new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), - this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, - batchOp.getClusterIds(), nonceGroup, nonce, mvcc, this.getReplicationScope()); + ? new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), + this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, + batchOp.getClusterIds(), nonceGroup, nonce, mvcc) + : new WALKeyImpl(this.getRegionInfo().getEncodedNameAsBytes(), + this.htableDescriptor.getTableName(), SequenceId.NO_SEQUENCE_ID, now, + batchOp.getClusterIds(), nonceGroup, nonce, mvcc, this.getReplicationScope()); if (isReplay) { walKey.setOrigLogSeqNum(batchOp.getOrigLogSeqNum()); } @@ -8546,15 +8101,15 @@ private WALKeyImpl createWALKeyForWALAppend(boolean isReplay, BatchOperation /** Returns writeEntry associated with this append */ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, - MiniBatchOperationInProgress miniBatchOp, long now, NonceKey nonceKey) - throws IOException { + MiniBatchOperationInProgress miniBatchOp, long now, NonceKey nonceKey) + throws IOException { Preconditions.checkArgument(walEdit != null && !walEdit.isEmpty(), "WALEdit is null or empty!"); Preconditions.checkArgument( - !walEdit.isReplay() || batchOp.getOrigLogSeqNum() != SequenceId.NO_SEQUENCE_ID, - "Invalid replay sequence Id for replay WALEdit!"); + !walEdit.isReplay() || batchOp.getOrigLogSeqNum() != SequenceId.NO_SEQUENCE_ID, + "Invalid replay sequence Id for replay WALEdit!"); WALKeyImpl walKey = createWALKeyForWALAppend(walEdit.isReplay(), batchOp, now, - nonceKey.getNonceGroup(), nonceKey.getNonce()); + nonceKey.getNonceGroup(), nonceKey.getNonce()); // don't call the coproc hook for writes to the WAL caused by // system lifecycle events like flushes or compactions if (this.coprocessorHost != null && !walEdit.isMetaEdit()) { @@ -8568,12 +8123,9 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, sync(txid, batchOp.durability); } /** - * If above {@link HRegion#sync} throws Exception, the RegionServer should be - * aborted and - * following {@link BatchOperation#writeMiniBatchOperationsToMemStore} will not - * be executed, - * so there is no need to replicate to secondary replica, for this reason here - * we attach the + * If above {@link HRegion#sync} throws Exception, the RegionServer should be aborted and + * following {@link BatchOperation#writeMiniBatchOperationsToMemStore} will not be executed, + * so there is no need to replicate to secondary replica, for this reason here we attach the * region replication action after the {@link HRegion#sync} is successful. */ this.attachRegionReplicationInWALAppend(batchOp, miniBatchOp, walKey, walEdit, writeEntry); @@ -8584,14 +8136,10 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, } /** - * If {@link WAL#sync} get a timeout exception, the only correct way is to abort - * the region - * server, as the design of {@link WAL#sync}, is to succeed or die, there is no - * 'failure'. It - * is usually not a big deal is because we set a very large default value(5 - * minutes) for - * {@link AbstractFSWAL#WAL_SYNC_TIMEOUT_MS}, usually the WAL system will abort - * the region + * If {@link WAL#sync} get a timeout exception, the only correct way is to abort the region + * server, as the design of {@link WAL#sync}, is to succeed or die, there is no 'failure'. It + * is usually not a big deal is because we set a very large default value(5 minutes) for + * {@link AbstractFSWAL#WAL_SYNC_TIMEOUT_MS}, usually the WAL system will abort the region * server if it can not finish the sync within 5 minutes. */ if (ioe instanceof WALSyncTimeoutIOException) { @@ -8604,31 +8152,25 @@ private WriteEntry doWALAppend(WALEdit walEdit, BatchOperation batchOp, } /** - * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for - * replicating to region + * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for replicating to region * replica. */ private void attachRegionReplicationInWALAppend(BatchOperation batchOp, - MiniBatchOperationInProgress miniBatchOp, WALKeyImpl walKey, WALEdit walEdit, - WriteEntry writeEntry) { + MiniBatchOperationInProgress miniBatchOp, WALKeyImpl walKey, WALEdit walEdit, + WriteEntry writeEntry) { if (!regionReplicationSink.isPresent()) { return; } /** - * If {@link HRegion#regionReplicationSink} is present,only - * {@link MutationBatchOperation} is + * If {@link HRegion#regionReplicationSink} is present,only {@link MutationBatchOperation} is * used and {@link NonceKey} is all the same for {@link Mutation}s in * {@link MutationBatchOperation},so for HBASE-26993 case 1,if - * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is not - * null and we could + * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is not null and we could * enter {@link HRegion#doWALAppend},that means partial {@link Mutation}s are * {@link Durability#SKIP_WAL}, we use - * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} to - * replicate to region - * replica,but if - * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is - * null,that means there is no {@link Mutation} is - * {@link Durability#SKIP_WAL},so we just use + * {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} to replicate to region + * replica,but if {@link MiniBatchOperationInProgress#getWalEditForReplicateSkipWAL} is + * null,that means there is no {@link Mutation} is {@link Durability#SKIP_WAL},so we just use * walEdit to replicate. */ assert batchOp instanceof MutationBatchOperation; @@ -8640,12 +8182,11 @@ private void attachRegionReplicationInWALAppend(BatchOperation batchOp, } /** - * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for - * replicating to region + * Attach {@link RegionReplicationSink#add} to the mvcc writeEntry for replicating to region * replica. */ private void doAttachReplicateRegionReplicaAction(WALKeyImpl walKey, WALEdit walEdit, - WriteEntry writeEntry) { + WriteEntry writeEntry) { if (walEdit == null || walEdit.isEmpty()) { return; } @@ -8669,43 +8210,34 @@ private void doAttachReplicateRegionReplicaAction(WALKeyImpl walKey, WALEdit wal // 1 x MetricsRegionWrapperImpl - metricsRegionWrapper // 1 x ReadPointCalculationLock - smallestReadPointCalcLock public static final long DEEP_OVERHEAD = FIXED_OVERHEAD + ClassSize.OBJECT + // closeLock - (2 * ClassSize.ATOMIC_BOOLEAN) + // closed, closing - (3 * ClassSize.ATOMIC_LONG) + // numPutsWithoutWAL, dataInMemoryWithoutWAL, - // compactionsFailed - (3 * ClassSize.CONCURRENT_HASHMAP) + // lockedRows, scannerReadPoints, regionLockHolders - WriteState.HEAP_SIZE + // writestate - ClassSize.CONCURRENT_SKIPLISTMAP + ClassSize.CONCURRENT_SKIPLISTMAP_ENTRY + // stores - (2 * ClassSize.REENTRANT_LOCK) + // lock, updatesLock - MultiVersionConcurrencyControl.FIXED_SIZE // mvcc - + 2 * ClassSize.TREEMAP // maxSeqIdInStores, replicationScopes - + 2 * ClassSize.ATOMIC_INTEGER // majorInProgress, minorInProgress - + ClassSize.STORE_SERVICES // store services - + StoreHotnessProtector.FIXED_SIZE; + (2 * ClassSize.ATOMIC_BOOLEAN) + // closed, closing + (3 * ClassSize.ATOMIC_LONG) + // numPutsWithoutWAL, dataInMemoryWithoutWAL, + // compactionsFailed + (3 * ClassSize.CONCURRENT_HASHMAP) + // lockedRows, scannerReadPoints, regionLockHolders + WriteState.HEAP_SIZE + // writestate + ClassSize.CONCURRENT_SKIPLISTMAP + ClassSize.CONCURRENT_SKIPLISTMAP_ENTRY + // stores + (2 * ClassSize.REENTRANT_LOCK) + // lock, updatesLock + MultiVersionConcurrencyControl.FIXED_SIZE // mvcc + + 2 * ClassSize.TREEMAP // maxSeqIdInStores, replicationScopes + + 2 * ClassSize.ATOMIC_INTEGER // majorInProgress, minorInProgress + + ClassSize.STORE_SERVICES // store services + + StoreHotnessProtector.FIXED_SIZE; @Override public long heapSize() { - // this does not take into account row locks, recent flushes, mvcc entries, and - // more + // this does not take into account row locks, recent flushes, mvcc entries, and more return DEEP_OVERHEAD + stores.values().stream().mapToLong(HStore::heapSize).sum(); } /** - * Registers a new protocol buffer {@link Service} subclass as a coprocessor - * endpoint to be - * available for handling - * {@link #execService(RpcController, CoprocessorServiceCall)} calls. + * Registers a new protocol buffer {@link Service} subclass as a coprocessor endpoint to be + * available for handling {@link #execService(RpcController, CoprocessorServiceCall)} calls. *

      - * Only a single instance may be registered per region for a given - * {@link Service} subclass (the - * instances are keyed on {@link ServiceDescriptor#getFullName()}.. After the - * first registration, - * subsequent calls with the same service name will fail with a return value of - * {@code false}. - * - * @param instance the {@code Service} subclass instance to expose as a - * coprocessor endpoint - * @return {@code true} if the registration was successful, {@code false} - * otherwise + * Only a single instance may be registered per region for a given {@link Service} subclass (the + * instances are keyed on {@link ServiceDescriptor#getFullName()}.. After the first registration, + * subsequent calls with the same service name will fail with a return value of {@code false}. + * @param instance the {@code Service} subclass instance to expose as a coprocessor endpoint + * @return {@code true} if the registration was successful, {@code false} otherwise */ public boolean registerService(Service instance) { // No stacking of instances is allowed for a single service name @@ -8713,44 +8245,37 @@ public boolean registerService(Service instance) { String serviceName = CoprocessorRpcUtils.getServiceName(serviceDesc); if (coprocessorServiceHandlers.containsKey(serviceName)) { LOG.error("Coprocessor service {} already registered, rejecting request from {} in region {}", - serviceName, instance, this); + serviceName, instance, this); return false; } coprocessorServiceHandlers.put(serviceName, instance); if (LOG.isDebugEnabled()) { LOG.debug("Registered coprocessor service: region=" - + Bytes.toStringBinary(getRegionInfo().getRegionName()) + " service=" + serviceName); + + Bytes.toStringBinary(getRegionInfo().getRegionName()) + " service=" + serviceName); } return true; } /** - * Executes a single protocol buffer coprocessor endpoint {@link Service} method - * using the - * registered protocol handlers. {@link Service} implementations must be - * registered via the + * Executes a single protocol buffer coprocessor endpoint {@link Service} method using the + * registered protocol handlers. {@link Service} implementations must be registered via the * {@link #registerService(Service)} method before they are available. - * - * @param controller an {@code RpcContoller} implementation to pass to the - * invoked service - * @param call a {@code CoprocessorServiceCall} instance identifying the - * service, method, + * @param controller an {@code RpcContoller} implementation to pass to the invoked service + * @param call a {@code CoprocessorServiceCall} instance identifying the service, method, * and parameters for the method invocation - * @return a protocol buffer {@code Message} instance containing the method's - * result - * @throws IOException if no registered service handler is found or an error - * occurs during the + * @return a protocol buffer {@code Message} instance containing the method's result + * @throws IOException if no registered service handler is found or an error occurs during the * invocation * @see #registerService(Service) */ public Message execService(RpcController controller, CoprocessorServiceCall call) - throws IOException { + throws IOException { String serviceName = call.getServiceName(); Service service = coprocessorServiceHandlers.get(serviceName); if (service == null) { throw new UnknownProtocolException(null, "No registered coprocessor service found for " - + serviceName + " in region " + Bytes.toStringBinary(getRegionInfo().getRegionName())); + + serviceName + " in region " + Bytes.toStringBinary(getRegionInfo().getRegionName())); } ServiceDescriptor serviceDesc = service.getDescriptorForType(); @@ -8767,7 +8292,8 @@ public Message execService(RpcController controller, CoprocessorServiceCall call request = coprocessorHost.preEndpointInvocation(service, methodName, request); } - final Message.Builder responseBuilder = service.getResponsePrototype(methodDesc).newBuilderForType(); + final Message.Builder responseBuilder = + service.getResponsePrototype(methodDesc).newBuilderForType(); service.callMethod(methodDesc, controller, request, new RpcCallback() { @Override public void run(Message message) { @@ -8780,7 +8306,8 @@ public void run(Message message) { if (coprocessorHost != null) { coprocessorHost.postEndpointInvocation(service, methodName, request, responseBuilder); } - IOException exception = org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.getControllerException(controller); + IOException exception = + org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils.getControllerException(controller); if (exception != null) { throw exception; } @@ -8793,8 +8320,7 @@ public Optional checkSplit() { } /** - * Return the split point. An empty result indicates the region isn't - * splittable. + * Return the split point. An empty result indicates the region isn't splittable. */ public Optional checkSplit(boolean force) { // Can't split META @@ -8836,7 +8362,7 @@ public int getCompactPriority() { return Store.PRIORITY_USER; } return stores.values().stream().mapToInt(HStore::getCompactPriority).min() - .orElse(Store.NO_PRIORITY); + .orElse(Store.NO_PRIORITY); } /** Returns the coprocessor host */ @@ -8874,10 +8400,11 @@ public void startRegionOperation(Operation op) throws IOException { default: // all others break; } - if (op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op == Operation.COMPACT_REGION - || op == Operation.COMPACT_SWITCH) { - // split, merge or compact region doesn't need to check the closing/closed state - // or lock the + if ( + op == Operation.MERGE_REGION || op == Operation.SPLIT_REGION || op == Operation.COMPACT_REGION + || op == Operation.COMPACT_SWITCH + ) { + // split, merge or compact region doesn't need to check the closing/closed state or lock the // region return; } @@ -8885,8 +8412,7 @@ public void startRegionOperation(Operation op) throws IOException { throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closing"); } lock(lock.readLock()); - // Update regionLockHolders ONLY for any startRegionOperation call that is - // invoked from + // Update regionLockHolders ONLY for any startRegionOperation call that is invoked from // an RPC handler Thread thisThread = Thread.currentThread(); if (isInterruptableOp) { @@ -8907,8 +8433,7 @@ public void startRegionOperation(Operation op) throws IOException { } } catch (Exception e) { if (isInterruptableOp) { - // would be harmless to remove what we didn't add but we know by - // 'isInterruptableOp' + // would be harmless to remove what we didn't add but we know by 'isInterruptableOp' // if we added this thread to regionLockHolders regionLockHolders.remove(thisThread); } @@ -8936,13 +8461,9 @@ public void closeRegionOperation(Operation operation) throws IOException { } /** - * This method needs to be called before any public call that reads or modifies - * stores in bulk. It - * has to be called just before a try. #closeBulkRegionOperation needs to be - * called in the try's - * finally block Acquires a writelock and checks if the region is closing or - * closed. - * + * This method needs to be called before any public call that reads or modifies stores in bulk. It + * has to be called just before a try. #closeBulkRegionOperation needs to be called in the try's + * finally block Acquires a writelock and checks if the region is closing or closed. * @throws NotServingRegionException when the region is closing or closed * @throws RegionTooBusyException if failed to get the lock in time * @throws InterruptedIOException if interrupted while waiting for a lock @@ -8951,50 +8472,41 @@ private void startBulkRegionOperation(boolean writeLockNeeded) throws IOExceptio if (this.closing.get()) { throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closing"); } - if (writeLockNeeded) - lock(lock.writeLock()); - else - lock(lock.readLock()); + if (writeLockNeeded) lock(lock.writeLock()); + else lock(lock.readLock()); if (this.closed.get()) { - if (writeLockNeeded) - lock.writeLock().unlock(); - else - lock.readLock().unlock(); + if (writeLockNeeded) lock.writeLock().unlock(); + else lock.readLock().unlock(); throw new NotServingRegionException(getRegionInfo().getRegionNameAsString() + " is closed"); } regionLockHolders.put(Thread.currentThread(), true); } /** - * Closes the lock. This needs to be called in the finally block corresponding - * to the try block of + * Closes the lock. This needs to be called in the finally block corresponding to the try block of * #startRegionOperation */ private void closeBulkRegionOperation() { regionLockHolders.remove(Thread.currentThread()); - if (lock.writeLock().isHeldByCurrentThread()) - lock.writeLock().unlock(); - else - lock.readLock().unlock(); + if (lock.writeLock().isHeldByCurrentThread()) lock.writeLock().unlock(); + else lock.readLock().unlock(); } /** - * Update LongAdders for number of puts without wal and the size of possible - * data loss. These + * Update LongAdders for number of puts without wal and the size of possible data loss. These * information are exposed by the region server metrics. */ private void recordMutationWithoutWal(final Map> familyMap) { numMutationsWithoutWAL.increment(); if (numMutationsWithoutWAL.sum() <= 1) { LOG.info("writing data to region " + this - + " with WAL disabled. Data may be lost in the event of a crash."); + + " with WAL disabled. Data may be lost in the event of a crash."); } long mutationSize = 0; for (List cells : familyMap.values()) { // Optimization: 'foreach' loop is not used. See: - // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator - // objects + // HBASE-12023 HRegion.applyFamilyMapToMemstore creates too many iterator objects assert cells instanceof RandomAccess; int listSize = cells.size(); for (int i = 0; i < listSize; i++) { @@ -9011,26 +8523,25 @@ private void lock(final Lock lock) throws IOException { } /** - * Try to acquire a lock. Throw RegionTooBusyException if failed to get the lock - * in time. Throw + * Try to acquire a lock. Throw RegionTooBusyException if failed to get the lock in time. Throw * InterruptedIOException if interrupted while waiting for the lock. */ private void lock(final Lock lock, final int multiplier) throws IOException { try { final long waitTime = Math.min(maxBusyWaitDuration, - busyWaitDuration * Math.min(multiplier, maxBusyWaitMultiplier)); + busyWaitDuration * Math.min(multiplier, maxBusyWaitMultiplier)); if (!lock.tryLock(waitTime, TimeUnit.MILLISECONDS)) { // Don't print millis. Message is used as a key over in // RetriesExhaustedWithDetailsException processing. - final String regionName = this.getRegionInfo() == null ? "unknown" - : this.getRegionInfo().getRegionNameAsString(); + final String regionName = + this.getRegionInfo() == null ? "unknown" : this.getRegionInfo().getRegionNameAsString(); final String serverName = this.getRegionServerServices() == null + ? "unknown" + : (this.getRegionServerServices().getServerName() == null ? "unknown" - : (this.getRegionServerServices().getServerName() == null - ? "unknown" - : this.getRegionServerServices().getServerName().toString()); + : this.getRegionServerServices().getServerName().toString()); RegionTooBusyException rtbe = new RegionTooBusyException( - "Failed to obtain lock; regionName=" + regionName + ", server=" + serverName); + "Failed to obtain lock; regionName=" + regionName + ", server=" + serverName); LOG.warn("Region is too busy to allow lock acquisition.", rtbe); throw rtbe; } @@ -9044,7 +8555,6 @@ private void lock(final Lock lock, final int multiplier) throws IOException { /** * Calls sync with the given transaction ID - * * @param txid should sync up to which transaction * @throws IOException If anything goes wrong with DFS */ @@ -9084,10 +8594,7 @@ private boolean shouldSyncWAL() { return regionDurability.ordinal() > Durability.ASYNC_WAL.ordinal(); } - /** - * Returns the latest sequence number that was read from storage when this - * region was opened - */ + /** Returns the latest sequence number that was read from storage when this region was opened */ public long getOpenSeqNum() { return this.openSeqNum; } @@ -9105,8 +8612,8 @@ public long getOldestSeqIdOfStore(byte[] familyName) { public CompactionState getCompactionState() { boolean hasMajor = majorInProgress.get() > 0, hasMinor = minorInProgress.get() > 0; return (hasMajor - ? (hasMinor ? CompactionState.MAJOR_AND_MINOR : CompactionState.MAJOR) - : (hasMinor ? CompactionState.MINOR : CompactionState.NONE)); + ? (hasMinor ? CompactionState.MAJOR_AND_MINOR : CompactionState.MAJOR) + : (hasMinor ? CompactionState.MINOR : CompactionState.NONE)); } public void reportCompactionRequestStart(boolean isMajor) { @@ -9145,8 +8652,7 @@ protected void decrementFlushesQueuedCount() { } /** - * If a handler thread is eligible for interrupt, make it ineligible. Should be - * paired with + * If a handler thread is eligible for interrupt, make it ineligible. Should be paired with * {{@link #enableInterrupts()}. */ void disableInterrupts() { @@ -9154,8 +8660,7 @@ void disableInterrupts() { } /** - * If a handler thread was made ineligible for interrupt via - * {{@link #disableInterrupts()}, make + * If a handler thread was made ineligible for interrupt via {{@link #disableInterrupts()}, make * it eligible again. No-op if interrupts are already enabled. */ void enableInterrupts() { @@ -9164,8 +8669,7 @@ void enableInterrupts() { /** * Interrupt any region options that have acquired the region lock via - * {@link #startRegionOperation(org.apache.hadoop.hbase.regionserver.Region.Operation)}, - * or + * {@link #startRegionOperation(org.apache.hadoop.hbase.regionserver.Region.Operation)}, or * {@link #startBulkRegionOperation(boolean)}. */ private void interruptRegionOperations() { @@ -9180,7 +8684,6 @@ private void interruptRegionOperations() { /** * Check thread interrupt status and throw an exception if interrupted. - * * @throws NotServingRegionException if region is closing * @throws InterruptedIOException if interrupted but region is not closing */ @@ -9189,7 +8692,7 @@ void checkInterrupt() throws NotServingRegionException, InterruptedIOException { if (Thread.interrupted()) { if (this.closing.get()) { throw new NotServingRegionException( - getRegionInfo().getRegionNameAsString() + " is closing"); + getRegionInfo().getRegionNameAsString() + " is closing"); } throw new InterruptedIOException(); } @@ -9197,14 +8700,13 @@ void checkInterrupt() throws NotServingRegionException, InterruptedIOException { /** * Throw the correct exception upon interrupt - * * @param t cause */ // Package scope for tests IOException throwOnInterrupt(Throwable t) { if (this.closing.get()) { return (NotServingRegionException) new NotServingRegionException( - getRegionInfo().getRegionNameAsString() + " is closing").initCause(t); + getRegionInfo().getRegionNameAsString() + " is closing").initCause(t); } return (InterruptedIOException) new InterruptedIOException().initCause(t); } @@ -9216,9 +8718,11 @@ IOException throwOnInterrupt(Throwable t) { public void onConfigurationChange(Configuration conf) { this.storeHotnessProtector.update(conf); // update coprocessorHost if the configuration has changed. - if (CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(), conf, + if ( + CoprocessorConfigurationUtil.checkConfigurationChange(getReadOnlyConfiguration(), conf, CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, - CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY)) { + CoprocessorHost.USER_REGION_COPROCESSOR_CONF_KEY) + ) { LOG.info("Update the system coprocessors because the configuration has changed"); decorateRegionConfiguration(conf); this.coprocessorHost = new RegionCoprocessorHost(this, rsServices, conf); @@ -9274,27 +8778,27 @@ void throwException(String title, String regionName) { @Override public void requestCompaction(String why, int priority, boolean major, - CompactionLifeCycleTracker tracker) throws IOException { + CompactionLifeCycleTracker tracker) throws IOException { if (major) { stores.values().forEach(HStore::triggerMajorCompaction); } rsServices.getCompactionRequestor().requestCompaction(this, why, priority, tracker, - RpcServer.getRequestUser().orElse(null)); + RpcServer.getRequestUser().orElse(null)); } @Override public void requestCompaction(byte[] family, String why, int priority, boolean major, - CompactionLifeCycleTracker tracker) throws IOException { + CompactionLifeCycleTracker tracker) throws IOException { HStore store = stores.get(family); if (store == null) { throw new NoSuchColumnFamilyException("column family " + Bytes.toString(family) - + " does not exist in region " + getRegionInfo().getRegionNameAsString()); + + " does not exist in region " + getRegionInfo().getRegionNameAsString()); } if (major) { store.triggerMajorCompaction(); } rsServices.getCompactionRequestor().requestCompaction(this, store, why, priority, tracker, - RpcServer.getRequestUser().orElse(null)); + RpcServer.getRequestUser().orElse(null)); } private void requestFlushIfNeeded() throws RegionTooBusyException { @@ -9335,9 +8839,7 @@ public void requestFlush(FlushLifeCycleTracker tracker) throws IOException { } /** - * This method modifies the region's configuration in order to inject - * replication-related features - * + * This method modifies the region's configuration in order to inject replication-related features * @param conf region configurations */ private static void decorateRegionConfiguration(Configuration conf) { @@ -9346,7 +8848,7 @@ private static void decorateRegionConfiguration(Configuration conf) { String replicationCoprocessorClass = ReplicationObserver.class.getCanonicalName(); if (!plugins.contains(replicationCoprocessorClass)) { conf.set(CoprocessorHost.REGION_COPROCESSOR_CONF_KEY, - (plugins.equals("") ? "" : (plugins + ",")) + replicationCoprocessorClass); + (plugins.equals("") ? "" : (plugins + ",")) + replicationCoprocessorClass); } } } @@ -9363,7 +8865,8 @@ public void addWriteRequestsCount(long writeRequestsCount) { this.writeRequestsCount.add(writeRequestsCount); } - @RestrictedApi(explanation = "Should only be called in tests", link = "", allowedOnPath = ".*/src/test/.*") + @RestrictedApi(explanation = "Should only be called in tests", link = "", + allowedOnPath = ".*/src/test/.*") boolean isReadsEnabled() { return this.writestate.readsEnabled; } From 5360e32275b7fb613e4802ad4eabfdf67e9c7b42 Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:57:57 +0900 Subject: [PATCH 6/7] Remove exclamation mark in while loop --- .../main/java/org/apache/hadoop/hbase/regionserver/HRegion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 4dcf8ab58093..f2b969d578af 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -4036,7 +4036,7 @@ private static Get toGet(final Mutation mutation) throws IOException { assert mutation instanceof Increment || mutation instanceof Append; Get get = new Get(mutation.getRow()); CellScanner cellScanner = mutation.cellScanner(); - while (!cellScanner.advance()) { + while (cellScanner.advance()) { Cell cell = cellScanner.current(); get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } From cb4f59cc998de10cea50d441848ed6e10adcb06d Mon Sep 17 00:00:00 2001 From: fjvbn2003 Date: Sun, 19 May 2024 20:59:11 +0900 Subject: [PATCH 7/7] DELETE obsolete lines --- .../main/java/org/apache/hadoop/hbase/regionserver/HRegion.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index f2b969d578af..fdc50bc69476 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -4041,8 +4041,6 @@ private static Get toGet(final Mutation mutation) throws IOException { get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); } if (mutation instanceof Increment) { - Cell cell = cellScanner.current(); - get.addColumn(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell)); // Increment Increment increment = (Increment) mutation; get.setTimeRange(increment.getTimeRange().getMin(), increment.getTimeRange().getMax());