@@ -325,6 +325,9 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
325
325
std::move (columnsMetadata),
326
326
std::move (writeIndexes),
327
327
priority);
328
+
329
+ // At current time only insert operation can fail.
330
+ NeedToFlushBeforeCommit |= (operationType == NKikimrDataEvents::TEvWrite::TOperation::OPERATION_INSERT);
328
331
CA_LOG_D (" Open: token=" << token);
329
332
return token;
330
333
}
@@ -357,6 +360,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
357
360
void CleanupClosedTokens () {
358
361
YQL_ENSURE (ShardedWriteController);
359
362
ShardedWriteController->CleanupClosedTokens ();
363
+ NeedToFlushBeforeCommit = false ;
360
364
}
361
365
362
366
void SetParentTraceId (NWilson::TTraceId traceId) {
@@ -1276,6 +1280,10 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
1276
1280
Stats.AffectedPartitions .clear ();
1277
1281
}
1278
1282
1283
+ bool FlushBeforeCommit () const {
1284
+ return NeedToFlushBeforeCommit;
1285
+ }
1286
+
1279
1287
private:
1280
1288
NActors::TActorId PipeCacheId = NKikimr::MakePipePerNodeCacheID(false );
1281
1289
@@ -1304,6 +1312,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
1304
1312
1305
1313
IKqpTransactionManagerPtr TxManager;
1306
1314
bool Closed = false ;
1315
+ bool NeedToFlushBeforeCommit = false ;
1307
1316
EMode Mode = EMode::WRITE;
1308
1317
THashMap<ui64, TInstant> SendTime;
1309
1318
@@ -1634,7 +1643,6 @@ class TKqpDirectWriteActor : public TActorBootstrapped<TKqpDirectWriteActor>, pu
1634
1643
std::optional<TKqpTableWriteActor::TWriteToken> WriteToken;
1635
1644
1636
1645
bool Closed = false ;
1637
-
1638
1646
bool WaitingForTableActor = false ;
1639
1647
1640
1648
NWilson::TSpan DirectWriteActorSpan;
@@ -1852,6 +1860,23 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1852
1860
Process ();
1853
1861
}
1854
1862
1863
+ bool NeedToFlush () {
1864
+ const bool outOfMemory = GetTotalFreeSpace () <= 0 ;
1865
+ const bool needToFlush = outOfMemory
1866
+ || State == EState::FLUSHING
1867
+ || State == EState::PREPARING
1868
+ || State == EState::COMMITTING
1869
+ || State == EState::ROLLINGBACK;
1870
+ return needToFlush;
1871
+ }
1872
+
1873
+ bool NeedToFlushActor (const TKqpTableWriteActor* actor) {
1874
+ return NeedToFlush ()
1875
+ && (State != EState::FLUSHING
1876
+ || !TxId // Flush between queries
1877
+ || actor->FlushBeforeCommit ()); // Flush before commit
1878
+ }
1879
+
1855
1880
bool Process () {
1856
1881
ProcessRequestQueue ();
1857
1882
if (!ProcessWrite ()) {
@@ -1862,7 +1887,9 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1862
1887
if (State == EState::FLUSHING) {
1863
1888
bool isEmpty = true ;
1864
1889
for (auto & [_, info] : WriteInfos) {
1865
- isEmpty = isEmpty && info.WriteTableActor ->IsReady () && info.WriteTableActor ->IsEmpty ();
1890
+ if (NeedToFlushActor (actor)) {
1891
+ isEmpty = isEmpty && info.WriteTableActor ->IsReady () && info.WriteTableActor ->IsEmpty ();
1892
+ }
1866
1893
}
1867
1894
if (isEmpty) {
1868
1895
OnFlushed ();
@@ -1916,15 +1943,8 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1916
1943
}
1917
1944
}
1918
1945
1919
- bool ProcessWrite () {
1920
- const bool outOfMemory = GetTotalFreeSpace () <= 0 ;
1921
- const bool needToFlush = outOfMemory
1922
- || State == EState::FLUSHING
1923
- || State == EState::PREPARING
1924
- || State == EState::COMMITTING
1925
- || State == EState::ROLLINGBACK;
1926
-
1927
- if (!EnableStreamWrite && outOfMemory) {
1946
+ bool ProcessFlush () {
1947
+ if (!EnableStreamWrite && GetTotalFreeSpace () <= 0 ) {
1928
1948
ReplyErrorAndDie (
1929
1949
NYql::NDqProto::StatusIds::PRECONDITION_FAILED,
1930
1950
NYql::TIssuesIds::KIKIMR_PRECONDITION_FAILED,
@@ -1934,10 +1954,10 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1934
1954
return false ;
1935
1955
}
1936
1956
1937
- if (needToFlush ) {
1957
+ if (NeedToFlush () ) {
1938
1958
CA_LOG_D (" Flush data" );
1939
1959
for (auto & [_, info] : WriteInfos) {
1940
- if (info.WriteTableActor ->IsReady ()) {
1960
+ if (info.WriteTableActor ->IsReady () && NeedToFlushActor (actor) ) {
1941
1961
if (!info.WriteTableActor ->FlushToShards ()) {
1942
1962
return false ;
1943
1963
}
@@ -1967,13 +1987,13 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1967
1987
1968
1988
CA_LOG_D (" Start prepare for distributed commit" );
1969
1989
YQL_ENSURE (State == EState::WRITING);
1970
- YQL_ENSURE (!NeedToFlushBeforeCommit);
1971
1990
State = EState::PREPARING;
1972
1991
for (auto & [_, queue] : DataQueues) {
1973
1992
YQL_ENSURE (queue.empty ());
1974
1993
}
1975
1994
YQL_ENSURE (TxId);
1976
1995
for (auto & [_, info] : WriteInfos) {
1996
+ AFL_ENSURE (!actor->FlushBeforeCommit ());
1977
1997
info.WriteTableActor ->SetPrepare (*TxId);
1978
1998
}
1979
1999
Close ();
@@ -2427,7 +2447,13 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2427
2447
} else {
2428
2448
AFL_ENSURE (ev->Get ()->TxId );
2429
2449
TxId = ev->Get ()->TxId ;
2430
- if (NeedToFlushBeforeCommit) {
2450
+
2451
+ bool needToFlushBeforeCommit = false ;
2452
+ for (auto & [_, info] : WriteInfos) {
2453
+ needToFlushBeforeCommit |= info.WriteTableActor ->FlushBeforeCommit ();
2454
+ }
2455
+
2456
+ if (needToFlushBeforeCommit) {
2431
2457
Flush (std::move (ev->TraceId ));
2432
2458
} else {
2433
2459
TxManager->StartPrepare ();
@@ -2812,8 +2838,19 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2812
2838
UpdateTracingState (" Write" , BufferWriteActorSpan.GetTraceId ());
2813
2839
OnOperationFinished (Counters->BufferActorFlushLatencyHistogram );
2814
2840
State = EState::WRITING;
2815
- AFL_ENSURE (!TxId || NeedToFlushBeforeCommit); // TxId => NeedToFlushBeforeCommit
2816
- NeedToFlushBeforeCommit = false ;
2841
+
2842
+ for (auto & [_, info] : WriteInfos) {
2843
+ AFL_ENSURE (TxId || info.WriteTableActor ->IsEmpty ());
2844
+ if (info.WriteTableActor ->IsEmpty ()) {
2845
+ info.WriteTableActor ->CleanupClosedTokens ();
2846
+ }
2847
+ if (!TxId) {
2848
+ info.WriteTableActor ->Unlink ();
2849
+ }
2850
+
2851
+ AFL_ENSURE (!info.WriteTableActor ->FlushBeforeCommit ());
2852
+ }
2853
+
2817
2854
if (TxId) {
2818
2855
TxManager->StartPrepare ();
2819
2856
Prepare (std::nullopt);
@@ -2947,7 +2984,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2947
2984
2948
2985
EState State;
2949
2986
bool HasError = false ;
2950
- bool NeedToFlushBeforeCommit = false ;
2951
2987
THashMap<TPathId, std::queue<TBufferWriteMessage>> DataQueues;
2952
2988
2953
2989
struct TAckMessage {
0 commit comments