aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew-rykov <arykov@ydb.tech>2022-08-10 13:26:34 +0300
committerandrew-rykov <arykov@ydb.tech>2022-08-10 13:26:34 +0300
commit811b039dffc7d5e35d3b8a34fad80b16c38f570c (patch)
tree1fed92fff9a6cbd73f8d953b265643d21acf60aa
parent41c0210dc6f25ccb7584f1efd8dde6f3824a197e (diff)
downloadydb-811b039dffc7d5e35d3b8a34fad80b16c38f570c.tar.gz
audit logs in schemeshard
fixed merge error remove consistent operation details audit logs in schemeshard
-rw-r--r--ydb/core/kqp/ut/kqp_scheme_ut.cpp71
-rw-r--r--ydb/core/tx/schemeshard/CMakeLists.txt2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation.cpp61
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation.h1
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp10
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_move_tables.cpp9
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_part.h18
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp513
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h34
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path.cpp7
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path.h2
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path_element.cpp352
-rw-r--r--ydb/core/tx/schemeshard/schemeshard_path_element.h405
14 files changed, 1119 insertions, 368 deletions
diff --git a/ydb/core/kqp/ut/kqp_scheme_ut.cpp b/ydb/core/kqp/ut/kqp_scheme_ut.cpp
index 06dc4ba969..ee97c8b17f 100644
--- a/ydb/core/kqp/ut/kqp_scheme_ut.cpp
+++ b/ydb/core/kqp/ut/kqp_scheme_ut.cpp
@@ -100,6 +100,77 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
}
+ Y_UNIT_TEST(CreateAndDropTableCheckAuditLog) {
+ TStringStream logStream;
+ TKikimrRunner kikimr(TKikimrSettings().SetLogStream(&logStream));
+ kikimr.GetTestServer().GetRuntime()->SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_INFO);
+ {
+ auto schemeClient = kikimr.GetSchemeClient();
+
+ NYdb::NScheme::TPermissions permissions("user0@builtin", {"ydb.deprecated.create_table"});
+ AssertSuccessResult(schemeClient.ModifyPermissions("/Root",
+ NYdb::NScheme::TModifyPermissionsSettings().AddGrantPermissions(permissions)
+ ).ExtractValueSync()
+ );
+ }
+
+ auto driverConfig = TDriverConfig()
+ .SetEndpoint(kikimr.GetEndpoint())
+ .SetAuthToken("user0@builtin");
+ auto driver = TDriver(driverConfig);
+ auto db = NYdb::NTable::TTableClient(driver);
+
+ auto session = db.CreateSession().GetValueSync().GetSession();
+
+ {
+ const static TString createTableQuery = R"(
+ CREATE TABLE `/Root/Test1234/KeyValue` (
+ Key Uint32,
+ Value String,
+ PRIMARY KEY(Key)
+ );
+ )";
+ auto result = session.ExecuteSchemeQuery(createTableQuery).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ }
+
+ {
+ const static TString dropTableQuery = R"(
+ DROP TABLE `/Root/Test1234/KeyValue`;
+ )";
+ auto result = session.ExecuteSchemeQuery(dropTableQuery).ExtractValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ }
+
+ TString line;
+ int mtc = 0;
+ int ctc = 0;
+ int dtc = 0;
+ while (logStream.ReadLine(line)) {
+ if (line.find("AUDIT:") == line.npos)
+ continue;
+
+ const TString modifyAclTablePattern("operation: MODIFY ACL");
+ if (line.find(modifyAclTablePattern) != line.npos) {
+ mtc += 1;
+ }
+
+ const TString createTablePattern("operation: CREATE TABLE");
+ if (line.find(createTablePattern) != line.npos) {
+ ctc += 1;
+ }
+
+ const TString dropTablePattern("operation: DROP TABLE");
+ if (line.find(dropTablePattern) != line.npos) {
+ dtc += 1;
+ }
+ }
+
+ UNIT_ASSERT_VALUES_EQUAL_C(mtc, 1, mtc);
+ UNIT_ASSERT_VALUES_EQUAL_C(ctc, 1, ctc);
+ UNIT_ASSERT_VALUES_EQUAL_C(dtc, 1, dtc);
+ }
+
Y_UNIT_TEST(CreateDropTableMultipleTime) {
TKikimrRunner kikimr;
auto db = kikimr.GetTableClient();
diff --git a/ydb/core/tx/schemeshard/CMakeLists.txt b/ydb/core/tx/schemeshard/CMakeLists.txt
index 480e801ccb..ac577e1ce8 100644
--- a/ydb/core/tx/schemeshard/CMakeLists.txt
+++ b/ydb/core/tx/schemeshard/CMakeLists.txt
@@ -150,6 +150,7 @@ target_sources(core-tx-schemeshard PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_schema.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__upgrade_access_database.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard__make_access_database_no_inheritable.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_impl.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_billing_helpers.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_domain_links.cpp
@@ -157,6 +158,7 @@ target_sources(core-tx-schemeshard PRIVATE
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_identificators.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_info_types.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_path_describer.cpp
+ ${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_path_element.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_path.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_types.cpp
${CMAKE_SOURCE_DIR}/ydb/core/tx/schemeshard/schemeshard_ui64id.cpp
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation.cpp b/ydb/core/tx/schemeshard/schemeshard__operation.cpp
index 517e7f3eb0..4180c031fa 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation.cpp
@@ -1,9 +1,12 @@
#include "schemeshard__operation.h"
+#include "schemeshard__operation_part.h"
#include "schemeshard__operation_side_effects.h"
#include "schemeshard__operation_memory_changes.h"
#include "schemeshard__operation_db_changes.h"
+#include "schemeshard_audit_log_fragment.h"
+
#include "schemeshard_impl.h"
#include <ydb/core/tablet/tablet_exception.h>
@@ -68,6 +71,33 @@ NKikimrScheme::TEvModifySchemeTransaction GetRecordForPrint(const NKikimrScheme:
return recordForPrint;
}
+TString GetAuditLogEntry(const TTxId& txId, const THolder<TProposeResponse>& response, TOperationContext& context) {
+ auto auditLog = TStringBuilder();
+
+ auditLog << "txId: " << txId;
+ for (const auto& frag: context.AuditLogFragments) {
+ auditLog << ", ";
+ auditLog << frag.ToString();
+ }
+
+ auto fragPath = TPath::Resolve(context.AuditLogFragments.front().GetAnyPath(), context.SS);
+ if (!fragPath.IsResolved()) {
+ fragPath.RiseUntilFirstResolvedParent();
+ }
+ if (!fragPath.IsEmpty()) {
+ auditLog << ", database: " << fragPath.GetDomainPathString();
+ }
+
+ auditLog << ", subject: " << context.GetSubject();
+
+ auditLog << ", status: " << NKikimrScheme::EStatus_Name(response->Record.GetStatus());
+ if (response->Record.HasReason()) {
+ auditLog << ", reason: " << response->Record.GetReason();
+ }
+
+ return auditLog;
+}
+
THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request, TOperationContext& context) {
THolder<TProposeResponse> response = nullptr;
@@ -85,7 +115,7 @@ THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request
}
TOperation::TPtr operation = new TOperation(txId);
- Operations[operation->GetTxId()] = operation; //record is erased at ApplyOnExecute if all parts are done at propose
+ Operations[txId] = operation; //record is erased at ApplyOnExecute if all parts are done at propose
if (record.GetUserToken()) {
NACLibProto::TUserToken tokenPb;
@@ -100,12 +130,18 @@ THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request
}
for (const auto& transaction: record.GetTransaction()) {
+ context.AddAuditLogFragment(transaction);
+ }
+
+ for (const auto& transaction: record.GetTransaction()) {
auto quotaResult = operation->ConsumeQuota(transaction, context);
if (quotaResult.Status != NKikimrScheme::StatusSuccess) {
response.Reset(new TEvSchemeShard::TEvModifySchemeTransactionResult(
quotaResult.Status, ui64(txId), ui64(selfId)));
response->SetError(quotaResult.Status, quotaResult.Reason);
- Operations.erase(operation->GetTxId());
+ Operations.erase(txId);
+
+ LOG_NOTICE_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "AUDIT: " << GetAuditLogEntry(txId, response, context));
return std::move(response);
}
}
@@ -126,16 +162,20 @@ THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request
response.Reset(new TEvSchemeShard::TEvModifySchemeTransactionResult(
splitResult.Status, ui64(txId), ui64(selfId)));
response->SetError(splitResult.Status, splitResult.Reason);
- Operations.erase(operation->GetTxId());
+ Operations.erase(txId);
+
+ LOG_NOTICE_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "AUDIT: " << GetAuditLogEntry(txId, response, context));
return std::move(response);
}
transactions.insert(transactions.end(), splitResult.Transactions.begin(), splitResult.Transactions.end());
}
+ const TString owner = record.HasOwner() ? record.GetOwner() : BUILTIN_ACL_ROOT;
+ context.ClearAuditLogFragments();
+
//for all tx in transactions
for (const auto& transaction: transactions) {
- const TOperationId pathOpId = TOperationId(txId, operation->Parts.size());
TVector<ISubOperationBase::TPtr> parts = operation->ConstructParts(transaction, context);
if (parts.size() > 1) {
@@ -143,15 +183,17 @@ THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request
context.IsAllowedPrivateTables = true;
}
- const TString owner = record.HasOwner() ? record.GetOwner() : BUILTIN_ACL_ROOT;
+ context.AddAuditLogFragment(transaction);
for (auto& part: parts) {
+ const TOperationId pathOpId = operation->NextPartId();
+
response = part->Propose(owner, context);
Y_VERIFY(response);
LOG_NOTICE_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD,
"IgniteOperation"
- << ", opId: " << pathOpId
+ << ", opId: " << operation->NextPartId()
<< ", propose status:" << NKikimrScheme::EStatus_Name(response->Record.GetStatus())
<< ", reason: " << response->Record.GetReason()
<< ", at schemeshard: " << selfId);
@@ -199,12 +241,15 @@ THolder<TProposeResponse> TSchemeShard::IgniteOperation(TProposeRequest& request
context.MemChanges.UnDo(context.SS);
context.OnComplete.ApplyOnExecute(context.SS, context.GetTxc(), context.Ctx);
- Operations.erase(operation->GetTxId());
+ Operations.erase(txId);
+
+ LOG_NOTICE_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "AUDIT: " << GetAuditLogEntry(txId, response, context));
return std::move(response);
}
}
}
+ LOG_NOTICE_S(context.Ctx, NKikimrServices::FLAT_TX_SCHEMESHARD, "AUDIT: " << GetAuditLogEntry(txId, response, context));
return std::move(response);
}
@@ -1121,7 +1166,7 @@ TVector<ISubOperationBase::TPtr> TOperation::ConstructParts(const TTxTransaction
switch (opType) {
case NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable:
if (tx.GetCreateTable().HasCopyFromTable()) {
- return {CreateCopyTable(NextPartId(), tx, context)}; // Copy indexes table as well as common table
+ return CreateCopyTable(NextPartId(), tx, context); // Copy indexes table as well as common table
}
return {ConstructPart(opType, tx)};
case NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexedTable:
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation.h b/ydb/core/tx/schemeshard/schemeshard__operation.h
index 5d19d8edbd..ea66e3c5c8 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation.h
+++ b/ydb/core/tx/schemeshard/schemeshard__operation.h
@@ -132,7 +132,6 @@ struct TOperation: TSimpleRefCount<TOperation> {
Y_VERIFY(Barriers.begin()->first == name);
Barriers.erase(name);
}
-private:
TOperationId NextPartId() { return TOperationId(TxId, TSubTxId(Parts.size())); }
};
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 2d957165c6..417fc98806 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_create_build_index.cpp
@@ -62,7 +62,7 @@ TVector<ISubOperationBase::TPtr> CreateBuildIndex(TOperationId nextId, const TTx
TString explain;
if (!NTableIndex::IsCompatibleIndex(baseTableColumns, indexKeys, explain)) {
- return {CreateReject(nextId, NKikimrScheme::EStatus::StatusInvalidParameter, explain)};
+ return {CreateReject(nextId, NKikimrScheme::EStatus::StatusInvalidParameter, explain)};
}
NTableIndex::TTableColumns impTableColumns = NTableIndex::CalcTableImplDescription(baseTableColumns, indexKeys);
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp
index 539c7d74c3..8ebf3bd757 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp
@@ -503,6 +503,11 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveIndex(TOperationId nextId,
return {CreateReject(nextId, NKikimrScheme::EStatus::StatusPreconditionFailed, errStr)};
}
+ const auto& moving = tx.GetMoveIndex();
+ const auto& mainTable = moving.GetTablePath();
+ const auto& srcIndex = moving.GetSrcPath();
+ const auto& dstIndex = moving.GetDstPath();
+
{
TString errStr;
if (!context.SS->CheckApplyIf(tx, errStr)) {
@@ -510,11 +515,6 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveIndex(TOperationId nextId,
}
}
- auto moving = tx.GetMoveIndex();
-
- const auto& mainTable = moving.GetTablePath();
- const auto& srcIndex = moving.GetSrcPath();
- const auto& dstIndex = moving.GetDstPath();
bool allowOverwrite = moving.HasAllowOverwrite() && moving.GetAllowOverwrite();
TPath mainTablePath = TPath::Resolve(mainTable, context.SS);
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_move_tables.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_move_tables.cpp
index 57b66f0ca8..e221523f8a 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_move_tables.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_move_tables.cpp
@@ -16,6 +16,10 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveTable(TOperationId nextId,
TVector<ISubOperationBase::TPtr> result;
+ const auto& moving = tx.GetMoveTable();
+ const auto& srcStr = moving.GetSrcPath();
+ const auto& dstStr = moving.GetDstPath();
+
{
TString errStr;
if (!context.SS->CheckApplyIf(tx, errStr)) {
@@ -23,11 +27,6 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveTable(TOperationId nextId,
}
}
- auto moving = tx.GetMoveTable();
-
- auto& srcStr = moving.GetSrcPath();
- auto& dstStr = moving.GetDstPath();
-
TPath srcPath = TPath::Resolve(srcStr, context.SS);
{
TPath::TChecker checks = srcPath.Check();
diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_part.h b/ydb/core/tx/schemeshard/schemeshard__operation_part.h
index f961f6cfaf..8d42df6893 100644
--- a/ydb/core/tx/schemeshard/schemeshard__operation_part.h
+++ b/ydb/core/tx/schemeshard/schemeshard__operation_part.h
@@ -4,6 +4,7 @@
#include "schemeshard_private.h"
#include "schemeshard_tx_infly.h"
#include "schemeshard_types.h"
+#include "schemeshard_audit_log_fragment.h"
#include "schemeshard__operation_side_effects.h"
#include "schemeshard__operation_memory_changes.h"
#include "schemeshard__operation_db_changes.h"
@@ -89,6 +90,8 @@ public:
TAutoPtr<NACLib::TUserToken> UserToken = nullptr;
bool IsAllowedPrivateTables = false;
+ TVector<TAuditLogFragment> AuditLogFragments;
+
private:
NTabletFlatExecutor::TTransactionContext& Txc;
bool ProtectDB = false;
@@ -107,6 +110,21 @@ public:
, Txc(txc)
{}
+ void AddAuditLogFragment(TAuditLogFragment&& op) {
+ AuditLogFragments.push_back(std::move(op));
+ }
+
+ void ClearAuditLogFragments() {
+ AuditLogFragments.clear();
+ }
+
+ TString GetSubject() const {
+ if (UserToken) {
+ return UserToken->GetUserSID();
+ }
+ return "no subject";
+ }
+
NTable::TDatabase& GetDB() {
Y_VERIFY_S(ProtectDB == false,
"there is attempt to write to the DB when it is protected,"
diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp
new file mode 100644
index 0000000000..289e80451d
--- /dev/null
+++ b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.cpp
@@ -0,0 +1,513 @@
+#include "schemeshard_audit_log_fragment.h"
+
+#include <ydb/library/aclib/aclib.h>
+#include <ydb/core/base/path.h>
+
+namespace NKikimr {
+namespace NSchemeShard {
+
+TString DefineUserOperationName(NKikimrSchemeOp::EOperationType type) {
+ switch (type) {
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMkDir:
+ return "CREATE DIRECTORY";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable:
+ return "CREATE TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreatePersQueueGroup:
+ return "CREATE PERSISTENT QUEUE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTable:
+ return "DROP TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropPersQueueGroup:
+ return "DROP PERSISTENT QUEUE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterTable:
+ return "ALTER TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterPersQueueGroup:
+ return "ALTER PERSISTENT QUEUE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL:
+ return "MODIFY ACL";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpRmDir:
+ return "DROP DIRECTORY";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpSplitMergeTablePartitions:
+ return "ALTER TABLE PARTITIONS";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpBackup:
+ return "BACKUP TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSubDomain:
+ return "CREATE DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSubDomain:
+ return "DROP DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateRtmrVolume:
+ return "CREATE RTMR VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateBlockStoreVolume:
+ return "CREATE BLOCK STORE VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterBlockStoreVolume:
+ return "ALTER BLOCK STORE VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAssignBlockStoreVolume:
+ return "ALTER BLOCK STORE VOLUME ASSIGN";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropBlockStoreVolume:
+ return "DROP BLOCK STORE VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateKesus:
+ return "CREATE KESUS";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropKesus:
+ return "DROP KESUS";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropSubDomain:
+ return "DROP DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSolomonVolume:
+ return "CREATE SOLOMON VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSolomonVolume:
+ return "DROP SOLOMON VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterKesus:
+ return "ALTER KESUS";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSubDomain:
+ return "ALTER DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterUserAttributes:
+ return "ALTER USER ATTRIBUTES";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropUnsafe:
+ return "DROP PATH UNSAFE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexedTable:
+ return "CREATE TABLE WITH INDEXES";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateTableIndex:
+ return "CREATE INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateConsistentCopyTables:
+ return "CREATE TABLE COPY FROM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTableIndex:
+ return "DROP INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateExtSubDomain:
+ return "CREATE DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterExtSubDomain:
+ return "ALTER DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropExtSubDomain:
+ return "DROP DATABASE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOp_DEPRECATED_35:
+ return "ESchemeOp_DEPRECATED_35";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpUpgradeSubDomain:
+ return "ALTER DATABASE MIGRATE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpUpgradeSubDomainDecision:
+ return "ALTER DATABASE MIGRATE DECISION";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexBuild:
+ return "BUILD INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexMainTable:
+ return "ALTER TABLE BUILD INDEX INIT";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateLockForIndexBuild:
+ return "ALTER TABLE LOCK";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpApplyIndexBuild:
+ return "ALTER TABLE BUILD INDEX APPLY";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpFinalizeBuildIndexMainTable:
+ return "ALTER TABLE BUILD INDEX FINISH";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterTableIndex:
+ return "ALTER INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSolomonVolume:
+ return "ALTER SOLOMON VOLUME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropLock:
+ return "ALTER TABLE UNLOCK";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpFinalizeBuildIndexImplTable:
+ return "ALTER TABLE BUILD INDEX FINISH";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexImplTable:
+ return "ALTER TABLE BUILD INDEX INIT";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropIndex:
+ return "ALTER TABLE DROP INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTableIndexAtMainTable:
+ return "ALTER TABLE DROP INDEX";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCancelIndexBuild:
+ return "ALTER TABLE BUILD INDEX CANCEL";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateFileStore:
+ return "CREATE FILE STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterFileStore:
+ return "ALTER FILE STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropFileStore:
+ return "DROP FILE STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpRestore:
+ return "RESTORE TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateColumnStore:
+ return "CREATE COLUMN STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterColumnStore:
+ return "ALTER COLUMN STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropColumnStore:
+ return "DROP COLUMN STORE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateColumnTable:
+ return "CREATE COLUMN TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterColumnTable:
+ return "ALTER COLUMN TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropColumnTable:
+ return "DROP COLUMN TABLE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterLogin:
+ return "ALTER LOGIN";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStream:
+ return "ATER TABLE CREATE CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStreamImpl:
+ return "CREATE CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStreamAtTable:
+ return "ATER TABLE CREATE CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStream:
+ return "ATER CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStreamImpl:
+ return "ATER CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStreamAtTable:
+ return "ATER TABLE ATER CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStream:
+ return "DROP CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStreamImpl:
+ return "DROP CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStreamAtTable:
+ return "ATER TABLE DROP CDC STREAM";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveTable:
+ return "ALTER TABLE RENAME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveTableIndex:
+ return "ALTER TABLE INDEX RENAME";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSequence:
+ return "CREATE SEQUENCE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSequence:
+ return "ALTER SEQUENCE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSequence:
+ return "DROP SEQUENCE";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateReplication:
+ return "CREATE REPLICATION";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterReplication:
+ return "ALTER REPLICATION";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropReplication:
+ return "DROP REPLICATION";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateBlobDepot:
+ return "CREATE BLOB DEPOT";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterBlobDepot:
+ return "ALTER BLOB DEPOT";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropBlobDepot:
+ return "DROP BLOB DEPOT";
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveIndex:
+ return "ALTER TABLE INDEX RENAME";
+ };
+}
+
+TAuditLogFragment::TAuditLogFragment(const NKikimrSchemeOp::TModifyScheme& tx)
+ : Operation(DefineUserOperationName(tx.GetOperationType()))
+ , ProtoRequest(tx.ShortDebugString())
+{
+ FillPathes(tx);
+ FillACL(tx);
+}
+
+void TAuditLogFragment::FillACL(const NKikimrSchemeOp::TModifyScheme& tx) {
+ using namespace NACLib;
+
+ bool hasACL = tx.HasModifyACL() && tx.GetModifyACL().HasDiffACL();
+ if (hasACL) {
+ NACLib::TDiffACL diffACL(tx.GetModifyACL().GetDiffACL());
+ for (const NACLibProto::TDiffACE& diffACE : diffACL.GetDiffACE()) {
+ const NACLibProto::TACE& ace = diffACE.GetACE();
+ switch (static_cast<EDiffType>(diffACE.GetDiffType())) {
+ case EDiffType::Add:
+ AddACL.push_back(TACL::ToString(ace));
+ break;
+ case EDiffType::Remove:
+ RmACL.push_back(TACL::ToString(ace));
+ break;
+ }
+ }
+ }
+
+ bool hasOwner = tx.HasModifyACL() && tx.GetModifyACL().HasNewOwner();
+ if (hasOwner) {
+ NewOwner = tx.GetModifyACL().GetNewOwner();
+ }
+}
+
+void TAuditLogFragment::FillPathes(const NKikimrSchemeOp::TModifyScheme& tx) {
+ switch (tx.GetOperationType()) {
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMkDir:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetMkDir().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreatePersQueueGroup:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreatePersQueueGroup().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropPersQueueGroup:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterPersQueueGroup:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterPersQueueGroup().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpModifyACL:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetModifyACL().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpRmDir:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpSplitMergeTablePartitions:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSplitMergeTablePartitions().GetTablePath()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpBackup:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetBackup().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateRtmrVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateRtmrVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateBlockStoreVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateBlockStoreVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterBlockStoreVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterBlockStoreVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAssignBlockStoreVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAssignBlockStoreVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropBlockStoreVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateKesus:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetKesus().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropKesus:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSolomonVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateSolomonVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSolomonVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterKesus:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetKesus().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterUserAttributes:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterUserAttributes().GetPathName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropUnsafe:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexedTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateIndexedTable().GetTableDescription().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateTableIndex:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateTableIndex().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateConsistentCopyTables:
+ for (const auto& item: tx.GetCreateConsistentCopyTables().GetCopyTableDescriptions()) {
+ SrcPaths.push_back(item.GetSrcPath());
+ DstPaths.push_back(item.GetDstPath());
+ }
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTableIndex:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateExtSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterExtSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpForceDropExtSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOp_DEPRECATED_35:
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpUpgradeSubDomain:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetUpgradeSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpUpgradeSubDomainDecision:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetUpgradeSubDomain().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateIndexBuild:
+ Path = JoinPath({tx.GetInitiateIndexBuild().GetTable(), tx.GetInitiateIndexBuild().GetIndex().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexMainTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetInitiateBuildIndexMainTable().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateLockForIndexBuild:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetLockConfig().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpApplyIndexBuild:
+ Path = JoinPath({tx.GetApplyIndexBuild().GetTablePath(), tx.GetApplyIndexBuild().GetIndexName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpFinalizeBuildIndexMainTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetFinalizeBuildIndexMainTable().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterTableIndex:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterTableIndex().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSolomonVolume:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterSolomonVolume().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropLock:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetLockConfig().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpFinalizeBuildIndexImplTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpInitiateBuildIndexImplTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropIndex:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDropIndex().GetTableName(), tx.GetDropIndex().GetIndexName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropTableIndexAtMainTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDropIndex().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCancelIndexBuild:
+ Path = JoinPath({tx.GetCancelIndexBuild().GetTablePath(), tx.GetCancelIndexBuild().GetIndexName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateFileStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateFileStore().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterFileStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterFileStore().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropFileStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpRestore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetRestore().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateColumnStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateColumnStore().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterColumnStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterColumnStore().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropColumnStore:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateColumnTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterColumnTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterColumnTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterColumnTable().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropColumnTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterLogin:
+ Path = tx.GetWorkingDir();
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStream:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateCdcStream().GetTableName(), tx.GetCreateCdcStream().GetStreamDescription().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStreamImpl:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateCdcStream().GetStreamDescription().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateCdcStreamAtTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetCreateCdcStream().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStream:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterCdcStream().GetTableName(), tx.GetAlterCdcStream().GetStreamName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStreamImpl:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterCdcStream().GetStreamName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterCdcStreamAtTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetAlterCdcStream().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStream:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDropCdcStream().GetTableName(), tx.GetDropCdcStream().GetStreamName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStreamImpl:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropCdcStreamAtTable:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDropCdcStream().GetTableName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveTable:
+ SrcPaths.push_back(tx.GetMoveTable().GetSrcPath());
+ DstPaths.push_back(tx.GetMoveTable().GetDstPath());
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveTableIndex:
+ SrcPaths.push_back(tx.GetMoveTableIndex().GetSrcPath());
+ DstPaths.push_back(tx.GetMoveTableIndex().GetDstPath());
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateSequence:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetSequence().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterSequence:
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropSequence:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateReplication:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetReplication().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterReplication:
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropReplication:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetDrop().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpCreateBlobDepot:
+ Path = JoinPath({tx.GetWorkingDir(), tx.GetBlobDepot().GetName()});
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpAlterBlobDepot:
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpDropBlobDepot:
+ break;
+ case NKikimrSchemeOp::EOperationType::ESchemeOpMoveIndex:
+ SrcPaths.push_back(JoinPath({tx.GetMoveIndex().GetTablePath(), tx.GetMoveIndex().GetSrcPath()}));
+ DstPaths.push_back(JoinPath({tx.GetMoveIndex().GetTablePath(), tx.GetMoveIndex().GetDstPath()}));
+ break;
+ };
+}
+
+TString TAuditLogFragment::GetAnyPath() const {
+ if (Path) {
+ return *Path;
+ } else if (SrcPaths) {
+ return SrcPaths.front();
+ } else if (DstPaths) {
+ return DstPaths.front();
+ } else {
+ return "";
+ }
+}
+
+TString TAuditLogFragment::ToString() const {
+ auto result = TStringBuilder();
+
+ result << "operation: " << Operation;
+
+ if (Path) {
+ result << ", path: " << Path;
+ } else if (SrcPaths && DstPaths) {
+ Y_VERIFY_DEBUG(SrcPaths.size() == DstPaths.size());
+ auto minSize = Min(SrcPaths.size(), DstPaths.size());
+ for (size_t i = 0; i < minSize; ++i) {
+ result << ", src path: " << SrcPaths[i];
+ result << ", dst path: " << DstPaths[i];
+ }
+ } else {
+ result << ", no path";
+ }
+
+ if (NewOwner) {
+ result << ", set owner: " << NewOwner;
+ }
+
+ for (const auto& acl: AddACL) {
+ result << ", add access: " << acl;
+ }
+
+ for (const auto& acl: RmACL) {
+ result << ", remove access: " << acl;
+ }
+
+ if (ProtoRequest) {
+ result << ", protobuf request: " << ProtoRequest;
+ }
+
+ return result;
+}
+
+}
+}
diff --git a/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h
new file mode 100644
index 0000000000..4829f0a795
--- /dev/null
+++ b/ydb/core/tx/schemeshard/schemeshard_audit_log_fragment.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "schemeshard_identificators.h"
+
+#include <ydb/core/protos/flat_scheme_op.pb.h>
+
+#include <util/generic/string.h>
+#include <util/generic/maybe.h>
+
+namespace NKikimr {
+namespace NSchemeShard {
+
+struct TAuditLogFragment {
+ TString Operation;
+ TMaybe<TString> Path;
+ TVector<TString> SrcPaths;
+ TVector<TString> DstPaths;
+ TVector<TString> AddACL;
+ TVector<TString> RmACL;
+ TMaybe<TString> NewOwner;
+ TMaybe<TString> ProtoRequest;
+
+ TAuditLogFragment(const NKikimrSchemeOp::TModifyScheme& tx);
+
+ void FillACL(const NKikimrSchemeOp::TModifyScheme& tx);
+ void FillPathes(const NKikimrSchemeOp::TModifyScheme& tx);
+
+ TString GetAnyPath() const;
+ TString ToString() const;
+};
+
+
+} // NSchemeShard
+} // NKikimr
diff --git a/ydb/core/tx/schemeshard/schemeshard_path.cpp b/ydb/core/tx/schemeshard/schemeshard_path.cpp
index 1a4c6aa511..a568424a6c 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path.cpp
+++ b/ydb/core/tx/schemeshard/schemeshard_path.cpp
@@ -1080,7 +1080,7 @@ TPath TPath::Root(TSchemeShard* ss) {
return result;
}
-TString TPath::PathString() const { // O(result length) complexity
+TString TPath::PathString() const { //O(1) if resolved, in other case O(result length) complexity
if (!NameParts) {
return TString();
}
@@ -1147,6 +1147,11 @@ TPath TPath::FirstExistedParent() const {
return result;
}
+TString TPath::GetDomainPathString() const {
+ // TODO: not effective because of creating vectors in Init() method. should keep subdomain path somethere in struct TSubDomainInfo
+ return Init(GetPathIdForDomain(), SS).PathString();
+}
+
TSubDomainInfo::TPtr TPath::DomainInfo() const {
Y_VERIFY(!IsEmpty());
Y_VERIFY(Elements.size());
diff --git a/ydb/core/tx/schemeshard/schemeshard_path.h b/ydb/core/tx/schemeshard/schemeshard_path.h
index 2a43e66d50..0593a0f258 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path.h
+++ b/ydb/core/tx/schemeshard/schemeshard_path.h
@@ -12,6 +12,7 @@ namespace NKikimr {
namespace NSchemeShard {
class TSchemeShard;
+struct TPathElement;
class TPath {
private:
@@ -120,6 +121,7 @@ public:
TPath FirstResoledParent() const;
TPath& RiseUntilExisted();
TPath FirstExistedParent() const;
+ TString GetDomainPathString() const;
TSubDomainInfo::TPtr DomainInfo() const;
TPathId GetPathIdForDomain() const;
TPathId GetDomainKey() const;
diff --git a/ydb/core/tx/schemeshard/schemeshard_path_element.cpp b/ydb/core/tx/schemeshard/schemeshard_path_element.cpp
new file mode 100644
index 0000000000..09c225372c
--- /dev/null
+++ b/ydb/core/tx/schemeshard/schemeshard_path_element.cpp
@@ -0,0 +1,352 @@
+#include "schemeshard_path_element.h"
+
+namespace NKikimr {
+namespace NSchemeShard {
+
+TPathElement::TPathElement(TPathId pathId, TPathId parentPathId, TPathId domainPathId, const TString& name, const TString& owner)
+ : PathId(pathId)
+ , ParentPathId(parentPathId)
+ , DomainPathId(domainPathId)
+ , Name(name)
+ , Owner(owner)
+ , UserAttrs(new TUserAttributes(1))
+{}
+
+ui64 TPathElement::GetAliveChildren() const {
+ return AliveChildrenCount;
+}
+
+void TPathElement::SetAliveChildren(ui64 val) {
+ AliveChildrenCount = val;
+}
+
+void TPathElement::IncAliveChildren(ui64 delta) {
+ Y_VERIFY(Max<ui64>() - AliveChildrenCount >= delta);
+ AliveChildrenCount += delta;
+}
+
+void TPathElement::DecAliveChildren(ui64 delta) {
+ Y_VERIFY(AliveChildrenCount >= delta);
+ AliveChildrenCount -= delta;
+}
+
+ui64 TPathElement::GetShardsInside() const {
+ return ShardsInsideCount;
+}
+
+void TPathElement::SetShardsInside(ui64 val) {
+ ShardsInsideCount = val;
+}
+
+void TPathElement::IncShardsInside(ui64 delta) {
+ Y_VERIFY(Max<ui64>() - ShardsInsideCount >= delta);
+ ShardsInsideCount += delta;
+}
+
+void TPathElement::DecShardsInside(ui64 delta) {
+ Y_VERIFY(ShardsInsideCount >= delta);
+ ShardsInsideCount -= delta;
+}
+
+bool TPathElement::IsRoot() const {
+ return PathId.LocalPathId == RootPathId;
+}
+
+bool TPathElement::IsDirectory() const {
+ return PathType == EPathType::EPathTypeDir;
+}
+
+bool TPathElement::IsTableIndex() const {
+ return PathType == EPathType::EPathTypeTableIndex;
+}
+
+bool TPathElement::IsCdcStream() const {
+ return PathType == EPathType::EPathTypeCdcStream;
+}
+
+bool TPathElement::IsTable() const {
+ return PathType == EPathType::EPathTypeTable;
+}
+
+bool TPathElement::IsSolomon() const {
+ return PathType == EPathType::EPathTypeSolomonVolume;
+}
+
+bool TPathElement::IsPQGroup() const {
+ return PathType == EPathType::EPathTypePersQueueGroup;
+}
+
+bool TPathElement::IsDomainRoot() const {
+ return IsSubDomainRoot() || IsExternalSubDomainRoot();
+}
+
+bool TPathElement::IsSubDomainRoot() const {
+ return PathType == EPathType::EPathTypeSubDomain || IsRoot();
+}
+
+bool TPathElement::IsExternalSubDomainRoot() const {
+ return PathType == EPathType::EPathTypeExtSubDomain;
+}
+
+bool TPathElement::IsRtmrVolume() const {
+ return PathType == EPathType::EPathTypeRtmrVolume;
+}
+
+bool TPathElement::IsBlockStoreVolume() const {
+ return PathType == EPathType::EPathTypeBlockStoreVolume;
+}
+
+bool TPathElement::IsFileStore() const {
+ return PathType == EPathType::EPathTypeFileStore;
+}
+
+bool TPathElement::IsKesus() const {
+ return PathType == EPathType::EPathTypeKesus;
+}
+
+bool TPathElement::IsOlapStore() const {
+ return PathType == EPathType::EPathTypeColumnStore;
+}
+
+bool TPathElement::IsColumnTable() const {
+ return PathType == EPathType::EPathTypeColumnTable;
+}
+
+bool TPathElement::IsSequence() const {
+ return PathType == EPathType::EPathTypeSequence;
+}
+
+bool TPathElement::IsReplication() const {
+ return PathType == EPathType::EPathTypeReplication;
+}
+
+bool TPathElement::IsBlobDepot() const {
+ return PathType == EPathType::EPathTypeBlobDepot;
+}
+
+bool TPathElement::IsContainer() const {
+ return PathType == EPathType::EPathTypeDir || PathType == EPathType::EPathTypeSubDomain
+ || PathType == EPathType::EPathTypeColumnStore;
+}
+
+bool TPathElement::IsLikeDirectory() const {
+ return IsDirectory() || IsDomainRoot() || IsOlapStore();
+}
+
+bool TPathElement::HasActiveChanges() const {
+ // there are old clusters where Root node has CreateTxId == 0
+ return (!IsRoot() && !CreateTxId) || (PathState != EPathState::EPathStateNoChanges);
+}
+
+bool TPathElement::IsCreateFinished() const {
+ return (IsRoot() && CreateTxId) || StepCreated;
+}
+
+TGlobalTimestamp TPathElement::GetCreateTS() const {
+ return TGlobalTimestamp(StepCreated, CreateTxId);
+}
+
+TGlobalTimestamp TPathElement::GetDropTS() const {
+ return TGlobalTimestamp(StepDropped, DropTxId);
+}
+
+void TPathElement::SetDropped(TStepId step, TTxId txId) {
+ PathState = EPathState::EPathStateNotExist;
+ StepDropped = step;
+ DropTxId = txId;
+}
+
+bool TPathElement::NormalState() const {
+ return PathState == EPathState::EPathStateNoChanges;
+}
+
+bool TPathElement::Dropped() const {
+ if (StepDropped) {
+ Y_VERIFY_DEBUG_S(PathState == EPathState::EPathStateNotExist,
+ "Non consistent PathState and StepDropped."
+ << " PathState: " << NKikimrSchemeOp::EPathState_Name(PathState)
+ << ", StepDropped: " << StepDropped
+ << ", PathId: " << PathId);
+ }
+ return bool(StepDropped);
+}
+
+bool TPathElement::IsMigrated() const {
+ return PathState == EPathState::EPathStateMigrated;
+}
+
+bool TPathElement::IsUnderMoving() const {
+ return PathState == EPathState::EPathStateMoving;
+}
+
+bool TPathElement::IsUnderCreating() const {
+ return PathState == EPathState::EPathStateCreate;
+}
+
+bool TPathElement::PlannedToCreate() const {
+ return PathState == EPathState::EPathStateCreate;
+}
+
+bool TPathElement::PlannedToDrop() const {
+ return PathState == EPathState::EPathStateDrop;
+}
+
+bool TPathElement::AddChild(const TString& name, TPathId pathId, bool replace) {
+ TPathId* ptr = FindChild(name);
+ if (ptr && !replace)
+ return false;
+ Children[name] = pathId;
+ return true;
+}
+
+bool TPathElement::RemoveChild(const TString& name, TPathId pathId) {
+ auto it = Children.find(name);
+ if (it != Children.end() && it->second == pathId) {
+ Children.erase(it);
+ return true;
+ }
+ return false;
+}
+
+TPathId* TPathElement::FindChild(const TString& name) {
+ return Children.FindPtr(name);
+}
+
+const TPathElement::TChildrenCont& TPathElement::GetChildren() const {
+ return Children;
+}
+
+void TPathElement::SwapChildren(TChildrenCont& container) {
+ container.swap(Children);
+}
+
+void TPathElement::ApplyACL(const TString& acl) {
+ NACLib::TACL secObj(ACL);
+ NACLib::TDiffACL diffACL(acl);
+ secObj.ApplyDiff(diffACL);
+ ACL = secObj.SerializeAsString();
+}
+
+void TPathElement::ApplySpecialAttributes() {
+ VolumeSpaceRaw.Limit = Max<ui64>();
+ VolumeSpaceSSD.Limit = Max<ui64>();
+ VolumeSpaceHDD.Limit = Max<ui64>();
+ VolumeSpaceSSDNonrepl.Limit = Max<ui64>();
+ VolumeSpaceSSDSystem.Limit = Max<ui64>();
+ ExtraPathSymbolsAllowed = TString();
+ for (const auto& item : UserAttrs->Attrs) {
+ switch (TUserAttributes::ParseName(item.first)) {
+ case EAttribute::VOLUME_SPACE_LIMIT:
+ HandleAttributeValue(item.second, VolumeSpaceRaw.Limit);
+ break;
+ case EAttribute::VOLUME_SPACE_LIMIT_SSD:
+ HandleAttributeValue(item.second, VolumeSpaceSSD.Limit);
+ break;
+ case EAttribute::VOLUME_SPACE_LIMIT_HDD:
+ HandleAttributeValue(item.second, VolumeSpaceHDD.Limit);
+ break;
+ case EAttribute::VOLUME_SPACE_LIMIT_SSD_NONREPL:
+ HandleAttributeValue(item.second, VolumeSpaceSSDNonrepl.Limit);
+ break;
+ case EAttribute::VOLUME_SPACE_LIMIT_SSD_SYSTEM:
+ HandleAttributeValue(item.second, VolumeSpaceSSDSystem.Limit);
+ break;
+ case EAttribute::EXTRA_PATH_SYMBOLS_ALLOWED:
+ HandleAttributeValue(item.second, ExtraPathSymbolsAllowed);
+ break;
+ case EAttribute::DOCUMENT_API_VERSION:
+ HandleAttributeValue(item.second, DocumentApiVersion);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void TPathElement::HandleAttributeValue(const TString& value, TString& target) {
+ target = value;
+}
+
+void TPathElement::HandleAttributeValue(const TString& value, ui64& target) {
+ ui64 parsed;
+ if (TryFromString(value, parsed)) {
+ target = parsed;
+ }
+}
+
+void TPathElement::ChangeVolumeSpaceBegin(TVolumeSpace newSpace, TVolumeSpace oldSpace) {
+ auto update = [](TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue) {
+ if (newValue > oldValue) {
+ // Volume space increase is handled at tx begin
+ limits.Allocated += newValue - oldValue;
+ }
+ };
+ update(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw);
+ update(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD);
+ update(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD);
+ update(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl);
+ update(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem);
+}
+
+void TPathElement::ChangeVolumeSpaceCommit(TVolumeSpace newSpace, TVolumeSpace oldSpace) {
+ auto update = [](TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue) {
+ if (newValue < oldValue) {
+ // Volume space decrease is handled at tx commit
+ ui64 diff = oldValue - newValue;
+ Y_VERIFY(limits.Allocated >= diff);
+ limits.Allocated -= diff;
+ }
+ };
+ update(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw);
+ update(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD);
+ update(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD);
+ update(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl);
+ update(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem);
+}
+
+bool TPathElement::CheckVolumeSpaceChange(TVolumeSpace newSpace, TVolumeSpace oldSpace, TString& errStr) {
+ auto check = [&errStr](const TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue, const char* suffix) -> bool {
+ if (newValue > oldValue) {
+ ui64 newAllocated = limits.Allocated + newValue - oldValue;
+ if (newAllocated > limits.Limit) {
+ errStr = TStringBuilder()
+ << "New volume space is over a limit" << suffix
+ << ": " << newAllocated << " > " << limits.Limit;
+ return false;
+ }
+ }
+ return true;
+ };
+ return (check(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw, "") &&
+ check(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD, " (ssd)") &&
+ check(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD, " (hdd)") &&
+ check(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl, " (ssd_nonrepl)") &&
+ check(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem, " (ssd_system)"));
+}
+
+bool TPathElement::HasRuntimeAttrs() const {
+ return (VolumeSpaceRaw.Allocated > 0 ||
+ VolumeSpaceSSD.Allocated > 0 ||
+ VolumeSpaceHDD.Allocated > 0 ||
+ VolumeSpaceSSDNonrepl.Allocated > 0 ||
+ VolumeSpaceSSDSystem.Allocated > 0);
+}
+
+void TPathElement::SerializeRuntimeAttrs(
+ google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TUserAttribute>* userAttrs) const
+{
+ auto process = [userAttrs](const TVolumeSpaceLimits& limits, const char* name) {
+ if (limits.Allocated > 0) {
+ auto* attr = userAttrs->Add();
+ attr->SetKey(name);
+ attr->SetValue(TStringBuilder() << limits.Allocated);
+ }
+ };
+ process(VolumeSpaceRaw, "__volume_space_allocated");
+ process(VolumeSpaceSSD, "__volume_space_allocated_ssd");
+ process(VolumeSpaceHDD, "__volume_space_allocated_hdd");
+ process(VolumeSpaceSSDNonrepl, "__volume_space_allocated_ssd_nonrepl");
+ process(VolumeSpaceSSDSystem, "__volume_space_allocated_ssd_system");
+}
+}
+}
diff --git a/ydb/core/tx/schemeshard/schemeshard_path_element.h b/ydb/core/tx/schemeshard/schemeshard_path_element.h
index 6fd2fbc313..499f661130 100644
--- a/ydb/core/tx/schemeshard/schemeshard_path_element.h
+++ b/ydb/core/tx/schemeshard/schemeshard_path_element.h
@@ -16,6 +16,8 @@
namespace NKikimr {
namespace NSchemeShard {
+class TPath;
+
constexpr TStringBuf ATTR_PREFIX = "__";
constexpr TStringBuf ATTR_VOLUME_SPACE_LIMIT = "__volume_space_limit";
constexpr TStringBuf ATTR_VOLUME_SPACE_LIMIT_HDD = "__volume_space_limit_hdd";
@@ -341,354 +343,63 @@ private:
ui64 AliveChildrenCount = 0;
ui64 ShardsInsideCount = 0;
TChildrenCont Children;
-
public:
- TPathElement(TPathId pathId, TPathId parentPathId, TPathId domainPathId, const TString& name, const TString& owner)
- : PathId(pathId)
- , ParentPathId(parentPathId)
- , DomainPathId(domainPathId)
- , Name(name)
- , Owner(owner)
- , UserAttrs(new TUserAttributes(1))
- {}
-
- ui64 GetAliveChildren() const {
- return AliveChildrenCount;
- }
-
- void SetAliveChildren(ui64 val) {
- AliveChildrenCount = val;
- }
-
- void IncAliveChildren(ui64 delta = 1) {
- Y_VERIFY(Max<ui64>() - AliveChildrenCount >= delta);
- AliveChildrenCount += delta;
- }
-
- void DecAliveChildren(ui64 delta = 1) {
- Y_VERIFY(AliveChildrenCount >= delta);
- AliveChildrenCount -= delta;
- }
-
- ui64 GetShardsInside() const {
- return ShardsInsideCount;
- }
-
- void SetShardsInside(ui64 val) {
- ShardsInsideCount = val;
- }
-
- void IncShardsInside(ui64 delta = 1) {
- Y_VERIFY(Max<ui64>() - ShardsInsideCount >= delta);
- ShardsInsideCount += delta;
- }
-
- void DecShardsInside(ui64 delta = 1) {
- Y_VERIFY(ShardsInsideCount >= delta);
- ShardsInsideCount -= delta;
- }
-
- bool IsRoot() const {
- return PathId.LocalPathId == RootPathId;
- }
-
- bool IsDirectory() const {
- return PathType == EPathType::EPathTypeDir;
- }
-
- bool IsTableIndex() const {
- return PathType == EPathType::EPathTypeTableIndex;
- }
-
- bool IsCdcStream() const {
- return PathType == EPathType::EPathTypeCdcStream;
- }
-
- bool IsTable() const {
- return PathType == EPathType::EPathTypeTable;
- }
-
- bool IsSolomon() const {
- return PathType == EPathType::EPathTypeSolomonVolume;
- }
-
- bool IsPQGroup() const {
- return PathType == EPathType::EPathTypePersQueueGroup;
- }
-
- bool IsDomainRoot() const {
- return IsSubDomainRoot() || IsExternalSubDomainRoot();
- }
-
- bool IsSubDomainRoot() const {
- return PathType == EPathType::EPathTypeSubDomain || IsRoot();
- }
-
- bool IsExternalSubDomainRoot() const {
- return PathType == EPathType::EPathTypeExtSubDomain;
- }
-
- bool IsRtmrVolume() const {
- return PathType == EPathType::EPathTypeRtmrVolume;
- }
-
- bool IsBlockStoreVolume() const {
- return PathType == EPathType::EPathTypeBlockStoreVolume;
- }
-
- bool IsFileStore() const {
- return PathType == EPathType::EPathTypeFileStore;
- }
-
- bool IsKesus() const {
- return PathType == EPathType::EPathTypeKesus;
- }
-
- bool IsOlapStore() const {
- return PathType == EPathType::EPathTypeColumnStore;
- }
-
- bool IsColumnTable() const {
- return PathType == EPathType::EPathTypeColumnTable;
- }
-
- bool IsSequence() const {
- return PathType == EPathType::EPathTypeSequence;
- }
-
- bool IsReplication() const {
- return PathType == EPathType::EPathTypeReplication;
- }
-
- bool IsBlobDepot() const {
- return PathType == EPathType::EPathTypeBlobDepot;
- }
-
- bool IsContainer() const {
- return PathType == EPathType::EPathTypeDir || PathType == EPathType::EPathTypeSubDomain
- || PathType == EPathType::EPathTypeColumnStore;
- }
-
- bool IsLikeDirectory() const {
- return IsDirectory() || IsDomainRoot() || IsOlapStore();
- }
-
- bool HasActiveChanges() const {
- // there are old clusters where Root node has CreateTxId == 0
- return (!IsRoot() && !CreateTxId) || (PathState != EPathState::EPathStateNoChanges);
- }
-
- bool IsCreateFinished() const {
- return (IsRoot() && CreateTxId) || StepCreated;
- }
-
- TGlobalTimestamp GetCreateTS() const {
- return TGlobalTimestamp(StepCreated, CreateTxId);
- }
-
- TGlobalTimestamp GetDropTS() const {
- return TGlobalTimestamp(StepDropped, DropTxId);
- }
-
- void SetDropped(TStepId step, TTxId txId) {
- PathState = EPathState::EPathStateNotExist;
- StepDropped = step;
- DropTxId = txId;
- }
-
- bool NormalState() const {
- return PathState == EPathState::EPathStateNoChanges;
- }
-
- bool Dropped() const {
- if (StepDropped) {
- Y_VERIFY_DEBUG_S(PathState == EPathState::EPathStateNotExist,
- "Non consistent PathState and StepDropped."
- << " PathState: " << NKikimrSchemeOp::EPathState_Name(PathState)
- << ", StepDropped: " << StepDropped
- << ", PathId: " << PathId);
- }
- return bool(StepDropped);
- }
-
- bool IsMigrated() const {
- return PathState == EPathState::EPathStateMigrated;
- }
-
- bool IsUnderMoving() const {
- return PathState == EPathState::EPathStateMoving;
- }
-
- bool IsUnderCreating() const {
- return PathState == EPathState::EPathStateCreate;
- }
-
- bool PlannedToCreate() const {
- return PathState == EPathState::EPathStateCreate;
- }
-
- bool PlannedToDrop() const {
- return PathState == EPathState::EPathStateDrop;
- }
-
- bool AddChild(const TString& name, TPathId pathId, bool replace = false) {
- TPathId* ptr = FindChild(name);
- if (ptr && !replace)
- return false;
- Children[name] = pathId;
- return true;
- }
-
- bool RemoveChild(const TString& name, TPathId pathId) {
- auto it = Children.find(name);
- if (it != Children.end() && it->second == pathId) {
- Children.erase(it);
- return true;
- }
- return false;
- }
-
- TPathId* FindChild(const TString& name) {
- return Children.FindPtr(name);
- }
-
- const TChildrenCont& GetChildren() const {
- return Children;
- }
-
- void SwapChildren(TChildrenCont& container) {
- container.swap(Children);
- }
-
- void ApplyACL(const TString& acl) {
- NACLib::TACL secObj(ACL);
- NACLib::TDiffACL diffACL(acl);
- secObj.ApplyDiff(diffACL);
- ACL = secObj.SerializeAsString();
- }
-
- void ApplySpecialAttributes() {
- VolumeSpaceRaw.Limit = Max<ui64>();
- VolumeSpaceSSD.Limit = Max<ui64>();
- VolumeSpaceHDD.Limit = Max<ui64>();
- VolumeSpaceSSDNonrepl.Limit = Max<ui64>();
- VolumeSpaceSSDSystem.Limit = Max<ui64>();
- ExtraPathSymbolsAllowed = TString();
- for (const auto& item : UserAttrs->Attrs) {
- switch (TUserAttributes::ParseName(item.first)) {
- case EAttribute::VOLUME_SPACE_LIMIT:
- HandleAttributeValue(item.second, VolumeSpaceRaw.Limit);
- break;
- case EAttribute::VOLUME_SPACE_LIMIT_SSD:
- HandleAttributeValue(item.second, VolumeSpaceSSD.Limit);
- break;
- case EAttribute::VOLUME_SPACE_LIMIT_HDD:
- HandleAttributeValue(item.second, VolumeSpaceHDD.Limit);
- break;
- case EAttribute::VOLUME_SPACE_LIMIT_SSD_NONREPL:
- HandleAttributeValue(item.second, VolumeSpaceSSDNonrepl.Limit);
- break;
- case EAttribute::VOLUME_SPACE_LIMIT_SSD_SYSTEM:
- HandleAttributeValue(item.second, VolumeSpaceSSDSystem.Limit);
- break;
- case EAttribute::EXTRA_PATH_SYMBOLS_ALLOWED:
- HandleAttributeValue(item.second, ExtraPathSymbolsAllowed);
- break;
- case EAttribute::DOCUMENT_API_VERSION:
- HandleAttributeValue(item.second, DocumentApiVersion);
- break;
- default:
- break;
- }
- }
- }
-
- void HandleAttributeValue(const TString& value, TString& target) {
- target = value;
- }
-
- void HandleAttributeValue(const TString& value, ui64& target) {
- ui64 parsed;
- if (TryFromString(value, parsed)) {
- target = parsed;
- }
- }
-
- void ChangeVolumeSpaceBegin(TVolumeSpace newSpace, TVolumeSpace oldSpace) {
- auto update = [](TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue) {
- if (newValue > oldValue) {
- // Volume space increase is handled at tx begin
- limits.Allocated += newValue - oldValue;
- }
- };
- update(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw);
- update(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD);
- update(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD);
- update(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl);
- update(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem);
- }
-
- void ChangeVolumeSpaceCommit(TVolumeSpace newSpace, TVolumeSpace oldSpace) {
- auto update = [](TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue) {
- if (newValue < oldValue) {
- // Volume space decrease is handled at tx commit
- ui64 diff = oldValue - newValue;
- Y_VERIFY(limits.Allocated >= diff);
- limits.Allocated -= diff;
- }
- };
- update(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw);
- update(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD);
- update(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD);
- update(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl);
- update(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem);
- }
-
- bool CheckVolumeSpaceChange(TVolumeSpace newSpace, TVolumeSpace oldSpace, TString& errStr) {
- auto check = [&errStr](const TVolumeSpaceLimits& limits, ui64 newValue, ui64 oldValue, const char* suffix) -> bool {
- if (newValue > oldValue) {
- ui64 newAllocated = limits.Allocated + newValue - oldValue;
- if (newAllocated > limits.Limit) {
- errStr = TStringBuilder()
- << "New volume space is over a limit" << suffix
- << ": " << newAllocated << " > " << limits.Limit;
- return false;
- }
- }
- return true;
- };
- return (check(VolumeSpaceRaw, newSpace.Raw, oldSpace.Raw, "") &&
- check(VolumeSpaceSSD, newSpace.SSD, oldSpace.SSD, " (ssd)") &&
- check(VolumeSpaceHDD, newSpace.HDD, oldSpace.HDD, " (hdd)") &&
- check(VolumeSpaceSSDNonrepl, newSpace.SSDNonrepl, oldSpace.SSDNonrepl, " (ssd_nonrepl)") &&
- check(VolumeSpaceSSDSystem, newSpace.SSDSystem, oldSpace.SSDSystem, " (ssd_system)"));
- }
-
- bool HasRuntimeAttrs() const {
- return (VolumeSpaceRaw.Allocated > 0 ||
- VolumeSpaceSSD.Allocated > 0 ||
- VolumeSpaceHDD.Allocated > 0 ||
- VolumeSpaceSSDNonrepl.Allocated > 0 ||
- VolumeSpaceSSDSystem.Allocated > 0);
- }
-
- void SerializeRuntimeAttrs(
- google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TUserAttribute>* userAttrs) const
- {
- auto process = [userAttrs](const TVolumeSpaceLimits& limits, const char* name) {
- if (limits.Allocated > 0) {
- auto* attr = userAttrs->Add();
- attr->SetKey(name);
- attr->SetValue(TStringBuilder() << limits.Allocated);
- }
- };
- process(VolumeSpaceRaw, "__volume_space_allocated");
- process(VolumeSpaceSSD, "__volume_space_allocated_ssd");
- process(VolumeSpaceHDD, "__volume_space_allocated_hdd");
- process(VolumeSpaceSSDNonrepl, "__volume_space_allocated_ssd_nonrepl");
- process(VolumeSpaceSSDSystem, "__volume_space_allocated_ssd_system");
- }
-
+ TPathElement(TPathId pathId, TPathId parentPathId, TPathId domainPathId, const TString& name, const TString& owner);
+ ui64 GetAliveChildren() const;
+ void SetAliveChildren(ui64 val);
+ void IncAliveChildren(ui64 delta = 1);
+ void DecAliveChildren(ui64 delta = 1);
+ ui64 GetShardsInside() const;
+ void SetShardsInside(ui64 val);
+ void IncShardsInside(ui64 delta = 1);
+ void DecShardsInside(ui64 delta = 1);
+ bool IsRoot() const;
+ bool IsDirectory() const;
+ bool IsTableIndex() const;
+ bool IsCdcStream() const;
+ bool IsTable() const;
+ bool IsSolomon() const;
+ bool IsPQGroup() const;
+ bool IsDomainRoot() const;
+ bool IsSubDomainRoot() const;
+ bool IsExternalSubDomainRoot() const;
+ bool IsRtmrVolume() const;
+ bool IsBlockStoreVolume() const;
+ bool IsFileStore() const;
+ bool IsKesus() const;
+ bool IsOlapStore() const;
+ bool IsColumnTable() const;
+ bool IsSequence() const;
+ bool IsReplication() const;
+ bool IsBlobDepot() const;
+ bool IsContainer() const;
+ bool IsLikeDirectory() const;
+ bool HasActiveChanges() const;
+ bool IsCreateFinished() const;
+ TGlobalTimestamp GetCreateTS() const;
+ TGlobalTimestamp GetDropTS() const;
+ void SetDropped(TStepId step, TTxId txId);
+ bool NormalState() const;
+ bool Dropped() const;
+ bool IsMigrated() const;
+ bool IsUnderMoving() const;
+ bool IsUnderCreating() const;
+ bool PlannedToCreate() const;
+ bool PlannedToDrop() const;
+ bool AddChild(const TString& name, TPathId pathId, bool replace = false);
+ bool RemoveChild(const TString& name, TPathId pathId);
+ TPathId* FindChild(const TString& name);
+ const TChildrenCont& GetChildren() const;
+ void SwapChildren(TChildrenCont& container);
+ void ApplyACL(const TString& acl);
+ void ApplySpecialAttributes();
+ void HandleAttributeValue(const TString& value, TString& target);
+ void HandleAttributeValue(const TString& value, ui64& target);
+ void ChangeVolumeSpaceBegin(TVolumeSpace newSpace, TVolumeSpace oldSpace);
+ void ChangeVolumeSpaceCommit(TVolumeSpace newSpace, TVolumeSpace oldSpace);
+ bool CheckVolumeSpaceChange(TVolumeSpace newSpace, TVolumeSpace oldSpace, TString& errStr);
+ bool HasRuntimeAttrs() const;
+ void SerializeRuntimeAttrs(google::protobuf::RepeatedPtrField<NKikimrSchemeOp::TUserAttribute>* userAttrs) const;
};
}
}