This is an automated email from the ASF dual-hosted git repository.
dataroaring pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push:
new c04a8da75bc branch-3.0: [fix](vault) Fix bugs about altering storage
vault name #45685 (#45963)
c04a8da75bc is described below
commit c04a8da75bcb39c387a9ac8465813bdfa5260a0b
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Dec 26 09:26:40 2024 +0800
branch-3.0: [fix](vault) Fix bugs about altering storage vault name #45685
(#45963)
Cherry-picked from #45685
Co-authored-by: Lei Zhang <[email protected]>
---
cloud/src/meta-service/meta_service_resource.cpp | 55 +++--
cloud/test/meta_service_test.cpp | 39 ++++
.../main/java/org/apache/doris/catalog/Env.java | 5 +-
.../java/org/apache/doris/catalog/OlapTable.java | 20 +-
.../org/apache/doris/catalog/StorageVault.java | 3 +-
.../org/apache/doris/catalog/StorageVaultMgr.java | 52 ++++-
.../org/apache/doris/catalog/TableProperty.java | 4 -
.../cloud/datasource/CloudInternalCatalog.java | 36 +---
.../apache/doris/datasource/InternalCatalog.java | 1 -
.../plans/commands/AlterStorageVaultCommand.java | 10 +
.../org/apache/doris/regression/suite/Suite.groovy | 4 +-
.../vault_p0/alter/test_alter_vault_name.groovy | 232 +++++++++++++++++++++
12 files changed, 386 insertions(+), 75 deletions(-)
diff --git a/cloud/src/meta-service/meta_service_resource.cpp
b/cloud/src/meta-service/meta_service_resource.cpp
index 4fa8cc5a132..d873dec7b21 100644
--- a/cloud/src/meta-service/meta_service_resource.cpp
+++ b/cloud/src/meta-service/meta_service_resource.cpp
@@ -523,9 +523,18 @@ static void set_default_vault_log_helper(const
InstanceInfoPB& instance,
LOG(INFO) << vault_msg;
}
-static int alter_hdfs_storage_vault(InstanceInfoPB& instance,
std::unique_ptr<Transaction> txn,
+static bool vault_exist(const InstanceInfoPB& instance, const std::string&
new_vault_name) {
+ for (auto& name : instance.storage_vault_names()) {
+ if (new_vault_name == name) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static int alter_hdfs_storage_vault(InstanceInfoPB& instance,
std::unique_ptr<Transaction>& txn,
const StorageVaultPB& vault,
MetaServiceCode& code,
- std::string& msg) {
+ std::string& msg,
AlterObjStoreInfoResponse* response) {
if (!vault.has_hdfs_info()) {
code = MetaServiceCode::INVALID_ARGUMENT;
std::stringstream ss;
@@ -591,6 +600,13 @@ static int alter_hdfs_storage_vault(InstanceInfoPB&
instance, std::unique_ptr<Tr
msg = ss.str();
return -1;
}
+
+ if (vault_exist(instance, vault.alter_name())) {
+ code = MetaServiceCode::ALREADY_EXISTED;
+ msg = fmt::format("vault_name={} already existed",
vault.alter_name());
+ return -1;
+ }
+
new_vault.set_name(vault.alter_name());
*name_itr = vault.alter_name();
}
@@ -623,19 +639,15 @@ static int alter_hdfs_storage_vault(InstanceInfoPB&
instance, std::unique_ptr<Tr
txn->put(vault_key, val);
LOG(INFO) << "put vault_id=" << vault_id << ", vault_key=" <<
hex(vault_key)
<< ", origin vault=" << origin_vault_info << ", new_vault=" <<
new_vault_info;
- err = txn->commit();
- if (err != TxnErrorCode::TXN_OK) {
- code = cast_as<ErrCategory::COMMIT>(err);
- msg = fmt::format("failed to commit kv txn, err={}", err);
- LOG(WARNING) << msg;
- }
+ DCHECK_EQ(new_vault.id(), vault_id);
+ response->set_storage_vault_id(new_vault.id());
return 0;
}
-static int alter_s3_storage_vault(InstanceInfoPB& instance,
std::unique_ptr<Transaction> txn,
+static int alter_s3_storage_vault(InstanceInfoPB& instance,
std::unique_ptr<Transaction>& txn,
const StorageVaultPB& vault,
MetaServiceCode& code,
- std::string& msg) {
+ std::string& msg, AlterObjStoreInfoResponse*
response) {
if (!vault.has_obj_info()) {
code = MetaServiceCode::INVALID_ARGUMENT;
std::stringstream ss;
@@ -708,6 +720,13 @@ static int alter_s3_storage_vault(InstanceInfoPB&
instance, std::unique_ptr<Tran
msg = ss.str();
return -1;
}
+
+ if (vault_exist(instance, vault.alter_name())) {
+ code = MetaServiceCode::ALREADY_EXISTED;
+ msg = fmt::format("vault_name={} already existed",
vault.alter_name());
+ return -1;
+ }
+
new_vault.set_name(vault.alter_name());
*name_itr = vault.alter_name();
}
@@ -747,13 +766,9 @@ static int alter_s3_storage_vault(InstanceInfoPB&
instance, std::unique_ptr<Tran
txn->put(vault_key, val);
LOG(INFO) << "put vault_id=" << vault_id << ", vault_key=" <<
hex(vault_key)
<< ", origin vault=" << origin_vault_info << ", new vault=" <<
new_vault_info;
- err = txn->commit();
- if (err != TxnErrorCode::TXN_OK) {
- code = cast_as<ErrCategory::COMMIT>(err);
- msg = fmt::format("failed to commit kv txn, err={}", err);
- LOG(WARNING) << msg;
- }
+ DCHECK_EQ(new_vault.id(), vault_id);
+ response->set_storage_vault_id(new_vault.id());
return 0;
}
@@ -1100,12 +1115,12 @@ void
MetaServiceImpl::alter_storage_vault(google::protobuf::RpcController* contr
break;
}
case AlterObjStoreInfoRequest::ALTER_S3_VAULT: {
- alter_s3_storage_vault(instance, std::move(txn), request->vault(),
code, msg);
- return;
+ alter_s3_storage_vault(instance, txn, request->vault(), code, msg,
response);
+ break;
}
case AlterObjStoreInfoRequest::ALTER_HDFS_VAULT: {
- alter_hdfs_storage_vault(instance, std::move(txn), request->vault(),
code, msg);
- return;
+ alter_hdfs_storage_vault(instance, txn, request->vault(), code, msg,
response);
+ break;
}
case AlterObjStoreInfoRequest::DROP_S3_VAULT:
[[fallthrough]];
diff --git a/cloud/test/meta_service_test.cpp b/cloud/test/meta_service_test.cpp
index 3bf20facca1..777c7419b70 100644
--- a/cloud/test/meta_service_test.cpp
+++ b/cloud/test/meta_service_test.cpp
@@ -637,6 +637,25 @@ TEST(MetaServiceTest, AlterS3StorageVaultTest) {
meta_service->alter_storage_vault(
reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
&req, &res, nullptr);
ASSERT_EQ(res.status().code(), MetaServiceCode::OK) <<
res.status().msg();
+
+ {
+ AlterObjStoreInfoRequest req;
+ req.set_cloud_unique_id("test_cloud_unique_id");
+ req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
+ StorageVaultPB vault;
+ vault.set_alter_name(new_vault_name);
+ ObjectStoreInfoPB obj;
+ obj_info.set_ak("new_ak");
+ obj_info.set_sk("new_sk");
+ vault.mutable_obj_info()->MergeFrom(obj);
+ vault.set_name(new_vault_name);
+ req.mutable_vault()->CopyFrom(vault);
+ meta_service->alter_storage_vault(
+
reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
+ nullptr);
+ ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED)
<< res.status().msg();
+ }
+
InstanceInfoPB instance;
get_test_instance(instance);
@@ -726,6 +745,7 @@ TEST(MetaServiceTest, AlterHdfsStorageVaultTest) {
meta_service->alter_storage_vault(
reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
&req, &res, nullptr);
ASSERT_EQ(res.status().code(), MetaServiceCode::OK) <<
res.status().msg();
+
InstanceInfoPB instance;
get_test_instance(instance);
@@ -793,6 +813,25 @@ TEST(MetaServiceTest, AlterHdfsStorageVaultTest) {
meta_service->alter_storage_vault(
reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
&req, &res, nullptr);
ASSERT_EQ(res.status().code(), MetaServiceCode::OK) <<
res.status().msg();
+
+ {
+ AlterObjStoreInfoRequest req;
+ req.set_cloud_unique_id("test_cloud_unique_id");
+ req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
+ StorageVaultPB vault;
+
vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
+ vault.set_name(new_vault_name);
+ vault.set_alter_name(new_vault_name);
+ req.mutable_vault()->CopyFrom(vault);
+
+ brpc::Controller cntl;
+ AlterObjStoreInfoResponse res;
+ meta_service->alter_storage_vault(
+
reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
+ nullptr);
+ ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED)
<< res.status().msg();
+ }
+
InstanceInfoPB instance;
get_test_instance(instance);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index 91a45bb71b0..f703fa0926a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -3693,7 +3693,10 @@ public class Env {
}
// Storage Vault
- if (!olapTable.getStorageVaultName().isEmpty()) {
+ if (!Strings.isNullOrEmpty(olapTable.getStorageVaultId())) {
+ sb.append(",\n\"").append(PropertyAnalyzer
+ .PROPERTIES_STORAGE_VAULT_ID).append("\" = \"");
+ sb.append(olapTable.getStorageVaultId()).append("\"");
sb.append(",\n\"").append(PropertyAnalyzer
.PROPERTIES_STORAGE_VAULT_NAME).append("\" = \"");
sb.append(olapTable.getStorageVaultName()).append("\"");
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index ef20b93053c..205702db632 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -263,22 +263,18 @@ public class OlapTable extends Table implements
MTMVRelatedTableIf, GsonPostProc
String.valueOf(isBeingSynced));
}
- public void setStorageVaultName(String storageVaultName) throws
DdlException {
- if (storageVaultName == null || storageVaultName.isEmpty()) {
- return;
- }
- getOrCreatTableProperty().setStorageVaultName(storageVaultName);
- }
-
public String getStorageVaultName() {
- return getOrCreatTableProperty().getStorageVaultName();
+ if (Strings.isNullOrEmpty(getStorageVaultId())) {
+ return "";
+ }
+ return
Env.getCurrentEnv().getStorageVaultMgr().getVaultNameById(getStorageVaultId());
}
- public void setStorageVaultId(String setStorageVaultId) throws
DdlException {
- if (setStorageVaultId == null || setStorageVaultId.isEmpty()) {
- throw new DdlException("Invalid Storage Vault, please set one
useful storage vault");
+ public void setStorageVaultId(String storageVaultId) throws DdlException {
+ if (Strings.isNullOrEmpty(storageVaultId)) {
+ throw new DdlException("Invalid storage vault id, please set an
available storage vault");
}
- getOrCreatTableProperty().setStorageVaultId(setStorageVaultId);
+ getOrCreatTableProperty().setStorageVaultId(storageVaultId);
}
public String getStorageVaultId() {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
index 9d45ce7bdd8..c1a22430d50 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVault.java
@@ -45,6 +45,8 @@ public abstract class StorageVault {
public static final String LOWER_CASE_META_NAMES = "lower_case_meta_names";
public static final String META_NAMES_MAPPING = "meta_names_mapping";
+ public static final String VAULT_NAME = "VAULT_NAME";
+
public enum StorageVaultType {
UNKNOWN,
S3,
@@ -60,7 +62,6 @@ public abstract class StorageVault {
}
}
- protected static final String VAULT_NAME = "VAULT_NAME";
protected String name;
protected StorageVaultType type;
protected String id;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
index cd97c92fb72..e48adad47ff 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/StorageVaultMgr.java
@@ -36,6 +36,8 @@ import org.apache.doris.system.SystemInfoService;
import org.apache.doris.thrift.TNetworkAddress;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -82,12 +84,42 @@ public class StorageVaultMgr {
rwLock.writeLock().unlock();
}
- public String getVaultIdByName(String name) {
- String vaultId;
- rwLock.readLock().lock();
- vaultId = vaultNameToVaultId.getOrDefault(name, "");
- rwLock.readLock().unlock();
- return vaultId;
+ public String getVaultIdByName(String vaultName) {
+ try {
+ rwLock.readLock().lock();
+ return vaultNameToVaultId.getOrDefault(vaultName, "");
+ } finally {
+ rwLock.readLock().unlock();
+ }
+ }
+
+ public String getVaultNameById(String vaultId) {
+ try {
+ rwLock.readLock().lock();
+ for (Map.Entry<String, String> entry :
vaultNameToVaultId.entrySet()) {
+ if (entry.getValue().equals(vaultId)) {
+ return entry.getKey();
+ }
+ }
+ return "";
+ } finally {
+ rwLock.readLock().unlock();
+ }
+ }
+
+ private void updateVaultNameToIdCache(String oldVaultName, String
newVaultName, String vaultId) {
+ try {
+ rwLock.writeLock().lock();
+ String cachedVaultId = vaultNameToVaultId.get(oldVaultName);
+ vaultNameToVaultId.remove(oldVaultName);
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(cachedVaultId),
cachedVaultId,
+ "Cached vault id is null or empty");
+ Preconditions.checkArgument(cachedVaultId.equals(vaultId),
+ "Cached vault id not equal to remote storage." +
cachedVaultId + " - " + vaultId);
+ vaultNameToVaultId.put(newVaultName, vaultId);
+ } finally {
+ rwLock.writeLock().unlock();
+ }
}
private Cloud.StorageVaultPB.Builder buildAlterS3VaultRequest(Map<String,
String> properties, String name)
@@ -168,8 +200,12 @@ public class StorageVaultMgr {
LOG.warn("failed to alter storage vault response: {} ",
response);
throw new DdlException(response.getStatus().getMsg());
}
- LOG.info("Succeed to alter storage vault {}, id {}, origin default
vault replaced {}",
- name, response.getStorageVaultId(),
response.getDefaultStorageVaultReplaced());
+
+ if (request.hasVault() && request.getVault().hasAlterName()) {
+ updateVaultNameToIdCache(name,
request.getVault().getAlterName(), response.getStorageVaultId());
+ LOG.info("Succeed to alter storage vault, old name:{} new
name: {} id:{}", name,
+ request.getVault().getAlterName(),
response.getStorageVaultId());
+ }
// Make BE eagerly fetch the storage vault info from Meta Service
ALTER_BE_SYNC_THREAD_POOL.execute(() -> alterSyncVaultTask());
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
index 3229d5dad72..a52477e66eb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TableProperty.java
@@ -770,10 +770,6 @@ public class TableProperty implements Writable,
GsonPostProcessable {
return
properties.getOrDefault(PropertyAnalyzer.PROPERTIES_STORAGE_VAULT_NAME, "");
}
- public void setStorageVaultName(String storageVaultName) {
- properties.put(PropertyAnalyzer.PROPERTIES_STORAGE_VAULT_NAME,
storageVaultName);
- }
-
public String getPropertiesString() throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
try {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
index c20d971cc30..8fc912d57df 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/cloud/datasource/CloudInternalCatalog.java
@@ -55,7 +55,6 @@ import org.apache.doris.cluster.ClusterNamespace;
import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.MetaNotFoundException;
-import org.apache.doris.common.Pair;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.proto.OlapCommon;
import org.apache.doris.proto.OlapFile;
@@ -105,6 +104,12 @@ public class CloudInternalCatalog extends InternalCatalog {
throws DdlException {
// create base index first.
Preconditions.checkArgument(tbl.getBaseIndexId() != -1);
+
+ if (((CloudEnv) Env.getCurrentEnv()).getEnableStorageVault()) {
+
Preconditions.checkArgument(!Strings.isNullOrEmpty(tbl.getStorageVaultId()),
+ "Storage vault id is null or empty");
+ }
+
MaterializedIndex baseIndex = new
MaterializedIndex(tbl.getBaseIndexId(), IndexState.NORMAL);
LOG.info("begin create cloud partition");
@@ -128,9 +133,6 @@ public class CloudInternalCatalog extends InternalCatalog {
long version = partition.getVisibleVersion();
- final String storageVaultName = tbl.getStorageVaultName();
- boolean storageVaultIdSet = tbl.getStorageVaultId().isEmpty();
-
// short totalReplicaNum = replicaAlloc.getTotalReplicaNum();
for (Map.Entry<Long, MaterializedIndex> entry : indexMap.entrySet()) {
long indexId = entry.getKey();
@@ -177,29 +179,11 @@ public class CloudInternalCatalog extends InternalCatalog
{
tbl.variantEnableFlattenNested());
requestBuilder.addTabletMetas(builder);
}
- if (!storageVaultIdSet && ((CloudEnv)
Env.getCurrentEnv()).getEnableStorageVault()) {
- requestBuilder.setStorageVaultName(storageVaultName);
- }
requestBuilder.setDbId(dbId);
-
- LOG.info("create tablets, dbId: {}, tableId: {}, tableName: {},
partitionId: {}, partitionName: {}, "
- + "indexId: {}, vault name: {}",
- dbId, tbl.getId(), tbl.getName(), partitionId,
partitionName, indexId, storageVaultName);
- Cloud.CreateTabletsResponse resp =
sendCreateTabletsRpc(requestBuilder);
- // If the resp has no vault id set, it means the MS is running
with enable_storage_vault false
- if (resp.hasStorageVaultId() && !storageVaultIdSet) {
- tbl.setStorageVaultId(resp.getStorageVaultId());
- storageVaultIdSet = true;
- if (storageVaultName.isEmpty()) {
- // If user doesn't specify the vault name for this table,
we should set it
- // to make the show create table stmt return correct stmt
- // TODO(ByteYue): setDefaultStorageVault for vaultMgr
might override user's
- // defualt vault, maybe we should set it using show
default storage vault stmt
- tbl.setStorageVaultName(resp.getStorageVaultName());
-
Env.getCurrentEnv().getStorageVaultMgr().setDefaultStorageVault(
- Pair.of(resp.getStorageVaultName(),
resp.getStorageVaultId()));
- }
- }
+ LOG.info("create tablets dbId: {} tableId: {} tableName: {}
partitionId: {} partitionName: {} "
+ + "indexId: {} vaultId: {}",
+ dbId, tbl.getId(), tbl.getName(), partitionId,
partitionName, indexId, tbl.getStorageVaultId());
+ sendCreateTabletsRpc(requestBuilder);
if (index.getId() != tbl.getBaseIndexId()) {
// add rollup index to partition
partition.createRollupIndex(index);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index aa14905c705..c5b2243aef2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -2746,7 +2746,6 @@ public class InternalCatalog implements
CatalogIf<Database> {
+ "' for storage vault '" + storageVaultName + "'");
}
- olapTable.setStorageVaultName(storageVaultName);
storageVaultId =
env.getStorageVaultMgr().getVaultIdByName(storageVaultName);
if (Strings.isNullOrEmpty(storageVaultId)) {
throw new DdlException("Storage vault '" + storageVaultName +
"' does not exist. "
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
index cbdc5765839..0766d236439 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/AlterStorageVaultCommand.java
@@ -21,11 +21,14 @@ import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.StorageVault;
import org.apache.doris.catalog.StorageVault.StorageVaultType;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.FeNameFormat;
import org.apache.doris.nereids.trees.plans.PlanType;
import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.StmtExecutor;
+import com.google.common.base.Preconditions;
+
import java.util.Map;
/**
@@ -48,6 +51,13 @@ public class AlterStorageVaultCommand extends Command
implements ForwardWithSync
if (vaultType == StorageVault.StorageVaultType.UNKNOWN) {
throw new AnalysisException("Unsupported Storage Vault type: " +
type);
}
+
+ FeNameFormat.checkStorageVaultName(name);
+ if (properties.containsKey(StorageVault.VAULT_NAME)) {
+ String newName = properties.get(StorageVault.VAULT_NAME);
+ FeNameFormat.checkStorageVaultName(newName);
+ Preconditions.checkArgument(!name.equalsIgnoreCase(newName),
"vault name no change");
+ }
Env.getCurrentEnv().getStorageVaultMgr().alterStorageVault(vaultType,
properties, name);
}
diff --git
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
index ee9a87251fd..a7b8421635e 100644
---
a/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
+++
b/regression-test/framework/src/main/groovy/org/apache/doris/regression/suite/Suite.groovy
@@ -783,11 +783,11 @@ class Suite implements GroovyInterceptable {
return randomBoolean ? "true" : "false"
}
- void expectExceptionLike(Closure userFunction, String errorMessage = null)
{
+ void expectExceptionLike(Closure userFunction, String errMsg = null) {
try {
userFunction()
} catch (Exception e) {
- if (!e.getMessage().contains(errorMessage)) {
+ if (!Strings.isNullOrEmpty(errMsg) &&
!e.getMessage().contains(errMsg)) {
throw e
}
}
diff --git a/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy
b/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy
new file mode 100644
index 00000000000..4592e72292a
--- /dev/null
+++ b/regression-test/suites/vault_p0/alter/test_alter_vault_name.groovy
@@ -0,0 +1,232 @@
+// 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.
+
+suite("test_alter_vault_name", "nonConcurrent") {
+ def suiteName = name;
+ if (!isCloudMode()) {
+ logger.info("skip ${suiteName} case, because not cloud mode")
+ return
+ }
+
+ if (!enableStoragevault()) {
+ logger.info("skip ${suiteName} case, because storage vault not
enabled")
+ return
+ }
+
+ def vaultName = UUID.randomUUID().toString().replace("-", "")
+ def hdfsVaultName = "hdfs_" + vaultName
+ sql """
+ CREATE STORAGE VAULT ${hdfsVaultName}
+ PROPERTIES (
+ "type" = "HDFS",
+ "fs.defaultFS" = "${getHdfsFs()}",
+ "path_prefix" = "${hdfsVaultName}",
+ "hadoop.username" = "${getHdfsUser()}"
+ );
+ """
+
+ def s3VaultName = "s3_" + vaultName
+ sql """
+ CREATE STORAGE VAULT ${s3VaultName}
+ PROPERTIES (
+ "type" = "S3",
+ "s3.endpoint" = "${getS3Endpoint()}",
+ "s3.region" = "${getS3Region()}",
+ "s3.access_key" = "${getS3AK()}",
+ "s3.secret_key" = "${getS3SK()}",
+ "s3.root.path" = "${s3VaultName}",
+ "s3.bucket" = "${getS3BucketName()}",
+ "s3.external_endpoint" = "",
+ "provider" = "${getS3Provider()}",
+ "use_path_style" = "false"
+ );
+ """
+
+ // case1
+ expectExceptionLike({
+ sql """
+ ALTER STORAGE VAULT ${hdfsVaultName}
+ PROPERTIES (
+ "type" = "hdfs",
+ "VAULT_NAME" = "${hdfsVaultName}"
+ );
+ """
+ }, "vault name no change")
+
+ // case2
+ expectExceptionLike({
+ sql """
+ ALTER STORAGE VAULT ${hdfsVaultName}
+ PROPERTIES (
+ "type" = "hdfs",
+ "VAULT_NAME" = "${s3VaultName}"
+ );
+ """
+ }, "already existed")
+
+ // case3
+ expectExceptionLike({
+ sql """
+ ALTER STORAGE VAULT ${s3VaultName}
+ PROPERTIES (
+ "type" = "s3",
+ "VAULT_NAME" = "${s3VaultName}"
+ );
+ """
+ }, "vault name no change")
+
+ // case4
+ expectExceptionLike({
+ sql """
+ ALTER STORAGE VAULT ${s3VaultName}
+ PROPERTIES (
+ "type" = "s3",
+ "VAULT_NAME" = "${hdfsVaultName}"
+ );
+ """
+ }, "already existed")
+
+ // case5
+ sql """
+ CREATE TABLE ${hdfsVaultName} (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${hdfsVaultName}
+ )
+ """
+ sql """ insert into ${hdfsVaultName} values(1, 1); """
+ sql """ sync;"""
+ def result = sql """ select * from ${hdfsVaultName}; """
+ assertEquals(result.size(), 1);
+
+ sql """
+ ALTER STORAGE VAULT ${hdfsVaultName}
+ PROPERTIES (
+ "type" = "hdfs",
+ "VAULT_NAME" = "${hdfsVaultName}_new"
+ );
+ """
+ sql """ insert into ${hdfsVaultName} values(2, 2); """
+ sql """ sync;"""
+ result = sql """ select * from ${hdfsVaultName}; """
+ assertEquals(result.size(), 2);
+
+ // case6
+ expectExceptionLike({
+ sql """
+ CREATE TABLE ${hdfsVaultName}_new (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${hdfsVaultName}
+ )
+ """
+ }, "does not exis")
+
+ // case7
+ sql """
+ CREATE TABLE ${hdfsVaultName}_new (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${hdfsVaultName}_new
+ )
+ """
+
+ sql """ insert into ${hdfsVaultName}_new values(1, 1); """
+ sql """ sync;"""
+ result = sql """ select * from ${hdfsVaultName}_new; """
+ assertEquals(result.size(), 1);
+
+ // case8
+ sql """
+ CREATE TABLE ${s3VaultName} (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${s3VaultName}
+ )
+ """
+ sql """ insert into ${s3VaultName} values(1, 1); """
+ sql """ sync;"""
+ result = sql """ select * from ${s3VaultName}; """
+ assertEquals(result.size(), 1);
+
+ sql """
+ ALTER STORAGE VAULT ${s3VaultName}
+ PROPERTIES (
+ "type" = "s3",
+ "VAULT_NAME" = "${s3VaultName}_new"
+ );
+ """
+ sql """ insert into ${s3VaultName} values(2, 2); """
+ sql """ sync;"""
+ result = sql """ select * from ${s3VaultName}; """
+ assertEquals(result.size(), 2);
+
+ // case9
+ expectExceptionLike({
+ sql """
+ CREATE TABLE ${s3VaultName}_new (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${s3VaultName}
+ )
+ """
+ }, "does not exis")
+
+ // case10
+ sql """
+ CREATE TABLE ${s3VaultName}_new (
+ C_CUSTKEY INTEGER NOT NULL,
+ C_NAME INTEGER NOT NULL
+ )
+ DUPLICATE KEY(C_CUSTKEY, C_NAME)
+ DISTRIBUTED BY HASH(C_CUSTKEY) BUCKETS 1
+ PROPERTIES (
+ "replication_num" = "1",
+ "storage_vault_name" = ${s3VaultName}_new
+ )
+ """
+
+ sql """ insert into ${s3VaultName}_new values(1, 1); """
+ sql """ sync;"""
+ result = sql """ select * from ${s3VaultName}_new; """
+ assertEquals(result.size(), 1);
+}
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]