You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2019/03/12 13:34:12 UTC
[hbase] branch branch-2.2 updated: HBASE-21977 Skip replay WAL and
update seqid when open regions restored from snapshot
This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch branch-2.2
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.2 by this push:
new 3649ec7 HBASE-21977 Skip replay WAL and update seqid when open regions restored from snapshot
3649ec7 is described below
commit 3649ec7daf188c71218be6d4f445479bbb7ff91c
Author: meiyi <my...@gamil.com>
AuthorDate: Thu Mar 7 09:57:37 2019 +0800
HBASE-21977 Skip replay WAL and update seqid when open regions restored from snapshot
Signed-off-by: zhangduo <zh...@apache.org>
---
.../hbase/client/ClientSideRegionScanner.java | 1 +
.../apache/hadoop/hbase/regionserver/HRegion.java | 30 ++++++++++------
.../hbase/snapshot/TestRestoreSnapshotHelper.java | 42 ++++++++++++++++++++++
3 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/ClientSideRegionScanner.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/ClientSideRegionScanner.java
index 23a2399..a23cede 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/client/ClientSideRegionScanner.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/client/ClientSideRegionScanner.java
@@ -60,6 +60,7 @@ public class ClientSideRegionScanner extends AbstractClientScanner {
// open region from the snapshot directory
region = HRegion.newHRegion(FSUtils.getTableDir(rootDir, htd.getTableName()), null, fs, conf,
hri, htd, null);
+ region.setRestoredRegion(true);
// we won't initialize the MobFileCache when not running in RS process. so provided an
// initialized cache. Consider the case: an CF was set from an mob to non-mob. if we only
// initialize cache for MOB region, NPE from HMobStore will still happen. So Initialize the
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 ffad33a..a4d3dff 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
@@ -338,6 +338,13 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
private Path regionDir;
private FileSystem walFS;
+ // set to true if the region is restored from snapshot
+ private boolean isRestoredRegion = false;
+
+ public void setRestoredRegion(boolean restoredRegion) {
+ isRestoredRegion = restoredRegion;
+ }
+
// The internal wait duration to acquire a lock before read/update
// from the region. It is not per row. The purpose of this wait time
// is to avoid waiting a long time while the region is busy, so that
@@ -951,7 +958,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
status.setStatus("Initializing all the Stores");
long maxSeqId = initializeStores(reporter, status);
this.mvcc.advanceTo(maxSeqId);
- if (ServerRegionReplicaUtil.shouldReplayRecoveredEdits(this)) {
+ if (!isRestoredRegion && ServerRegionReplicaUtil.shouldReplayRecoveredEdits(this)) {
Collection<HStore> stores = this.stores.values();
try {
// update the stores that we are replaying
@@ -1000,15 +1007,18 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
// Use maximum of log sequenceid or that which was found in stores
// (particularly if no recovered edits, seqid will be -1).
- long maxSeqIdFromFile =
- WALSplitter.getMaxRegionSequenceId(getWalFileSystem(), getWALRegionDirOfDefaultReplica());
- long 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 reopend, 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());
- WALSplitter.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), nextSeqId - 1);
+ long nextSeqId = maxSeqId + 1;
+ if (!isRestoredRegion) {
+ long maxSeqIdFromFile =
+ WALSplitter.getMaxRegionSequenceId(getWalFileSystem(), getWALRegionDirOfDefaultReplica());
+ 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 reopend, 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());
+ WALSplitter.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), nextSeqId - 1);
+ }
}
LOG.info("Opened {}; next sequenceid={}", this.getRegionInfo().getShortNameToLog(), nextSeqId);
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestRestoreSnapshotHelper.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestRestoreSnapshotHelper.java
index c1ce040..acc1f55 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestRestoreSnapshotHelper.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/snapshot/TestRestoreSnapshotHelper.java
@@ -31,12 +31,14 @@ import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.TableDescriptor;
import org.apache.hadoop.hbase.errorhandling.ForeignExceptionDispatcher;
import org.apache.hadoop.hbase.io.HFileLink;
import org.apache.hadoop.hbase.mob.MobUtils;
import org.apache.hadoop.hbase.monitoring.MonitoredTask;
+import org.apache.hadoop.hbase.regionserver.HRegion;
import org.apache.hadoop.hbase.regionserver.StoreFileInfo;
import org.apache.hadoop.hbase.snapshot.SnapshotTestingUtils.SnapshotMock;
import org.apache.hadoop.hbase.testclassification.MediumTests;
@@ -45,6 +47,7 @@ import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.CommonFSUtils;
import org.apache.hadoop.hbase.util.FSTableDescriptors;
import org.apache.hadoop.hbase.util.FSUtils;
+import org.apache.hadoop.hbase.wal.WALSplitter;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
@@ -136,6 +139,45 @@ public class TestRestoreSnapshotHelper {
checkNoHFileLinkInTableDir(tableName);
}
+ @Test
+ public void testSkipReplayAndUpdateSeqId() throws Exception {
+ rootDir = TEST_UTIL.getDefaultRootDirPath();
+ FSUtils.setRootDir(conf, rootDir);
+ TableName tableName = TableName.valueOf("testSkipReplayAndUpdateSeqId");
+ String snapshotName = "testSkipReplayAndUpdateSeqId";
+ createTableAndSnapshot(tableName, snapshotName);
+ // put some data in the table
+ Table table = TEST_UTIL.getConnection().getTable(tableName);
+ TEST_UTIL.loadTable(table, Bytes.toBytes("A"));
+
+ Configuration conf = TEST_UTIL.getConfiguration();
+ Path rootDir = FSUtils.getRootDir(conf);
+ Path restoreDir = new Path("/hbase/.tmp-restore/testScannerWithRestoreScanner2");
+ // restore snapshot.
+ final RestoreSnapshotHelper.RestoreMetaChanges meta =
+ RestoreSnapshotHelper.copySnapshotForScanner(conf, fs, rootDir, restoreDir, snapshotName);
+ TableDescriptor htd = meta.getTableDescriptor();
+ final List<RegionInfo> restoredRegions = meta.getRegionsToAdd();
+ for (RegionInfo restoredRegion : restoredRegions) {
+ // open restored region
+ HRegion region = HRegion.newHRegion(FSUtils.getTableDir(restoreDir, tableName), null, fs,
+ conf, restoredRegion, htd, null);
+ // set restore flag
+ region.setRestoredRegion(true);
+ region.initialize();
+ Path recoveredEdit =
+ FSUtils.getWALRegionDir(conf, tableName, region.getRegionInfo().getEncodedName());
+ long maxSeqId = WALSplitter.getMaxRegionSequenceId(fs, recoveredEdit);
+
+ // open restored region without set restored flag
+ HRegion region2 = HRegion.newHRegion(FSUtils.getTableDir(restoreDir, tableName), null, fs,
+ conf, restoredRegion, htd, null);
+ region2.initialize();
+ long maxSeqId2 = WALSplitter.getMaxRegionSequenceId(fs, recoveredEdit);
+ Assert.assertTrue(maxSeqId2 > maxSeqId);
+ }
+ }
+
protected void createTableAndSnapshot(TableName tableName, String snapshotName)
throws IOException {
byte[] column = Bytes.toBytes("A");