@@ -382,6 +382,9 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
382
382
std::move (columnsMetadata),
383
383
std::move (writeIndexes),
384
384
priority);
385
+
386
+ // At current time only insert operation can fail.
387
+ NeedToFlushBeforeCommit |= (operationType == NKikimrDataEvents::TEvWrite::TOperation::OPERATION_INSERT);
385
388
CA_LOG_D (" Open: token=" << token);
386
389
}
387
390
@@ -413,6 +416,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
413
416
void CleanupClosedTokens () {
414
417
YQL_ENSURE (ShardedWriteController);
415
418
ShardedWriteController->CleanupClosedTokens ();
419
+ NeedToFlushBeforeCommit = false ;
416
420
}
417
421
418
422
void SetParentTraceId (NWilson::TTraceId traceId) {
@@ -1297,6 +1301,10 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
1297
1301
Stats.FillStats (stats, TablePath);
1298
1302
}
1299
1303
1304
+ bool FlushBeforeCommit () const {
1305
+ return NeedToFlushBeforeCommit;
1306
+ }
1307
+
1300
1308
private:
1301
1309
NActors::TActorId PipeCacheId = NKikimr::MakePipePerNodeCacheID(false );
1302
1310
bool LinkedPipeCache = false ;
@@ -1326,6 +1334,7 @@ class TKqpTableWriteActor : public TActorBootstrapped<TKqpTableWriteActor> {
1326
1334
1327
1335
IKqpTransactionManagerPtr TxManager;
1328
1336
bool Closed = false ;
1337
+ bool NeedToFlushBeforeCommit = false ;
1329
1338
EMode Mode = EMode::WRITE;
1330
1339
THashMap<ui64, TInstant> SendTime;
1331
1340
@@ -1662,7 +1671,6 @@ class TKqpDirectWriteActor : public TActorBootstrapped<TKqpDirectWriteActor>, pu
1662
1671
TKqpTableWriteActor::TWriteToken WriteToken = 0 ;
1663
1672
1664
1673
bool Closed = false ;
1665
-
1666
1674
bool WaitingForTableActor = false ;
1667
1675
1668
1676
NWilson::TSpan DirectWriteActorSpan;
@@ -1909,9 +1917,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1909
1917
settings.Priority );
1910
1918
}
1911
1919
1912
- // At current time only insert operation can fail.
1913
- NeedToFlushBeforeCommit |= (settings.OperationType == NKikimrDataEvents::TEvWrite::TOperation::OPERATION_INSERT);
1914
-
1915
1920
writeInfo.Actors .at (settings.TableId .PathId ).WriteActor ->Open (
1916
1921
token.Cookie ,
1917
1922
settings.OperationType ,
@@ -1935,6 +1940,23 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1935
1940
Process ();
1936
1941
}
1937
1942
1943
+ bool NeedToFlush () {
1944
+ const bool outOfMemory = GetTotalFreeSpace () <= 0 ;
1945
+ const bool needToFlush = outOfMemory
1946
+ || State == EState::FLUSHING
1947
+ || State == EState::PREPARING
1948
+ || State == EState::COMMITTING
1949
+ || State == EState::ROLLINGBACK;
1950
+ return needToFlush;
1951
+ }
1952
+
1953
+ bool NeedToFlushActor (const TKqpTableWriteActor* actor) {
1954
+ return NeedToFlush ()
1955
+ && (State != EState::FLUSHING
1956
+ || !TxId // Flush between queries
1957
+ || actor->FlushBeforeCommit ()); // Flush before commit
1958
+ }
1959
+
1938
1960
bool Process () {
1939
1961
ProcessRequestQueue ();
1940
1962
if (!ProcessFlush ()) {
@@ -1945,7 +1967,9 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
1945
1967
if (State == EState::FLUSHING) {
1946
1968
bool isEmpty = true ;
1947
1969
ForEachWriteActor ([&](const TKqpTableWriteActor* actor, const TActorId) {
1948
- isEmpty &= actor->IsReady () && actor->IsEmpty ();
1970
+ if (NeedToFlushActor (actor)) {
1971
+ isEmpty &= actor->IsReady () && actor->IsEmpty ();
1972
+ }
1949
1973
});
1950
1974
if (isEmpty) {
1951
1975
OnFlushed ();
@@ -2014,14 +2038,7 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2014
2038
}
2015
2039
2016
2040
bool ProcessFlush () {
2017
- const bool outOfMemory = GetTotalFreeSpace () <= 0 ;
2018
- const bool needToFlush = outOfMemory
2019
- || State == EState::FLUSHING
2020
- || State == EState::PREPARING
2021
- || State == EState::COMMITTING
2022
- || State == EState::ROLLINGBACK;
2023
-
2024
- if (!EnableStreamWrite && outOfMemory) {
2041
+ if (!EnableStreamWrite && GetTotalFreeSpace () <= 0 ) {
2025
2042
ReplyErrorAndDie (
2026
2043
NYql::NDqProto::StatusIds::PRECONDITION_FAILED,
2027
2044
NYql::TIssuesIds::KIKIMR_PRECONDITION_FAILED,
@@ -2031,12 +2048,12 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2031
2048
return false ;
2032
2049
}
2033
2050
2034
- if (needToFlush ) {
2051
+ if (NeedToFlush () ) {
2035
2052
CA_LOG_D (" Flush data" );
2036
2053
2037
2054
bool flushFailed = false ;
2038
2055
ForEachWriteActor ([&](TKqpTableWriteActor* actor, const TActorId) {
2039
- if (!flushFailed && actor->IsReady ()) {
2056
+ if (!flushFailed && actor->IsReady () && NeedToFlushActor (actor) ) {
2040
2057
actor->FlushBuffers ();
2041
2058
if (!actor->FlushToShards ()) {
2042
2059
flushFailed = true ;
@@ -2069,11 +2086,11 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2069
2086
2070
2087
CA_LOG_D (" Start prepare for distributed commit" );
2071
2088
YQL_ENSURE (State == EState::WRITING);
2072
- YQL_ENSURE (!NeedToFlushBeforeCommit);
2073
2089
State = EState::PREPARING;
2074
2090
CheckQueuesEmpty ();
2075
2091
AFL_ENSURE (TxId);
2076
2092
ForEachWriteActor ([&](TKqpTableWriteActor* actor, const TActorId) {
2093
+ AFL_ENSURE (!actor->FlushBeforeCommit ());
2077
2094
actor->SetPrepare (*TxId);
2078
2095
});
2079
2096
Close ();
@@ -2517,7 +2534,13 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2517
2534
} else {
2518
2535
AFL_ENSURE (ev->Get ()->TxId );
2519
2536
TxId = ev->Get ()->TxId ;
2520
- if (NeedToFlushBeforeCommit) {
2537
+
2538
+ bool needToFlushBeforeCommit = false ;
2539
+ ForEachWriteActor ([&](TKqpTableWriteActor* actor, const TActorId) {
2540
+ needToFlushBeforeCommit |= actor->FlushBeforeCommit ();
2541
+ });
2542
+
2543
+ if (needToFlushBeforeCommit) {
2521
2544
Flush (std::move (ev->TraceId ));
2522
2545
} else {
2523
2546
TxManager->StartPrepare ();
@@ -2902,8 +2925,19 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2902
2925
UpdateTracingState (" Write" , BufferWriteActorSpan.GetTraceId ());
2903
2926
OnOperationFinished (Counters->BufferActorFlushLatencyHistogram );
2904
2927
State = EState::WRITING;
2905
- AFL_ENSURE (!TxId || NeedToFlushBeforeCommit); // TxId => NeedToFlushBeforeCommit
2906
- NeedToFlushBeforeCommit = false ;
2928
+
2929
+ ForEachWriteActor ([&](TKqpTableWriteActor* actor, const TActorId) {
2930
+ AFL_ENSURE (TxId || actor->IsEmpty ());
2931
+ if (actor->IsEmpty ()) {
2932
+ actor->CleanupClosedTokens ();
2933
+ }
2934
+ if (!TxId) {
2935
+ actor->Unlink ();
2936
+ }
2937
+
2938
+ AFL_ENSURE (!actor->FlushBeforeCommit ());
2939
+ });
2940
+
2907
2941
if (TxId) {
2908
2942
TxManager->StartPrepare ();
2909
2943
Prepare (std::nullopt);
@@ -2915,11 +2949,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
2915
2949
});
2916
2950
ExecuterActorId = {};
2917
2951
Y_ABORT_UNLESS (GetTotalMemory () == 0 );
2918
-
2919
- ForEachWriteActor ([&](TKqpTableWriteActor* actor, const TActorId) {
2920
- actor->CleanupClosedTokens ();
2921
- actor->Unlink ();
2922
- });
2923
2952
}
2924
2953
2925
2954
void OnError (NYql::NDqProto::StatusIds::StatusCode statusCode, NYql::EYqlIssueCode id, const TString& message, const NYql::TIssues& subIssues) override {
@@ -3059,7 +3088,6 @@ class TKqpBufferWriteActor :public TActorBootstrapped<TKqpBufferWriteActor>, pub
3059
3088
3060
3089
EState State;
3061
3090
bool HasError = false ;
3062
- bool NeedToFlushBeforeCommit = false ;
3063
3091
THashMap<TPathId, std::queue<TBufferWriteMessage>> RequestQueues;
3064
3092
3065
3093
struct TAckMessage {
0 commit comments