You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by en...@apache.org on 2015/04/21 20:56:02 UTC
hbase git commit: HBASE-13515 Handle FileNotFoundException in region
replica replay for flush/compaction events
Repository: hbase
Updated Branches:
refs/heads/master 2ba4c4eb9 -> 4e0de088c
HBASE-13515 Handle FileNotFoundException in region replica replay for flush/compaction events
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/4e0de088
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/4e0de088
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/4e0de088
Branch: refs/heads/master
Commit: 4e0de088c5f2fe13ea12219ffa4b85bdb7e26553
Parents: 2ba4c4e
Author: Enis Soztutar <en...@apache.org>
Authored: Tue Apr 21 11:55:35 2015 -0700
Committer: Enis Soztutar <en...@apache.org>
Committed: Tue Apr 21 11:55:35 2015 -0700
----------------------------------------------------------------------
.../hadoop/hbase/regionserver/HRegion.java | 33 ++++++--
.../hbase/regionserver/StoreFileInfo.java | 5 +-
.../regionserver/TestHRegionReplayEvents.java | 80 +++++++++++++++++++-
3 files changed, 106 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/4e0de088/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java
----------------------------------------------------------------------
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 c731923..7ba0988 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
@@ -4073,6 +4073,11 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
}
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);
} finally {
closeRegionOperation(Operation.REPLAY_EVENT);
}
@@ -4341,16 +4346,22 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
// flushes from ALL stores.
getMVCC().advanceMemstoreReadPointIfNeeded(flush.getFlushSequenceNumber());
- // C. Finally notify anyone waiting on memstore to clear:
- // e.g. checkResources().
- synchronized (this) {
- notifyAll(); // FindBugs NN_NAKED_NOTIFY
- }
- } finally {
+ } 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);
+ }
+ finally {
status.cleanup();
writestate.notifyAll();
}
}
+
+ // C. Finally notify anyone waiting on memstore to clear:
+ // e.g. checkResources().
+ synchronized (this) {
+ notifyAll(); // FindBugs NN_NAKED_NOTIFY
+ }
}
/**
@@ -4389,6 +4400,7 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
+ Bytes.toString(family) + " but no associated flush context. Ignoring");
continue;
}
+
ctx.replayFlush(flushFiles, dropMemstoreSnapshot); // replay the flush
// Record latest flush time
@@ -4531,7 +4543,14 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi
long storeSeqId = store.getMaxSequenceId();
List<String> storeFiles = storeDescriptor.getStoreFileList();
- store.refreshStoreFiles(storeFiles); // replace the files with the new ones
+ try {
+ 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);
+ continue;
+ }
if (store.getMaxSequenceId() != storeSeqId) {
// Record latest flush time if we picked up new files
lastStoreFlushTimeMap.put(store, EnvironmentEdgeManager.currentTime());
http://git-wip-us.apache.org/repos/asf/hbase/blob/4e0de088/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
index 0a360e2..0939529 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileInfo.java
@@ -408,7 +408,10 @@ public class StoreFileInfo {
// Tabledir is up two directories from where Reference was written.
Path tableDir = p.getParent().getParent().getParent();
String nameStrippedOfSuffix = m.group(1);
- LOG.debug("reference '" + p + "' to region=" + otherRegion + " hfile=" + nameStrippedOfSuffix);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("reference '" + p + "' to region=" + otherRegion
+ + " hfile=" + nameStrippedOfSuffix);
+ }
// Build up new path with the referenced region in place of our current
// region in the reference path. Also strip regionname suffix from name.
http://git-wip-us.apache.org/repos/asf/hbase/blob/4e0de088/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionReplayEvents.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionReplayEvents.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionReplayEvents.java
index 1ced627..9c9cfdc 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionReplayEvents.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegionReplayEvents.java
@@ -28,9 +28,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.apache.hadoop.hbase.regionserver.TestHRegion.*;
-import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -58,15 +56,17 @@ import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
-import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.io.hfile.HFile;
import org.apache.hadoop.hbase.io.hfile.HFileContext;
+import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutationProto.MutationType;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.BulkLoadDescriptor;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.CompactionDescriptor;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.FlushDescriptor;
+import org.apache.hadoop.hbase.protobuf.generated.WALProtos.FlushDescriptor.StoreFlushDescriptor;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.RegionEventDescriptor;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.FlushDescriptor.FlushAction;
+import org.apache.hadoop.hbase.protobuf.generated.WALProtos.RegionEventDescriptor.EventType;
import org.apache.hadoop.hbase.protobuf.generated.WALProtos.StoreDescriptor;
import org.apache.hadoop.hbase.regionserver.HRegion.FlushResultImpl;
import org.apache.hadoop.hbase.regionserver.HRegion.PrepareFlushResult;
@@ -89,7 +89,6 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
import com.google.common.collect.Lists;
@@ -1510,6 +1509,79 @@ public class TestHRegionReplayEvents {
}
}
+ @Test
+ public void testReplayingFlushCommitWithFileAlreadyDeleted() throws IOException {
+ // tests replaying flush commit marker, but the flush file has already been compacted
+ // from primary and also deleted from the archive directory
+ secondaryRegion.replayWALFlushCommitMarker(FlushDescriptor.newBuilder().
+ setFlushSequenceNumber(Long.MAX_VALUE)
+ .setTableName(ByteString.copyFrom(primaryRegion.getTableDesc().getTableName().getName()))
+ .setAction(FlushAction.COMMIT_FLUSH)
+ .setEncodedRegionName(
+ ByteString.copyFrom(primaryRegion.getRegionInfo().getEncodedNameAsBytes()))
+ .setRegionName(ByteString.copyFrom(primaryRegion.getRegionInfo().getRegionName()))
+ .addStoreFlushes(StoreFlushDescriptor.newBuilder()
+ .setFamilyName(ByteString.copyFrom(families[0]))
+ .setStoreHomeDir("/store_home_dir")
+ .addFlushOutput("/foo/baz/bar")
+ .build())
+ .build());
+ }
+
+ @Test
+ public void testReplayingCompactionWithFileAlreadyDeleted() throws IOException {
+ // tests replaying compaction marker, but the compaction output file has already been compacted
+ // from primary and also deleted from the archive directory
+ secondaryRegion.replayWALCompactionMarker(CompactionDescriptor.newBuilder()
+ .setTableName(ByteString.copyFrom(primaryRegion.getTableDesc().getTableName().getName()))
+ .setEncodedRegionName(
+ ByteString.copyFrom(primaryRegion.getRegionInfo().getEncodedNameAsBytes()))
+ .setFamilyName(ByteString.copyFrom(families[0]))
+ .addCompactionInput("/foo")
+ .addCompactionOutput("/bar")
+ .setStoreHomeDir("/store_home_dir")
+ .setRegionName(ByteString.copyFrom(primaryRegion.getRegionInfo().getRegionName()))
+ .build()
+ , true, true, Long.MAX_VALUE);
+ }
+
+ @Test
+ public void testReplayingRegionOpenEventWithFileAlreadyDeleted() throws IOException {
+ // tests replaying region open event marker, but the region files have already been compacted
+ // from primary and also deleted from the archive directory
+ secondaryRegion.replayWALRegionEventMarker(RegionEventDescriptor.newBuilder()
+ .setTableName(ByteString.copyFrom(primaryRegion.getTableDesc().getTableName().getName()))
+ .setEncodedRegionName(
+ ByteString.copyFrom(primaryRegion.getRegionInfo().getEncodedNameAsBytes()))
+ .setRegionName(ByteString.copyFrom(primaryRegion.getRegionInfo().getRegionName()))
+ .setEventType(EventType.REGION_OPEN)
+ .setServer(ProtobufUtil.toServerName(ServerName.valueOf("foo", 1, 1)))
+ .setLogSequenceNumber(Long.MAX_VALUE)
+ .addStores(StoreDescriptor.newBuilder()
+ .setFamilyName(ByteString.copyFrom(families[0]))
+ .setStoreHomeDir("/store_home_dir")
+ .addStoreFile("/foo")
+ .build())
+ .build());
+ }
+
+ @Test
+ public void testReplayingBulkLoadEventWithFileAlreadyDeleted() throws IOException {
+ // tests replaying bulk load event marker, but the bulk load files have already been compacted
+ // from primary and also deleted from the archive directory
+ secondaryRegion.replayWALBulkLoadEventMarker(BulkLoadDescriptor.newBuilder()
+ .setTableName(ProtobufUtil.toProtoTableName(primaryRegion.getTableDesc().getTableName()))
+ .setEncodedRegionName(
+ ByteString.copyFrom(primaryRegion.getRegionInfo().getEncodedNameAsBytes()))
+ .setBulkloadSeqNum(Long.MAX_VALUE)
+ .addStores(StoreDescriptor.newBuilder()
+ .setFamilyName(ByteString.copyFrom(families[0]))
+ .setStoreHomeDir("/store_home_dir")
+ .addStoreFile("/foo")
+ .build())
+ .build());
+ }
+
private String createHFileForFamilies(Path testPath, byte[] family,
byte[] valueBytes) throws IOException {
HFile.WriterFactory hFileFactory = HFile.getWriterFactoryNoCache(TEST_UTIL.getConfiguration());