You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by qi...@apache.org on 2022/05/03 07:56:10 UTC
[iotdb] branch master updated: Fix concurrent failure of testInsertMultiTabletPlanParallel (#5767)
This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new f40ae52eb5 Fix concurrent failure of testInsertMultiTabletPlanParallel (#5767)
f40ae52eb5 is described below
commit f40ae52eb56f5399db2afd312eed8d6c6e368c22
Author: Marcos_Zyk <38...@users.noreply.github.com>
AuthorDate: Tue May 3 15:56:04 2022 +0800
Fix concurrent failure of testInsertMultiTabletPlanParallel (#5767)
---
.../iotdb/db/localconfignode/LocalConfigNode.java | 25 +++++++++++++++++++++-
.../iotdb/db/metadata/LocalSchemaProcessor.java | 16 ++++++--------
.../db/metadata/schemaregion/SchemaEngine.java | 16 +++++++++-----
3 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
index 96b0fedb11..de1957f472 100644
--- a/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/localconfignode/LocalConfigNode.java
@@ -539,7 +539,30 @@ public class LocalConfigNode {
*/
public SchemaRegionId getBelongedSchemaRegionId(PartialPath path) throws MetadataException {
PartialPath storageGroup = storageGroupSchemaManager.getBelongedStorageGroup(path);
- return schemaPartitionTable.getSchemaRegionId(storageGroup, path);
+ SchemaRegionId schemaRegionId = schemaPartitionTable.getSchemaRegionId(storageGroup, path);
+ // Since the creation of storageGroup, schemaRegionId and schemaRegion is not atomic or locked,
+ // any access concurrent with this creation may get null.
+ // Thread A: create sg, allocate schemaRegionId, create schemaRegion
+ // Thread B: access sg, access partitionTable to get schemaRegionId, access schemaEngine to get
+ // schemaRegion
+ // When A and B are running concurrently, B may get null while getting schemaRegionId or
+ // schemaRegion. This means B must run after A ends.
+ // To avoid this exception, please invoke getBelongedSchemaRegionIdWithAutoCreate according to
+ // the scenario.
+ if (schemaRegionId == null) {
+ throw new MetadataException(
+ String.format(
+ "Storage group %s has not been prepared well. Schema region for %s has not been allocated or is not initialized.",
+ storageGroup, path));
+ }
+ ISchemaRegion schemaRegion = schemaEngine.getSchemaRegion(schemaRegionId);
+ if (schemaRegion == null) {
+ throw new MetadataException(
+ String.format(
+ "Storage group [%s] has not been prepared well. Schema region [%s] is not initialized.",
+ storageGroup, schemaRegionId));
+ }
+ return schemaRegionId;
}
// This interface involves storage group and schema region auto creation
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/LocalSchemaProcessor.java b/server/src/main/java/org/apache/iotdb/db/metadata/LocalSchemaProcessor.java
index a34b71633e..26f5e3e5ec 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/LocalSchemaProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/LocalSchemaProcessor.java
@@ -1259,16 +1259,14 @@ public class LocalSchemaProcessor {
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
public IMNode getSeriesSchemasAndReadLockDevice(InsertPlan plan)
throws MetadataException, IOException {
- try {
- return getBelongedSchemaRegion(plan.getDevicePath()).getSeriesSchemasAndReadLockDevice(plan);
- } catch (StorageGroupNotSetException e) {
- if (config.isAutoCreateSchemaEnabled()) {
- return getBelongedSchemaRegionWithAutoCreate(plan.getDevicePath())
- .getSeriesSchemasAndReadLockDevice(plan);
- } else {
- throw e;
- }
+ ISchemaRegion schemaRegion;
+ if (config.isAutoCreateSchemaEnabled()) {
+ schemaRegion = getBelongedSchemaRegionWithAutoCreate(plan.getDevicePath());
+ } else {
+ schemaRegion = getBelongedSchemaRegion(plan.getDevicePath());
}
+
+ return schemaRegion.getSeriesSchemasAndReadLockDevice(plan);
}
// endregion
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaEngine.java b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaEngine.java
index fce9c38aeb..22b09f8a00 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaEngine.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/schemaregion/SchemaEngine.java
@@ -163,11 +163,17 @@ public class SchemaEngine {
PartialPath storageGroup, SchemaRegionId schemaRegionId) throws MetadataException {
ISchemaRegion schemaRegion = schemaRegionMap.get(schemaRegionId);
if (schemaRegion != null) {
- throw new MetadataException(
- String.format(
- "SchemaRegion [%s] is duplicated between [%s] and [%s], "
- + "and the former one has been recovered.",
- schemaRegionId, schemaRegion.getStorageGroupFullPath(), storageGroup.getFullPath()));
+ if (schemaRegion.getStorageGroupFullPath().equals(storageGroup.getFullPath())) {
+ return;
+ } else {
+ throw new MetadataException(
+ String.format(
+ "SchemaRegion [%s] is duplicated between [%s] and [%s], "
+ + "and the former one has been recovered.",
+ schemaRegionId,
+ schemaRegion.getStorageGroupFullPath(),
+ storageGroup.getFullPath()));
+ }
}
schemaRegionMap.put(
schemaRegionId, createSchemaRegionWithoutExistenceCheck(storageGroup, schemaRegionId));