apurtell commented on code in PR #8584:
URL: https://github.com/apache/hbase/pull/8584#discussion_r3896401536


##########
hbase-server/src/main/java/org/apache/hadoop/hbase/master/ServerManager.java:
##########
@@ -1092,6 +1092,22 @@ public void removeRegion(final RegionInfo regionInfo) {
     flushedSequenceIdByRegion.remove(encodedName);
   }
 
+  /**
+   * Called on region OPEN to seed {@link #flushedSequenceIdByRegion} with the 
region's
+   * {@code openSeqNum}. Without this, the entry stays absent until the 
hosting server's next
+   * heartbeat, so {@link #getLastFlushedSequenceId} returns {@link 
HConstants#NO_SEQNUM} and
+   * WALSplitter conservatively treats already-durable edits as unflushed - 
producing orphaned
+   * recovered.edits when the source server crashes soon after a drain-move. 
Uses
+   * {@code putIfAbsent} so a heartbeat-supplied value (which may reflect 
flushes after open) is
+   * never regressed. See HBASE-30335.
+   */
+  public void reportRegionOpen(final RegionInfo regionInfo, final long 
openSeqNum) {
+    if (openSeqNum == HConstants.NO_SEQNUM || openSeqNum < 0) {
+      return;
+    }
+    flushedSequenceIdByRegion.putIfAbsent(regionInfo.getEncodedNameAsBytes(), 
openSeqNum);

Review Comment:
   A max merge is more correct and equally safe, because at OPEN time a region 
cannot have flushed past its own `openSeqNum`.
   
   ```java
   public void reportRegionOpen(final RegionInfo regionInfo, final long 
openSeqNum) {
     if (openSeqNum < 0) { // NO_SEQNUM == -1
       return;
     }
     flushedSequenceIdByRegion.merge(regionInfo.getEncodedNameAsBytes(), 
openSeqNum, Math::max);
   }
   ```



##########
hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestGetLastFlushedSequenceId.java:
##########
@@ -89,10 +91,14 @@ public void test() throws IOException, InterruptedException 
{
     Thread.sleep(2000);
     RegionStoreSequenceIds ids = 
testUtil.getHBaseCluster().getMaster().getServerManager()
       
.getLastFlushedSequenceId(region.getRegionInfo().getEncodedNameAsBytes());
-    assertEquals(HConstants.NO_SEQNUM, ids.getLastFlushedSequenceId());
     // This will be the sequenceid just before that of the earliest edit in 
memstore.
     long storeSequenceId = ids.getStoreSequenceId(0).getSequenceId();
     assertTrue(storeSequenceId > 0);
+    // HBASE-30335: openSeqNum is now seeded on region OPEN, so 
lastFlushedSequenceId is no
+    // longer NO_SEQNUM before the first flush - it is the region's 
openSeqNum, which must
+    // still be strictly less than the memstore's earliest unflushed edit.
+    assertNotEquals(HConstants.NO_SEQNUM, ids.getLastFlushedSequenceId());
+    assertTrue(ids.getLastFlushedSequenceId() < storeSequenceId);

Review Comment:
   This assertion is fragile. 
   It is technically off by one, but because the region open marker consumes 
one seq id, the test will currently pass.
   
   Maybe `assertNotEquals(NO_SEQNUM, ...)` instead? 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to