diff options
author | Daniil Demin <deminds@ydb.tech> | 2025-02-21 19:19:44 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-21 19:19:44 +0300 |
commit | d1adfd1b1ff14f23e1d26ee6a4f31d5a07a12c2b (patch) | |
tree | 5335b30bd19c9a13956f5f62d9dd4bf5b922e9d7 | |
parent | cb5a9d0f7f95167f4e407a02ad88504f5f3f7355 (diff) | |
download | ydb-d1adfd1b1ff14f23e1d26ee6a4f31d5a07a12c2b.tar.gz |
Ingore basic scheme limits for internal operations (#14813)
7 files changed, 154 insertions, 17 deletions
diff --git a/ydb/core/protos/index_builder.proto b/ydb/core/protos/index_builder.proto index c148577dde..c14c54e347 100644 --- a/ydb/core/protos/index_builder.proto +++ b/ydb/core/protos/index_builder.proto @@ -49,6 +49,8 @@ message TEvCreateRequest { optional uint64 TxId = 2; optional string DatabaseName = 3; optional TIndexBuildSettings Settings = 4; + // Internal flag is true for system-generated operations and is false for those initiated directly by the user. + optional bool Internal = 5 [default = false]; } message TEvCreateResponse { diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp index 2024ec1427..31f792184a 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp @@ -24,6 +24,7 @@ TVector<ISubOperation::TPtr> CreateBuildColumn(TOperationId opId, const TTxTrans { auto outTx = TransactionTemplate(table.Parent().PathString(), NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexMainTable); *outTx.MutableLockGuard() = tx.GetLockGuard(); + outTx.SetInternal(tx.GetInternal()); auto& snapshot = *outTx.MutableInitiateBuildIndexMainTable(); snapshot.SetTableName(table.LeafName()); @@ -62,8 +63,12 @@ TVector<ISubOperation::TPtr> CreateBuildIndex(TOperationId opId, const TTxTransa checks .IsValidLeafName() .PathsLimit(2) // index and impl-table - .DirChildrenLimit() - .ShardsLimit(1); // impl-table + .DirChildrenLimit(); + + if (!tx.GetInternal()) { + checks + .ShardsLimit(1); // impl-table + } if (!checks) { return {CreateReject(opId, checks.GetStatus(), checks.GetError())}; @@ -95,6 +100,7 @@ TVector<ISubOperation::TPtr> CreateBuildIndex(TOperationId opId, const TTxTransa *outTx.MutableLockGuard() = tx.GetLockGuard(); outTx.MutableCreateTableIndex()->CopyFrom(indexDesc); outTx.MutableCreateTableIndex()->SetState(NKikimrSchemeOp::EIndexStateWriteOnly); + outTx.SetInternal(tx.GetInternal()); if (!indexDesc.HasType()) { outTx.MutableCreateTableIndex()->SetType(NKikimrSchemeOp::EIndexTypeGlobal); @@ -106,6 +112,7 @@ TVector<ISubOperation::TPtr> CreateBuildIndex(TOperationId opId, const TTxTransa { auto outTx = TransactionTemplate(table.Parent().PathString(), NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexMainTable); *outTx.MutableLockGuard() = tx.GetLockGuard(); + outTx.SetInternal(tx.GetInternal()); auto& snapshot = *outTx.MutableInitiateBuildIndexMainTable(); snapshot.SetTableName(table.LeafName()); @@ -118,6 +125,7 @@ TVector<ISubOperation::TPtr> CreateBuildIndex(TOperationId opId, const TTxTransa auto outTx = TransactionTemplate(index.PathString(), NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexImplTable); *outTx.MutableCreateTable() = std::move(implTableDesc); + outTx.SetInternal(tx.GetInternal()); return CreateInitializeBuildIndexImplTable(NextPartId(opId, result), outTx); }; diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_indexed_table.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_indexed_table.cpp index 3adaa630e0..c47eb8fde2 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_create_indexed_table.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_indexed_table.cpp @@ -110,9 +110,13 @@ TVector<ISubOperation::TPtr> CreateIndexedTable(TOperationId nextId, const TTxTr { auto checks = baseTablePath.Check(); checks - .PathShardsLimit(baseShards) - .PathsLimit(pathToCreate) - .ShardsLimit(shardsToCreate); + .PathsLimit(pathToCreate); + + if (!tx.GetInternal()) { + checks + .PathShardsLimit(baseShards) + .ShardsLimit(shardsToCreate); + } if (!checks) { return {CreateReject(nextId, NKikimrScheme::EStatus::StatusResourceExhausted, checks.GetError())}; @@ -224,6 +228,7 @@ TVector<ISubOperation::TPtr> CreateIndexedTable(TOperationId nextId, const TTxTr auto scheme = TransactionTemplate(tx.GetWorkingDir(), NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable); scheme.SetFailOnExist(tx.GetFailOnExist()); scheme.SetAllowCreateInTempDir(tx.GetAllowCreateInTempDir()); + scheme.SetInternal(tx.GetInternal()); scheme.MutableCreateTable()->CopyFrom(baseTableDescription); if (tx.HasAlterUserAttributes()) { @@ -270,6 +275,7 @@ TVector<ISubOperation::TPtr> CreateIndexedTable(TOperationId nextId, const TTxTr NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable); scheme.SetFailOnExist(tx.GetFailOnExist()); scheme.SetAllowCreateInTempDir(tx.GetAllowCreateInTempDir()); + scheme.SetInternal(tx.GetInternal()); *scheme.MutableCreateTable() = std::move(implTableDesc); @@ -311,6 +317,7 @@ TVector<ISubOperation::TPtr> CreateIndexedTable(TOperationId nextId, const TTxTr NKikimrSchemeOp::EOperationType::ESchemeOpCreateSequence); scheme.SetFailOnExist(tx.GetFailOnExist()); scheme.SetAllowCreateInTempDir(tx.GetAllowCreateInTempDir()); + scheme.SetInternal(tx.GetInternal()); *scheme.MutableSequence() = sequenceDescription; diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_create_table.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_create_table.cpp index 8b91c72d56..d43c27aee8 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_create_table.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_table.cpp @@ -503,9 +503,13 @@ public: .IsValidLeafName() .PathsLimit() .DirChildrenLimit() - .ShardsLimit(shardsToCreate) - .PathShardsLimit(shardsToCreate) .IsValidACL(acl); + + if (!Transaction.GetInternal()) { + checks + .ShardsLimit(shardsToCreate) + .PathShardsLimit(shardsToCreate); + } } if (!checks) { diff --git a/ydb/core/tx/schemeshard/schemeshard_build_index__create.cpp b/ydb/core/tx/schemeshard/schemeshard_build_index__create.cpp index 98c75f6de4..4ff88c8d43 100644 --- a/ydb/core/tx/schemeshard/schemeshard_build_index__create.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_build_index__create.cpp @@ -117,8 +117,12 @@ public: checks .IsValidLeafName() .PathsLimit(2) // index and impl-table - .DirChildrenLimit() - .ShardsLimit(1); // impl-table + .DirChildrenLimit(); + + if (!request.GetInternal()) { + checks + .ShardsLimit(1); // impl-table + } if (!checks) { return Reply(checks.GetStatus(), checks.GetError()); diff --git a/ydb/core/tx/schemeshard/schemeshard_import_flow_proposals.cpp b/ydb/core/tx/schemeshard/schemeshard_import_flow_proposals.cpp index 30b63428d4..7786174035 100644 --- a/ydb/core/tx/schemeshard/schemeshard_import_flow_proposals.cpp +++ b/ydb/core/tx/schemeshard/schemeshard_import_flow_proposals.cpp @@ -217,7 +217,9 @@ THolder<TEvIndexBuilder::TEvCreateRequest> BuildIndexPropose( const TPath domainPath = TPath::Init(importInfo->DomainPathId, ss); auto propose = MakeHolder<TEvIndexBuilder::TEvCreateRequest>(ui64(txId), domainPath.PathString(), std::move(settings)); - (*propose->Record.MutableOperationParams()->mutable_labels())["uid"] = uid; + auto& request = propose->Record; + (*request.MutableOperationParams()->mutable_labels())["uid"] = uid; + request.SetInternal(true); return propose; } @@ -259,11 +261,11 @@ THolder<TEvSchemeShard::TEvModifySchemeTransaction> CreateChangefeedPropose( if (!FillChangefeedDescription(cdcStreamDescription, changefeed, status, error)) { return nullptr; } - + if (topic.has_retention_period()) { cdcStream.SetRetentionPeriodSeconds(topic.retention_period().seconds()); } - + if (topic.has_partitioning_settings()) { i64 minActivePartitions = topic.partitioning_settings().min_active_partitions(); diff --git a/ydb/core/tx/schemeshard/ut_restore/ut_restore.cpp b/ydb/core/tx/schemeshard/ut_restore/ut_restore.cpp index ec6cb468cb..a290d297a1 100644 --- a/ydb/core/tx/schemeshard/ut_restore/ut_restore.cpp +++ b/ydb/core/tx/schemeshard/ut_restore/ut_restore.cpp @@ -296,7 +296,7 @@ namespace { case EPathTypeView: result.emplace(prefix + "/create_view.sql", item.CreationQuery); break; - case EPathTypeCdcStream: + case EPathTypeCdcStream: result.emplace(prefix + "/changefeed_description.pb", item.Changefeed.Changefeed); result.emplace(prefix + "/topic_description.pb", item.Changefeed.Topic); break; @@ -5031,6 +5031,116 @@ Y_UNIT_TEST_SUITE(TImportTests) { Y_UNIT_TEST(ChangefeedsWithTablePermissions) { TestImportChangefeeds(3, AddedSchemeWithPermissions); } + + Y_UNIT_TEST(IgnoreBasicSchemeLimits) { + TTestBasicRuntime runtime; + TTestEnv env(runtime); + ui64 txId = 100; + + TestCreateExtSubDomain(runtime, ++txId, "/MyRoot", R"( + Name: "Alice" + )"); + TestAlterExtSubDomain(runtime, ++txId, "/MyRoot", R"( + Name: "Alice" + ExternalSchemeShard: true + PlanResolution: 50 + Coordinators: 1 + Mediators: 1 + TimeCastBucketsPerMediator: 2 + StoragePools { + Name: "Alice:hdd" + Kind: "hdd" + } + )"); + env.TestWaitNotification(runtime, txId); + + ui64 tenantSchemeShard = 0; + TestDescribeResult(DescribePath(runtime, "/MyRoot/Alice"), { + NLs::ExtractTenantSchemeshard(&tenantSchemeShard) + }); + UNIT_ASSERT_UNEQUAL(tenantSchemeShard, 0); + + TSchemeLimits basicLimits; + basicLimits.MaxShards = 4; + basicLimits.MaxShardsInPath = 2; + SetSchemeshardSchemaLimits(runtime, basicLimits, tenantSchemeShard); + + TestDescribeResult(DescribePath(runtime, tenantSchemeShard, "/MyRoot/Alice"), { + NLs::DomainLimitsIs(basicLimits.MaxPaths, basicLimits.MaxShards), + NLs::PathsInsideDomain(0), + NLs::ShardsInsideDomain(3) + }); + + TestCreateTable(runtime, tenantSchemeShard, ++txId, "/MyRoot/Alice", R"( + Name: "table1" + Columns { Name: "Key" Type: "Uint64" } + Columns { Name: "Value" Type: "Utf8" } + KeyColumnNames: ["Key"] + )"); + env.TestWaitNotification(runtime, txId, tenantSchemeShard); + + TestCreateTable(runtime, tenantSchemeShard, ++txId, "/MyRoot/Alice", R"( + Name: "table2" + Columns { Name: "Key" Type: "Uint64" } + Columns { Name: "Value" Type: "Utf8" } + KeyColumnNames: ["Key"] + )", + { NKikimrScheme::StatusResourceExhausted } + ); + + const auto data = GenerateTestData(R"( + columns { + name: "key" + type { optional_type { item { type_id: UTF8 } } } + } + columns { + name: "value" + type { optional_type { item { type_id: UTF8 } } } + } + primary_key: "key" + partition_at_keys { + split_points { + type { tuple_type { elements { optional_type { item { type_id: UTF8 } } } } } + value { items { text_value: "b" } } + } + } + indexes { + name: "ByValue" + index_columns: "value" + global_index {} + } + )", + {{"a", 1}, {"b", 1}} + ); + + TPortManager portManager; + const ui16 port = portManager.GetPort(); + + TS3Mock s3Mock(ConvertTestData(data), TS3Mock::TSettings(port)); + UNIT_ASSERT(s3Mock.Start()); + + const auto importId = ++txId; + TestImport(runtime, tenantSchemeShard, importId, "/MyRoot/Alice", Sprintf(R"( + ImportFromS3Settings { + endpoint: "localhost:%d" + scheme: HTTP + items { + source_prefix: "" + destination_path: "/MyRoot/Alice/ImportDir/Table" + } + } + )", + port + )); + env.TestWaitNotification(runtime, importId, tenantSchemeShard); + TestGetImport(runtime, tenantSchemeShard, importId, "/MyRoot/Alice"); + + TestDescribeResult(DescribePath(runtime, tenantSchemeShard, "/MyRoot/Alice"), { + NLs::DomainLimitsIs(basicLimits.MaxPaths, basicLimits.MaxShards), + NLs::PathsInsideDomain(5), + NLs::ShardsInsideDomain(7) + }); + } } Y_UNIT_TEST_SUITE(TImportWithRebootsTests) { @@ -5380,7 +5490,7 @@ Y_UNIT_TEST_SUITE(TImportWithRebootsTests) { const auto changefeedName = "update_changefeed"; schemes.emplace("", R"( - columns { + columns { name: "key" type { optional_type { item { type_id: UTF8 } } } } @@ -5447,11 +5557,11 @@ Y_UNIT_TEST_SUITE(TImportWithRebootsTests) { } } )"; - + NAttr::TAttributes attr; attr.emplace(NAttr::EKeys::TOPIC_DESCRIPTION, topicDesc); - schemes.emplace("/update_feed", + schemes.emplace("/update_feed", TTypedScheme { EPathTypeCdcStream, changefeedDesc, @@ -5468,7 +5578,7 @@ Y_UNIT_TEST_SUITE(TImportWithRebootsTests) { Y_UNIT_TEST(CancelShouldSucceedOnSingleChangefeed) { CancelShouldSucceed(GetSchemeWithChangefeed()); } - + Y_UNIT_TEST(CancelShouldSucceedOnDependentView) { CancelShouldSucceed( { |