From 8d9ec188b254080423c91263873499804f6b02b6 Mon Sep 17 00:00:00 2001 From: Dom Garguilo Date: Fri, 2 Jan 2026 13:08:05 -0500 Subject: [PATCH 1/2] Refactor LockRange creation --- .../accumulo/manager/tableOps/Utils.java | 2 +- .../tableOps/availability/LockTable.java | 43 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java index cb8b7744769..4b3c5fec476 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java @@ -86,7 +86,7 @@ public static > T getNextId(String name, ServerContext c } } - private static KeyExtent findContaining(Ample ample, TableId tableId, Text row) { + public static KeyExtent findContaining(Ample ample, TableId tableId, Text row) { Objects.requireNonNull(row); try (var tablets = ample.readTablets().forTable(tableId).overlapping(row, true, row) .fetch(TabletMetadata.ColumnType.PREV_ROW).build()) { diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java index b8ab0aac5af..7b22c1ced2c 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java @@ -21,17 +21,25 @@ import org.apache.accumulo.core.client.admin.TabletAvailability; import org.apache.accumulo.core.clientImpl.thrift.TableOperation; import org.apache.accumulo.core.data.NamespaceId; +import org.apache.accumulo.core.data.Range; +import org.apache.accumulo.core.data.RowRange; import org.apache.accumulo.core.data.TableId; import org.apache.accumulo.core.dataImpl.thrift.TRange; import org.apache.accumulo.core.fate.FateId; import org.apache.accumulo.core.fate.Repo; import org.apache.accumulo.core.fate.zookeeper.DistributedReadWriteLock; +import org.apache.accumulo.core.fate.zookeeper.LockRange; +import org.apache.accumulo.core.util.RowRangeUtil; import org.apache.accumulo.manager.tableOps.AbstractFateOperation; import org.apache.accumulo.manager.tableOps.FateEnv; import org.apache.accumulo.manager.tableOps.Utils; +import org.apache.hadoop.io.Text; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class LockTable extends AbstractFateOperation { private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(LockTable.class); private final TableId tableId; private final NamespaceId namespaceId; @@ -48,10 +56,12 @@ public LockTable(TableId tableId, NamespaceId namespaceId, TRange range, @Override public long isReady(FateId fateId, FateEnv env) throws Exception { + LockRange lockRange = getLockRange(env); return Utils.reserveNamespace(env.getContext(), namespaceId, fateId, DistributedReadWriteLock.LockType.READ, true, TableOperation.SET_TABLET_AVAILABILITY) + Utils.reserveTable(env.getContext(), tableId, fateId, - DistributedReadWriteLock.LockType.WRITE, true, TableOperation.SET_TABLET_AVAILABILITY); + DistributedReadWriteLock.LockType.WRITE, true, TableOperation.SET_TABLET_AVAILABILITY, + lockRange); } @Override @@ -66,4 +76,35 @@ public void undo(FateId fateId, FateEnv env) throws Exception { Utils.unreserveTable(env.getContext(), tableId, fateId, DistributedReadWriteLock.LockType.WRITE); } + + /** + * Get the LockRange for {@code this} object using its tRange field. Converts the key-range to a + * row-range which is needed for the LockRange. We do a safe conversion meaning potentially + * locking slightly more than is needed so we have at least what we need. If the key-range can't + * be converted to a RowRange, an infinite LockRange is returned. + */ + private LockRange getLockRange(FateEnv env) { + Range range = new Range(tRange); + + try { + RowRange rowRange = RowRangeUtil.toRowRange(range); + Text startRow = rowRange.getLowerBound(); + Text endRow = rowRange.getUpperBound(); + + Text lockStartRow = null; + if (startRow != null) { + if (rowRange.isLowerBoundInclusive()) { + lockStartRow = + Utils.findContaining(env.getContext().getAmple(), tableId, startRow).prevEndRow(); + } else { + lockStartRow = startRow; + } + } + + return LockRange.of(lockStartRow, endRow); + } catch (IllegalArgumentException | java.util.NoSuchElementException e) { + LOG.debug("Unable to convert {} to a RowRange, defaulting to infinite lock range", range, e); + return LockRange.infinite(); + } + } } From 29daa35123889e52ada49409adb482e36a6f94e1 Mon Sep 17 00:00:00 2001 From: Dom Garguilo Date: Mon, 5 Jan 2026 15:39:42 -0500 Subject: [PATCH 2/2] add docs to newly public method, short circuit infinite --- .../java/org/apache/accumulo/manager/tableOps/Utils.java | 6 ++++++ .../accumulo/manager/tableOps/availability/LockTable.java | 3 +++ 2 files changed, 9 insertions(+) diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java index 4b3c5fec476..b791badf8b0 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/Utils.java @@ -86,6 +86,12 @@ public static > T getNextId(String name, ServerContext c } } + /** + * Finds the single tablet extent that contains the provided row. + * + * @throws NullPointerException if row is null + * @throws java.util.NoSuchElementException if no tablet contains the row + */ public static KeyExtent findContaining(Ample ample, TableId tableId, Text row) { Objects.requireNonNull(row); try (var tablets = ample.readTablets().forTable(tableId).overlapping(row, true, row) diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java index 7b22c1ced2c..7b5abfa3ada 100644 --- a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java +++ b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/availability/LockTable.java @@ -84,6 +84,9 @@ public void undo(FateId fateId, FateEnv env) throws Exception { * be converted to a RowRange, an infinite LockRange is returned. */ private LockRange getLockRange(FateEnv env) { + if (tRange.infiniteStartKey && tRange.infiniteStopKey) { + return LockRange.infinite(); + } Range range = new Range(tRange); try {