diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java index 3286f53..1cdbd68 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/BaseRegionObserver.java @@ -445,6 +445,16 @@ public abstract class BaseRegionObserver implements RegionObserver { final InternalScanner s) throws IOException { } + @Override + public void preRestoreWALs(ObserverContext env, + HRegionInfo info) throws IOException { + } + + @Override + public void postRestoreWALs(ObserverContext env, + HRegionInfo info) throws IOException { + } + /** * Implementers should override this version of the method and leave the deprecated one as-is. */ diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java index e133f73..5671357 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/RegionObserver.java @@ -1108,6 +1108,24 @@ public interface RegionObserver extends Coprocessor { throws IOException; /** + * Called before replaying WALs for this region. + * @param env the environment provided by the region server + * @param info the RegionInfo for this region + * @throws IOException if an error occurred on the coprocessor + */ + void preRestoreWALs(final ObserverContext env, + HRegionInfo info) throws IOException; + + /** + * Called after replaying WALs for this region. + * @param env the environment provided by the region server + * @param info the RegionInfo for this region + * @throws IOException if an error occurred on the coprocessor + */ + void postRestoreWALs(final ObserverContext env, + HRegionInfo info) throws IOException; + + /** * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit} * replayed for this region. */ 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 f03c205..45bf7ab 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 @@ -4084,6 +4084,10 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi int period = this.conf.getInt("hbase.hstore.report.period", 300000); long lastReport = EnvironmentEdgeManager.currentTime(); + if (coprocessorHost != null) { + coprocessorHost.preRestoreWALs(this.getRegionInfo()); + } + while ((entry = reader.next()) != null) { WALKey key = entry.getKey(); WALEdit val = entry.getEdit(); @@ -4202,6 +4206,10 @@ public class HRegion implements HeapSize, PropagatingConfigurationObserver, Regi coprocessorHost.postWALRestore(this.getRegionInfo(), key, val); } } + + if (coprocessorHost != null) { + coprocessorHost.postRestoreWALs(this.getRegionInfo()); + } } catch (EOFException eof) { Path p = WALSplitter.moveAsideBadEditsFile(fs, edits); msg = "Encountered EOF. Most likely due to Master failure during " + diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java index 48e67f7..8c212b6 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/RegionCoprocessorHost.java @@ -1402,6 +1402,34 @@ public class RegionCoprocessorHost } /** + * @param info the RegionInfo for this region + * @throws IOException Exception + */ + public boolean preRestoreWALs(final HRegionInfo info) throws IOException { + return execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { + @Override + public void call(RegionObserver oserver, ObserverContext ctx) + throws IOException { + oserver.preRestoreWALs(ctx, info); + } + }); + } + + /** + * @param info the RegionInfo for this region + * @throws IOException Exception + */ + public void postRestoreWALs(final HRegionInfo info) throws IOException { + execOperation(coprocessors.isEmpty() ? null : new RegionOperation() { + @Override + public void call(RegionObserver oserver, ObserverContext ctx) + throws IOException { + oserver.postRestoreWALs(ctx, info); + } + }); + } + + /** * @param info * @param logKey * @param logEdit diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java index 58a2820..fb1fbc8 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/SimpleRegionObserver.java @@ -126,6 +126,8 @@ public class SimpleRegionObserver extends BaseRegionObserver { final AtomicInteger ctPostBulkLoadHFile = new AtomicInteger(0); final AtomicInteger ctPreBatchMutate = new AtomicInteger(0); final AtomicInteger ctPostBatchMutate = new AtomicInteger(0); + final AtomicInteger ctPreRestoreWALs = new AtomicInteger(0); + final AtomicInteger ctPostRestoreWALs = new AtomicInteger(0); final AtomicInteger ctPreWALRestore = new AtomicInteger(0); final AtomicInteger ctPostWALRestore = new AtomicInteger(0); final AtomicInteger ctPreWALRestoreDeprecated = new AtomicInteger(0); @@ -651,6 +653,18 @@ public class SimpleRegionObserver extends BaseRegionObserver { } @Override + public void preRestoreWALs(ObserverContext env, + HRegionInfo info) throws IOException { + ctPreRestoreWALs.incrementAndGet(); + } + + @Override + public void postRestoreWALs(ObserverContext env, + HRegionInfo info) throws IOException { + ctPostRestoreWALs.incrementAndGet(); + } + + @Override public void preWALRestore(ObserverContext env, HRegionInfo info, WALKey logKey, WALEdit logEdit) throws IOException { String tableName = logKey.getTablename().getNameAsString(); @@ -798,6 +812,14 @@ public class SimpleRegionObserver extends BaseRegionObserver { return ctPrePrepareDeleteTS.get() > 0; } + public boolean hadPreRestoreWALs() { + return ctPreRestoreWALs.get() > 0; + } + + public boolean hadPostRestoreWALs() { + return ctPostRestoreWALs.get() > 0; + } + public boolean hadPreWALRestore() { return ctPreWALRestore.get() > 0; } @@ -931,6 +953,14 @@ public class SimpleRegionObserver extends BaseRegionObserver { return ctPostIncrement.get(); } + public int getCtPreRestoreWALs() { + return ctPreRestoreWALs.get(); + } + + public int getCtPostRestoreWALs() { + return ctPostRestoreWALs.get(); + } + public int getCtPreWALRestore() { return ctPreWALRestore.get(); } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java index abfadec..89a20a6 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/coprocessor/TestRegionObserverInterface.java @@ -607,7 +607,6 @@ public class TestRegionObserverInterface { } } - @Ignore // TODO: HBASE-13391 to fix flaky test @Test (timeout=300000) public void testRecovery() throws Exception { LOG.info(TestRegionObserverInterface.class.getName() +".testRecovery"); @@ -630,6 +629,9 @@ public class TestRegionObserverInterface { put.addColumn(C, C, C); table.put(put); + // put two times + table.put(put); + verifyMethodResult(SimpleRegionObserver.class, new String[] {"hadPreGet", "hadPostGet", "hadPrePut", "hadPostPut", "hadPreBatchMutate", "hadPostBatchMutate", "hadDelete"}, @@ -638,10 +640,11 @@ public class TestRegionObserverInterface { ); verifyMethodResult(SimpleRegionObserver.class, - new String[] {"getCtPreWALRestore", "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", - "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, + new String[] {"getCtPreRestoreWALs", "getCtPostRestoreWALs", "getCtPreWALRestore", + "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", + "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, tableName, - new Integer[] {0, 0, 1, 1, 0, 0}); + new Integer[] {0, 0, 0, 0, 2, 2, 0, 0}); cluster.killRegionServer(rs1.getRegionServer().getServerName()); Threads.sleep(1000); // Let the kill soak in. @@ -649,17 +652,17 @@ public class TestRegionObserverInterface { LOG.info("All regions assigned"); verifyMethodResult(SimpleRegionObserver.class, - new String[] {"getCtPreWALRestore", "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", - "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, + new String[] {"getCtPreRestoreWALs", "getCtPostRestoreWALs", "getCtPreWALRestore", + "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", + "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, tableName, - new Integer[]{1, 1, 0, 0, 0, 0}); + new Integer[]{1, 1, 4, 4, 0, 0, 0, 0}); } finally { util.deleteTable(tableName); table.close(); } } - @Ignore // TODO: HBASE-13391 to fix flaky test @Test (timeout=300000) public void testLegacyRecovery() throws Exception { LOG.info(TestRegionObserverInterface.class.getName() +".testLegacyRecovery"); @@ -682,6 +685,9 @@ public class TestRegionObserverInterface { put.addColumn(C, C, C); table.put(put); + // put two times + table.put(put); + verifyMethodResult(SimpleRegionObserver.Legacy.class, new String[] {"hadPreGet", "hadPostGet", "hadPrePut", "hadPostPut", "hadPreBatchMutate", "hadPostBatchMutate", "hadDelete"}, @@ -690,10 +696,11 @@ public class TestRegionObserverInterface { ); verifyMethodResult(SimpleRegionObserver.Legacy.class, - new String[] {"getCtPreWALRestore", "getCtPostWALRestore", "getCtPrePut", - "getCtPostPut", "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, + new String[] {"getCtPreRestoreWALs", "getCtPostRestoreWALs", "getCtPreWALRestore", + "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", + "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, tableName, - new Integer[] {0, 0, 1, 1, 0, 0}); + new Integer[] {0, 0, 0, 0, 2, 2, 0, 0}); cluster.killRegionServer(rs1.getRegionServer().getServerName()); Threads.sleep(1000); // Let the kill soak in. @@ -701,10 +708,11 @@ public class TestRegionObserverInterface { LOG.info("All regions assigned"); verifyMethodResult(SimpleRegionObserver.Legacy.class, - new String[] {"getCtPreWALRestore", "getCtPostWALRestore", "getCtPrePut", - "getCtPostPut", "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, + new String[] {"getCtPreRestoreWALs", "getCtPostRestoreWALs", "getCtPreWALRestore", + "getCtPostWALRestore", "getCtPrePut", "getCtPostPut", + "getCtPreWALRestoreDeprecated", "getCtPostWALRestoreDeprecated"}, tableName, - new Integer[]{1, 1, 0, 0, 1, 1}); + new Integer[]{1, 1, 4, 4, 0, 0, 4, 4}); } } finally { util.deleteTable(tableName);