This is an automated email from the ASF dual-hosted git repository.
jt2594838 pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/dev/1.3 by this push:
new 4bc6ba6ff2b Fix stale space quota usage update on DataNode (#18668)
4bc6ba6ff2b is described below
commit 4bc6ba6ff2b9e24cdc5565e176ea19bf47b9c21f
Author: Caideyipi <[email protected]>
AuthorDate: Thu Sep 17 18:40:06 2026 +0800
Fix stale space quota usage update on DataNode (#18668)
---
.../rescon/quotas/DataNodeSpaceQuotaManager.java | 26 ++++++-----
.../quotas/DataNodeSpaceQuotaManagerTest.java | 50 ++++++++++++++++++++++
2 files changed, 65 insertions(+), 11 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManager.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManager.java
index c448febf3b7..ea6d576ac3d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManager.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManager.java
@@ -31,29 +31,31 @@ import org.apache.iotdb.rpc.TSStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class DataNodeSpaceQuotaManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(DataNodeSpaceQuotaManager.class);
- private Map<String, TSpaceQuota> spaceQuotaLimit;
- private Map<String, TSpaceQuota> spaceQuotaUsage;
+ private ConcurrentMap<String, TSpaceQuota> spaceQuotaLimit;
+ private ConcurrentMap<String, TSpaceQuota> spaceQuotaUsage;
private DataNodeSizeStore dataNodeSizeStore;
public DataNodeSpaceQuotaManager() {
- spaceQuotaLimit = new HashMap<>();
- spaceQuotaUsage = new HashMap<>();
+ spaceQuotaLimit = new ConcurrentHashMap<>();
+ spaceQuotaUsage = new ConcurrentHashMap<>();
dataNodeSizeStore = new DataNodeSizeStore();
recover();
}
public DataNodeSpaceQuotaManager(
Map<String, TSpaceQuota> spaceQuotaLimit, Map<String, TSpaceQuota>
spaceQuotaUsage) {
- this.spaceQuotaLimit = spaceQuotaLimit;
- this.spaceQuotaUsage = spaceQuotaUsage;
+ this.spaceQuotaLimit = new ConcurrentHashMap<>(spaceQuotaLimit);
+ this.spaceQuotaUsage = new ConcurrentHashMap<>(spaceQuotaUsage);
}
/** SingleTon */
@@ -69,8 +71,8 @@ public class DataNodeSpaceQuotaManager {
public TSStatus setSpaceQuota(TSetSpaceQuotaReq req) {
for (String database : req.getDatabase()) {
- spaceQuotaLimit.put(database, req.getSpaceLimit());
spaceQuotaUsage.put(database, new TSpaceQuota());
+ spaceQuotaLimit.put(database, req.getSpaceLimit());
}
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
}
@@ -81,8 +83,8 @@ public class DataNodeSpaceQuotaManager {
if (spaceQuota.getStatus().getCode() ==
TSStatusCode.SUCCESS_STATUS.getStatusCode()
&& spaceQuota.getSpaceQuota() != null) {
for (String database : spaceQuota.getSpaceQuota().keySet()) {
- spaceQuotaLimit.put(database,
spaceQuota.getSpaceQuota().get(database));
spaceQuotaUsage.put(database, new TSpaceQuota());
+ spaceQuotaLimit.put(database,
spaceQuota.getSpaceQuota().get(database));
}
}
LOGGER.info("Space quota limit restored succeeded. " +
spaceQuotaLimit.toString());
@@ -107,7 +109,9 @@ public class DataNodeSpaceQuotaManager {
}
public void updateSpaceQuotaUsage(Map<String, TSpaceQuota> spaceQuotaUsage) {
- this.spaceQuotaUsage = spaceQuotaUsage;
+ if (Objects.nonNull(spaceQuotaUsage)) {
+ this.spaceQuotaUsage.putAll(spaceQuotaUsage);
+ }
}
public boolean checkTimeSeriesNum(String database) {
@@ -148,6 +152,6 @@ public class DataNodeSpaceQuotaManager {
}
public void setSpaceQuotaLimit(Map<String, TSpaceQuota> spaceQuotaLimit) {
- this.spaceQuotaLimit = spaceQuotaLimit;
+ this.spaceQuotaLimit = new ConcurrentHashMap<>(spaceQuotaLimit);
}
}
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManagerTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManagerTest.java
new file mode 100644
index 00000000000..5965107e064
--- /dev/null
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/quotas/DataNodeSpaceQuotaManagerTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.db.storageengine.rescon.quotas;
+
+import org.apache.iotdb.common.rpc.thrift.TSetSpaceQuotaReq;
+import org.apache.iotdb.common.rpc.thrift.TSpaceQuota;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+public class DataNodeSpaceQuotaManagerTest {
+
+ @Test
+ public void testSpaceQuotaUsageUpdatePreservesNewDatabase() {
+ final DataNodeSpaceQuotaManager quotaManager =
+ new DataNodeSpaceQuotaManager(new HashMap<>(), new HashMap<>());
+ final TSpaceQuota spaceQuota = new TSpaceQuota();
+ spaceQuota.setDeviceNum(2);
+ spaceQuota.setTimeserieNum(0);
+ spaceQuota.setDiskSize(0);
+ final TSetSpaceQuotaReq request = new TSetSpaceQuotaReq();
+ request.setDatabase(Collections.singletonList("root.sg1"));
+ request.setSpaceLimit(spaceQuota);
+
+ quotaManager.setSpaceQuota(request);
+ quotaManager.updateSpaceQuotaUsage(Collections.singletonMap("root.sg0",
new TSpaceQuota()));
+
+ Assert.assertTrue(quotaManager.checkDeviceLimit("sg1"));
+ }
+}