This is an automated email from the ASF dual-hosted git repository.
kturner pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/main by this push:
new 9812f05f4e Removed table name lock in Manager (#5801)
9812f05f4e is described below
commit 9812f05f4e4e71fc91f3d26ac9d232d6dcb8dbcf
Author: Imirie Billey <[email protected]>
AuthorDate: Tue Aug 19 13:29:59 2025 -0400
Removed table name lock in Manager (#5801)
Created `testDefendAgainstThreadsCreateSameTableNameConcurrently()` in
TableOperationsIT to ensure that Zookeeper can defend against concurrent create
table operations that try to create a table with the same table name. Verified
it worked and removed the lock in the call method in the PopulateZookeeper file.
---
.../manager/tableOps/create/PopulateZookeeper.java | 36 ++++++--------
.../apache/accumulo/test/TableOperationsIT.java | 55 ++++++++++++++++++++++
2 files changed, 70 insertions(+), 21 deletions(-)
diff --git
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
index 0517e7c8ea..4e7b01e09c 100644
---
a/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
+++
b/server/manager/src/main/java/org/apache/accumulo/manager/tableOps/create/PopulateZookeeper.java
@@ -51,30 +51,24 @@ class PopulateZookeeper extends ManagerRepo {
public Repo<Manager> call(FateId fateId, Manager manager) throws Exception {
// reserve the table name in zookeeper or fail
- Utils.getTableNameLock().lock();
- try {
- var context = manager.getContext();
- // write tableName & tableId, first to Table Mapping and then to
Zookeeper
-
context.getTableMapping(tableInfo.getNamespaceId()).put(tableInfo.getTableId(),
- tableInfo.getTableName(), TableOperation.CREATE);
- manager.getTableManager().addTable(tableInfo.getTableId(),
tableInfo.getNamespaceId(),
- tableInfo.getTableName());
-
- try {
- PropUtil.setProperties(context,
TablePropKey.of(tableInfo.getTableId()), tableInfo.props);
- } catch (IllegalStateException ex) {
- throw new ThriftTableOperationException(null, tableInfo.getTableName(),
- TableOperation.CREATE, TableOperationExceptionType.OTHER,
- "Property or value not valid for create " +
tableInfo.getTableName() + " in "
- + tableInfo.props);
- }
+ var context = manager.getContext();
+ // write tableName & tableId, first to Table Mapping and then to Zookeeper
+
context.getTableMapping(tableInfo.getNamespaceId()).put(tableInfo.getTableId(),
+ tableInfo.getTableName(), TableOperation.CREATE);
+ manager.getTableManager().addTable(tableInfo.getTableId(),
tableInfo.getNamespaceId(),
+ tableInfo.getTableName());
- context.clearTableListCache();
- return new ChooseDir(tableInfo);
- } finally {
- Utils.getTableNameLock().unlock();
+ try {
+ PropUtil.setProperties(context, TablePropKey.of(tableInfo.getTableId()),
tableInfo.props);
+ } catch (IllegalStateException ex) {
+ throw new ThriftTableOperationException(null, tableInfo.getTableName(),
TableOperation.CREATE,
+ TableOperationExceptionType.OTHER, "Property or value not valid for
create "
+ + tableInfo.getTableName() + " in " + tableInfo.props);
}
+ context.clearTableListCache();
+ return new ChooseDir(tableInfo);
+
}
@Override
diff --git a/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
b/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
index 2b9fae4677..75730ed8b1 100644
--- a/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/TableOperationsIT.java
@@ -39,10 +39,12 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import org.apache.accumulo.core.client.Accumulo;
@@ -79,6 +81,7 @@ import org.apache.accumulo.harness.AccumuloClusterHarness;
import org.apache.accumulo.manager.tableOps.Utils;
import org.apache.accumulo.test.functional.BadIterator;
import org.apache.accumulo.test.functional.FunctionalTestUtils;
+import org.apache.accumulo.test.util.Wait;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.io.Text;
import org.junit.jupiter.api.AfterEach;
@@ -202,6 +205,58 @@ public class TableOperationsIT extends
AccumuloClusterHarness {
accumuloClient.tableOperations().delete(tableName);
}
+ @Test
+ public void testDefendAgainstThreadsCreateSameTableNameConcurrently()
+ throws ExecutionException, InterruptedException {
+ final int initialTableSize =
accumuloClient.tableOperations().list().size();
+ final int numTasks = 10;
+ ExecutorService pool = Executors.newFixedThreadPool(numTasks);
+
+ for (String tablename : getUniqueNames(30)) {
+ CountDownLatch startSignal = new CountDownLatch(1);
+ AtomicInteger numTasksRunning = new AtomicInteger(0);
+
+ List<Future<Boolean>> futureList = new ArrayList<>();
+
+ for (int j = 0; j < numTasks; j++) {
+ Future<Boolean> future = pool.submit(() -> {
+ boolean result;
+ try {
+ numTasksRunning.incrementAndGet();
+ startSignal.await();
+ accumuloClient.tableOperations().create(tablename);
+ result = true;
+ } catch (TableExistsException e) {
+ result = false;
+ }
+ return result;
+ });
+ futureList.add(future);
+ }
+
+ Wait.waitFor(() -> numTasksRunning.get() == numTasks);
+
+ startSignal.countDown();
+
+ int taskSucceeded = 0;
+ int taskFailed = 0;
+ for (Future<Boolean> result : futureList) {
+ if (result.get() == true) {
+ taskSucceeded++;
+ } else {
+ taskFailed++;
+ }
+ }
+
+ assertEquals(1, taskSucceeded);
+ assertEquals(9, taskFailed);
+ }
+
+ assertEquals(30, accumuloClient.tableOperations().list().size() -
initialTableSize);
+
+ pool.shutdown();
+ }
+
@Test
public void createTableWithSystemUser() throws TableExistsException,
AccumuloException,
AccumuloSecurityException, TableNotFoundException {