@@ -4344,134 +4344,6 @@ R"(CREATE TABLE `test_show_create` (
43444344 [[0u]];
43454345 ])" , ysonString);
43464346 }
4347-
4348- Y_UNIT_TEST_TWIN (QueryMetricsLocksBroken, UseSink) {
4349- TTestEnvSettings settings;
4350- settings.EnableSVP = true ;
4351- settings.TableServiceConfig .SetEnableOltpSink (UseSink);
4352- TTestEnv env (1 , 2 , settings);
4353- CreateTenant (env, " Tenant1" , true );
4354-
4355- auto driverConfig = TDriverConfig ()
4356- .SetEndpoint (env.GetEndpoint ())
4357- .SetDiscoveryMode (EDiscoveryMode::Off)
4358- .SetDatabase (" /Root/Tenant1" );
4359- auto driver = TDriver (driverConfig);
4360-
4361- TTableClient client (driver);
4362- auto session = client.CreateSession ().GetValueSync ().GetSession ();
4363- auto victimSession = client.CreateSession ().GetValueSync ().GetSession ();
4364-
4365- // Create table and insert initial data
4366- NKqp::AssertSuccessResult (session.ExecuteSchemeQuery (R"(
4367- CREATE TABLE `/Root/Tenant1/TableLocks` (
4368- Key Uint64,
4369- Value String,
4370- PRIMARY KEY (Key)
4371- );
4372- )" ).GetValueSync ());
4373-
4374- NKqp::AssertSuccessResult (session.ExecuteDataQuery (
4375- " UPSERT INTO `/Root/Tenant1/TableLocks` (Key, Value) VALUES (1u, \" Initial\" )" ,
4376- TTxControl::BeginTx ().CommitTx ()
4377- ).GetValueSync ());
4378-
4379- // Establish locks by reading in a transaction (victim)
4380- std::optional<TTransaction> victimTx;
4381- while (!victimTx) {
4382- auto result = victimSession.ExecuteDataQuery (
4383- " SELECT * FROM `/Root/Tenant1/TableLocks` WHERE Key = 1u /* victim-query */" ,
4384- TTxControl::BeginTx ()
4385- ).ExtractValueSync ();
4386- UNIT_ASSERT_C (result.GetStatus () == EStatus::SUCCESS, result.GetIssues ().ToString ());
4387-
4388- TString yson = FormatResultSetYson (result.GetResultSet (0 ));
4389- if (yson == " []" ) {
4390- continue ; // Data not visible yet, retry
4391- }
4392-
4393- victimTx = result.GetTransaction ();
4394- UNIT_ASSERT (victimTx);
4395- }
4396-
4397- // Breaker transaction: writes to key 1, breaking victim's read lock
4398- NKqp::AssertSuccessResult (session.ExecuteDataQuery (
4399- " UPSERT INTO `/Root/Tenant1/TableLocks` (Key, Value) VALUES (1u, \" BreakerValue\" ) /* lock-breaker */" ,
4400- TTxControl::BeginTx ().CommitTx ()
4401- ).GetValueSync ());
4402-
4403- // Victim tries to commit with write to the same key
4404- // This triggers lock validation, which fails because the lock on key 1 was broken
4405- auto commitResult = victimSession.ExecuteDataQuery (
4406- " UPSERT INTO `/Root/Tenant1/TableLocks` (Key, Value) VALUES (1u, \" VictimValue\" ) /* victim-commit */" ,
4407- TTxControl::Tx (*victimTx).CommitTx ()
4408- ).ExtractValueSync ();
4409-
4410- // Victim should be ABORTED because its locks were broken
4411- UNIT_ASSERT_VALUES_EQUAL (commitResult.GetStatus (), EStatus::ABORTED);
4412-
4413- // Wait for stats to be collected and check both LocksBrokenAsBreaker and LocksBrokenAsVictim
4414- ui64 locksBrokenAsBreaker = 0 ;
4415- ui64 locksBrokenAsVictim = 0 ;
4416- bool foundBreaker = false ;
4417- bool foundVictim = false ;
4418-
4419- for (size_t iter = 0 ; iter < 30 && (!foundBreaker || !foundVictim); ++iter) {
4420- // Query both breaker and victim metrics in one pass
4421- auto it = client.StreamExecuteScanQuery (R"(
4422- SELECT QueryText, LocksBrokenAsBreaker, LocksBrokenAsVictim
4423- FROM `/Root/Tenant1/.sys/query_metrics_one_minute`
4424- WHERE QueryText LIKE '%lock-breaker%' OR QueryText LIKE '%victim-commit%';
4425- )" ).GetValueSync ();
4426-
4427- UNIT_ASSERT_C (it.IsSuccess (), it.GetIssues ().ToString ());
4428- TString ysonString = NKqp::StreamResultToYson (it);
4429- Cerr << " Query metrics result: " << ysonString << Endl;
4430-
4431- auto node = NYT::NodeFromYsonString (ysonString, ::NYson::EYsonType::Node);
4432- UNIT_ASSERT (node.IsList ());
4433-
4434- for (const auto & row : node.AsList ()) {
4435- if (!row.IsList () || row.AsList ().size () < 3 ) continue ;
4436-
4437- auto getStringValue = [](const NYT::TNode& n) -> TString {
4438- if (n.IsList () && !n.AsList ().empty ()) {
4439- return n.AsList ()[0 ].AsString ();
4440- }
4441- return n.AsString ();
4442- };
4443- auto getUint64Value = [](const NYT::TNode& n) -> ui64 {
4444- if (n.IsList () && !n.AsList ().empty ()) {
4445- return n.AsList ()[0 ].AsUint64 ();
4446- }
4447- return n.AsUint64 ();
4448- };
4449-
4450- TString queryText = getStringValue (row.AsList ()[0 ]);
4451- ui64 breaker = getUint64Value (row.AsList ()[1 ]);
4452- ui64 victim = getUint64Value (row.AsList ()[2 ]);
4453-
4454- if (queryText.Contains (" lock-breaker" ) && !queryText.Contains (" query_metrics" )) {
4455- locksBrokenAsBreaker = breaker;
4456- foundBreaker = true ;
4457- }
4458- if (queryText.Contains (" victim-commit" ) && !queryText.Contains (" query_metrics" )) {
4459- locksBrokenAsVictim = victim;
4460- foundVictim = true ;
4461- }
4462- }
4463-
4464- if (!foundBreaker || !foundVictim) {
4465- Sleep (TDuration::Seconds (5 ));
4466- }
4467- }
4468-
4469- UNIT_ASSERT_C (foundBreaker, " Breaker not found in metrics" );
4470- UNIT_ASSERT_C (foundVictim, " Victim not found in metrics" );
4471-
4472- UNIT_ASSERT_VALUES_EQUAL (locksBrokenAsBreaker, 1u );
4473- UNIT_ASSERT_VALUES_EQUAL (locksBrokenAsVictim, 1u );
4474- }
44754347}
44764348
44774349Y_UNIT_TEST_SUITE (ShowCreateView) {
0 commit comments