@@ -5918,6 +5918,78 @@ Y_UNIT_TEST_SUITE(DataShardSnapshots) {
59185918 runtime.SimulateSleep (TDuration::Seconds (1 ));
59195919 }
59205920
5921+ Y_UNIT_TEST (ShardRestartAfterDropTableAndAbort) {
5922+ TPortManager pm;
5923+ TServerSettings serverSettings (pm.GetPort (2134 ));
5924+ serverSettings.SetDomainName (" Root" )
5925+ .SetUseRealThreads (false )
5926+ .SetDomainPlanResolution (100 );
5927+
5928+ // The bug was discovered in 24-4 that doesn't have in-memory state migration
5929+ serverSettings.FeatureFlags .SetEnableDataShardInMemoryStateMigration (false );
5930+
5931+ Tests::TServer::TPtr server = new TServer (serverSettings);
5932+ auto &runtime = *server->GetRuntime ();
5933+ auto sender = runtime.AllocateEdgeActor ();
5934+
5935+ runtime.SetLogPriority (NKikimrServices::TX_DATASHARD, NLog::PRI_TRACE);
5936+
5937+ InitRoot (server, sender);
5938+
5939+ TDisableDataShardLogBatching disableDataShardLogBatching;
5940+
5941+ UNIT_ASSERT_VALUES_EQUAL (
5942+ KqpSchemeExec (runtime, R"(
5943+ CREATE TABLE `/Root/table` (key Uint32, value Uint32, PRIMARY KEY (key));
5944+ )" ),
5945+ " SUCCESS" );
5946+
5947+ const auto shards = GetTableShards (server, sender, " /Root/table" );
5948+ UNIT_ASSERT_VALUES_EQUAL (shards.size (), 1u );
5949+
5950+ ExecSQL (server, sender, " UPSERT INTO `/Root/table` (key, value) VALUES (1, 11);" );
5951+
5952+ TString sessionId, txId;
5953+ UNIT_ASSERT_VALUES_EQUAL (
5954+ KqpSimpleBegin (runtime, sessionId, txId, R"(
5955+ UPSERT INTO `/Root/table` (key, value) VALUES (2, 22);
5956+
5957+ SELECT key, value FROM `/Root/table`
5958+ WHERE key <= 5
5959+ ORDER BY key;
5960+ )" ),
5961+ " { items { uint32_value: 1 } items { uint32_value: 11 } }, "
5962+ " { items { uint32_value: 2 } items { uint32_value: 22 } }" );
5963+
5964+ // Copy table (this will prevent shard deletion)
5965+ {
5966+ auto senderCopy = runtime.AllocateEdgeActor ();
5967+ ui64 txId = AsyncCreateCopyTable (server, senderCopy, " /Root" , " table-copy" , " /Root/table" );
5968+ WaitTxNotification (server, senderCopy, txId);
5969+ }
5970+
5971+ // Drop the original table
5972+ {
5973+ auto senderDrop = runtime.AllocateEdgeActor ();
5974+ ui64 txId = AsyncDropTable (server, senderDrop, " /Root" , " table" );
5975+ WaitTxNotification (server, senderDrop, txId);
5976+ }
5977+
5978+ TBlockEvents<TEvLongTxService::TEvLockStatus> blockedLockStatus (runtime);
5979+
5980+ UNIT_ASSERT_VALUES_EQUAL (
5981+ KqpSimpleCommit (runtime, sessionId, txId, " SELECT 1" ),
5982+ " ERROR: UNAVAILABLE" );
5983+
5984+ runtime.WaitFor (" blocked lock status" , [&]{ return blockedLockStatus.size () > 0 ; });
5985+ blockedLockStatus.Stop ().clear ();
5986+
5987+ // Reboot the original table shard and sleep a little
5988+ // The bug was causing shard to crash in RemoveSubscribedLock
5989+ RebootTablet (runtime, shards.at (0 ), sender);
5990+ runtime.SimulateSleep (TDuration::Seconds (1 ));
5991+ }
5992+
59215993 Y_UNIT_TEST (BrokenLockChangesDontLeak) {
59225994 TPortManager pm;
59235995 TServerSettings serverSettings (pm.GetPort (2134 ));
0 commit comments