This is an automated email from the ASF dual-hosted git repository.

domgarguilo pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/2.1 by this push:
     new 5bba2f3cf3 Improvements to scan ref removal in DatafileManager (#5674)
5bba2f3cf3 is described below

commit 5bba2f3cf36717d0e2fabbf4abb93c3455c0619e
Author: Dom G. <domgargu...@apache.org>
AuthorDate: Wed Jul 2 11:36:32 2025 -0400

    Improvements to scan ref removal in DatafileManager (#5674)
    
    * Use a new scheduled task in the tablet server to clean up all scan refs. 
This removes the attempt to clean them up after each scan so we can batch this 
operation
    
    ---------
    
    Co-authored-by: Keith Turner <ktur...@apache.org>
---
 .../org/apache/accumulo/tserver/TabletServer.java  |  2 +-
 .../accumulo/tserver/tablet/DatafileManager.java   | 71 +++++++++++-----------
 .../org/apache/accumulo/tserver/tablet/Tablet.java | 18 +++++-
 3 files changed, 51 insertions(+), 40 deletions(-)

diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
index d5d411db50..0cf5c2ec47 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
@@ -314,7 +314,7 @@ public class TabletServer extends AbstractServer
         
context.getScheduledExecutor().scheduleWithFixedDelay(Threads.createNamedRunnable(
             "ScanRefCleanupTask", () -> 
getOnlineTablets().values().forEach(tablet -> {
               try {
-                tablet.removeOrphanedScanRefs();
+                tablet.removeBatchedScanRefs();
               } catch (Exception e) {
                 log.error("Error cleaning up stale scan references for tablet 
{}",
                     tablet.getExtent(), e);
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/DatafileManager.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/DatafileManager.java
index df88ad6225..ce8c4dcd29 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/DatafileManager.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/DatafileManager.java
@@ -119,43 +119,27 @@ class DatafileManager {
 
   void returnFilesForScan(Long reservationId) {
 
-    final Set<StoredTabletFile> filesToDelete = new HashSet<>();
-
-    try {
-      synchronized (tablet) {
-        Set<StoredTabletFile> absFilePaths = 
scanFileReservations.remove(reservationId);
+    synchronized (tablet) {
+      Set<StoredTabletFile> absFilePaths = 
scanFileReservations.remove(reservationId);
 
-        if (absFilePaths == null) {
-          throw new IllegalArgumentException("Unknown scan reservation id " + 
reservationId);
-        }
+      if (absFilePaths == null) {
+        throw new IllegalArgumentException("Unknown scan reservation id " + 
reservationId);
+      }
 
-        boolean notify = false;
-        try {
-          for (StoredTabletFile path : absFilePaths) {
-            long refCount = fileScanReferenceCounts.decrement(path, 1);
-            if (refCount == 0) {
-              if (filesToDeleteAfterScan.remove(path)) {
-                filesToDelete.add(path);
-              }
-              notify = true;
-            } else if (refCount < 0) {
-              throw new IllegalStateException("Scan ref count for " + path + " 
is " + refCount);
-            }
-          }
-        } finally {
-          if (notify) {
-            tablet.notifyAll();
+      boolean notify = false;
+      try {
+        for (StoredTabletFile path : absFilePaths) {
+          long refCount = fileScanReferenceCounts.decrement(path, 1);
+          if (refCount == 0) {
+            notify = true;
+          } else if (refCount < 0) {
+            throw new IllegalStateException("Scan ref count for " + path + " 
is " + refCount);
           }
         }
-      }
-    } finally {
-      // Remove scan files even if the loop above did not fully complete 
because once a
-      // file is in the set filesToDelete that means it was removed from 
filesToDeleteAfterScan
-      // and would never be added back.
-      if (!filesToDelete.isEmpty()) {
-        log.debug("Removing scan refs from metadata {} {}", 
tablet.getExtent(), filesToDelete);
-        MetadataTableUtil.removeScanFiles(tablet.getExtent(), filesToDelete, 
tablet.getContext(),
-            tablet.getTabletServer().getLock());
+      } finally {
+        if (notify) {
+          tablet.notifyAll();
+        }
       }
     }
   }
@@ -185,11 +169,10 @@ class DatafileManager {
   }
 
   /**
-   * Removes any scan-in-use metadata entries that were left behind when a 
scan cleanup was
-   * interrupted. Intended to be called periodically to clear these orphaned 
scan refs once their
-   * in-memory reference count reaches zero.
+   * This method will remove any scan references that have been added to 
filesToDeleteAfterScan.
+   * This is meant to be called periodically as to batch the removal of scan 
references.
    */
-  public void removeOrphanedScanRefs() {
+  public void removeBatchedScanRefs() {
     Set<StoredTabletFile> snapshot;
     synchronized (tablet) {
       snapshot = new HashSet<>(filesToDeleteAfterScan);
@@ -198,6 +181,20 @@ class DatafileManager {
     removeFilesAfterScan(snapshot);
   }
 
+  /**
+   * @return true if any file is no longer in use by a scan and can be 
removed, false otherwise.
+   */
+  boolean canScanRefsBeRemoved() {
+    synchronized (tablet) {
+      for (var path : filesToDeleteAfterScan) {
+        if (fileScanReferenceCounts.get(path) == 0) {
+          return true;
+        }
+      }
+      return false;
+    }
+  }
+
   private TreeSet<StoredTabletFile> waitForScansToFinish(Set<StoredTabletFile> 
pathsToWaitFor) {
     long maxWait = 10000L;
     long startTime = System.currentTimeMillis();
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
index e4d9f9787c..8e296d400d 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
@@ -2220,8 +2220,22 @@ public class Tablet extends TabletBase {
     return getDatafileManager().getUpdateCount();
   }
 
-  public void removeOrphanedScanRefs() {
-    getDatafileManager().removeOrphanedScanRefs();
+  public void removeBatchedScanRefs() {
+    synchronized (this) {
+      if (isClosed() || isClosing()) {
+        return;
+      }
+      // return early if there are no scan files to remove
+      if (!getDatafileManager().canScanRefsBeRemoved()) {
+        return;
+      }
+      incrementWritesInProgress();
+    }
+    try {
+      getDatafileManager().removeBatchedScanRefs();
+    } finally {
+      decrementWritesInProgress();
+    }
   }
 
   TabletMemory getTabletMemory() {

Reply via email to