@@ -82,8 +82,71 @@ class TExecuteWriteUnit : public TExecutionUnit {
82
82
return false ;
83
83
}
84
84
85
- EExecutionStatus OnTabletNotReadyException (TDataShardUserDb& userDb, TWriteOperation& writeOp, TTransactionContext& txc, const TActorContext& ctx) {
85
+ void FillOps (const NTable::TScheme& scheme, const TUserTable& userTable, const NTable::TScheme::TTableInfo& tableInfo, const TValidatedWriteTxOperation& validatedOperation, ui32 rowIdx, TSmallVec<NTable::TUpdateOp>& ops) {
86
+ const TSerializedCellMatrix& matrix = validatedOperation.GetMatrix ();
87
+ const auto & columnIds = validatedOperation.GetColumnIds ();
88
+
89
+ ops.clear ();
90
+ Y_ENSURE (matrix.GetColCount () >= userTable.KeyColumnIds .size ());
91
+ ops.reserve (matrix.GetColCount () - userTable.KeyColumnIds .size ());
92
+
93
+ for (ui16 valueColIdx = userTable.KeyColumnIds .size (); valueColIdx < matrix.GetColCount (); ++valueColIdx) {
94
+ ui32 columnTag = columnIds[valueColIdx];
95
+ const TCell& cell = matrix.GetCell (rowIdx, valueColIdx);
96
+
97
+ const NScheme::TTypeId vtypeId = scheme.GetColumnInfo (&tableInfo, columnTag)->PType .GetTypeId ();
98
+ ops.emplace_back (columnTag, NTable::ECellOp::Set, cell.IsNull () ? TRawTypeValue () : TRawTypeValue (cell.Data (), cell.Size (), vtypeId));
99
+ }
100
+ };
101
+
102
+ void FillKey (const NTable::TScheme& scheme, const TUserTable& userTable, const NTable::TScheme::TTableInfo& tableInfo, const TValidatedWriteTxOperation& validatedOperation, ui32 rowIdx, TSmallVec<TRawTypeValue>& key) {
103
+ const TSerializedCellMatrix& matrix = validatedOperation.GetMatrix ();
104
+
105
+ key.clear ();
106
+ key.reserve (userTable.KeyColumnIds .size ());
107
+ for (ui16 keyColIdx = 0 ; keyColIdx < userTable.KeyColumnIds .size (); ++keyColIdx) {
108
+ const TCell& cell = matrix.GetCell (rowIdx, keyColIdx);
109
+ ui32 keyCol = tableInfo.KeyColumns [keyColIdx];
110
+ if (cell.IsNull ()) {
111
+ key.emplace_back ();
112
+ } else {
113
+ NScheme::TTypeId vtypeId = scheme.GetColumnInfo (&tableInfo, keyCol)->PType .GetTypeId ();
114
+ key.emplace_back (cell.Data (), cell.Size (), vtypeId);
115
+ }
116
+ }
117
+ };
118
+
119
+ EExecutionStatus OnTabletNotReadyException (TDataShardUserDb& userDb, TWriteOperation& writeOp, size_t operationIndexToPrecharge, TTransactionContext& txc, const TActorContext& ctx) {
86
120
LOG_TRACE_S (ctx, NKikimrServices::TX_DATASHARD, " Tablet " << DataShard.TabletID () << " is not ready for " << writeOp << " execution" );
121
+
122
+ // Precharge
123
+ if (operationIndexToPrecharge != SIZE_MAX) {
124
+ const TValidatedWriteTx::TPtr& writeTx = writeOp.GetWriteTx ();
125
+ for (size_t operationIndex = operationIndexToPrecharge; operationIndex < writeTx->GetOperations ().size (); ++operationIndex) {
126
+ const TValidatedWriteTxOperation& validatedOperation = writeTx->GetOperations ()[operationIndex];
127
+ const ui64 tableId = validatedOperation.GetTableId ().PathId .LocalPathId ;
128
+ const TTableId fullTableId (DataShard.GetPathOwnerId (), tableId);
129
+ const TUserTable& userTable = *DataShard.GetUserTables ().at (tableId);
130
+
131
+ const NTable::TScheme& scheme = txc.DB .GetScheme ();
132
+ const NTable::TScheme::TTableInfo& tableInfo = *scheme.GetTableInfo (userTable.LocalTid );
133
+
134
+ const TSerializedCellMatrix& matrix = validatedOperation.GetMatrix ();
135
+ const auto operationType = validatedOperation.GetOperationType ();
136
+
137
+ TSmallVec<TRawTypeValue> key;
138
+
139
+ if (operationType == NKikimrDataEvents::TEvWrite::TOperation::OPERATION_INSERT ||
140
+ operationType == NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPDATE ||
141
+ userDb.NeedToReadBeforeWrite (fullTableId))
142
+ {
143
+ for (ui32 rowIdx = 0 ; rowIdx < matrix.GetRowCount (); ++rowIdx) {
144
+ FillKey (scheme, userTable, tableInfo, validatedOperation, rowIdx, key);
145
+ userDb.PrechargeRow (fullTableId, key);
146
+ }
147
+ }
148
+ }
149
+ }
87
150
88
151
DataShard.IncCounter (COUNTER_TX_TABLET_NOT_READY);
89
152
@@ -107,51 +170,35 @@ class TExecuteWriteUnit : public TExecutionUnit {
107
170
const TUserTable& userTable = *DataShard.GetUserTables ().at (tableId);
108
171
109
172
const NTable::TScheme& scheme = txc.DB .GetScheme ();
110
- const NTable::TScheme::TTableInfo* tableInfo = scheme.GetTableInfo (userTable.LocalTid );
111
-
112
- TSmallVec<TRawTypeValue> key;
113
- TSmallVec<NTable::TUpdateOp> ops;
173
+ const NTable::TScheme::TTableInfo& tableInfo = *scheme.GetTableInfo (userTable.LocalTid );
114
174
115
175
const TSerializedCellMatrix& matrix = validatedOperation.GetMatrix ();
116
176
const auto operationType = validatedOperation.GetOperationType ();
117
177
178
+ <<<<<<< HEAD
118
179
auto fillOps = [&](ui32 rowIdx) {
119
180
ops.clear ();
120
181
Y_ABORT_UNLESS (matrix.GetColCount () >= userTable.KeyColumnIds .size ());
121
182
ops.reserve (matrix.GetColCount () - userTable.KeyColumnIds .size ());
183
+ =======
184
+ TSmallVec<TRawTypeValue> key;
185
+ TSmallVec<NTable::TUpdateOp> ops;
186
+ >>>>>>> 27683edc32f (Precharge in EvWrite (#17721 ))
122
187
123
- for (ui16 valueColIdx = userTable.KeyColumnIds .size (); valueColIdx < matrix.GetColCount (); ++valueColIdx) {
124
- ui32 columnTag = validatedOperation.GetColumnIds ()[valueColIdx];
125
- const TCell& cell = matrix.GetCell (rowIdx, valueColIdx);
126
-
127
- const NScheme::TTypeId vtypeId = scheme.GetColumnInfo (tableInfo, columnTag)->PType .GetTypeId ();
128
- ops.emplace_back (columnTag, NTable::ECellOp::Set, cell.IsNull () ? TRawTypeValue () : TRawTypeValue (cell.Data (), cell.Size (), vtypeId));
129
- }
130
- };
188
+ // Main update cycle
131
189
132
190
for (ui32 rowIdx = 0 ; rowIdx < matrix.GetRowCount (); ++rowIdx)
133
191
{
134
- key.clear ();
135
- key.reserve (userTable.KeyColumnIds .size ());
136
- for (ui16 keyColIdx = 0 ; keyColIdx < userTable.KeyColumnIds .size (); ++keyColIdx) {
137
- const TCell& cell = matrix.GetCell (rowIdx, keyColIdx);
138
- ui32 keyCol = tableInfo->KeyColumns [keyColIdx];
139
- if (cell.IsNull ()) {
140
- key.emplace_back ();
141
- } else {
142
- NScheme::TTypeId vtypeId = scheme.GetColumnInfo (tableInfo, keyCol)->PType .GetTypeId ();
143
- key.emplace_back (cell.Data (), cell.Size (), vtypeId);
144
- }
145
- }
192
+ FillKey (scheme, userTable, tableInfo, validatedOperation, rowIdx, key);
146
193
147
194
switch (operationType) {
148
195
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPSERT: {
149
- fillOps ( rowIdx);
196
+ FillOps (scheme, userTable, tableInfo, validatedOperation, rowIdx, ops );
150
197
userDb.UpsertRow (fullTableId, key, ops);
151
198
break ;
152
199
}
153
200
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_REPLACE: {
154
- fillOps ( rowIdx);
201
+ FillOps (scheme, userTable, tableInfo, validatedOperation, rowIdx, ops );
155
202
userDb.ReplaceRow (fullTableId, key, ops);
156
203
break ;
157
204
}
@@ -160,12 +207,12 @@ class TExecuteWriteUnit : public TExecutionUnit {
160
207
break ;
161
208
}
162
209
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_INSERT: {
163
- fillOps ( rowIdx);
210
+ FillOps (scheme, userTable, tableInfo, validatedOperation, rowIdx, ops );
164
211
userDb.InsertRow (fullTableId, key, ops);
165
212
break ;
166
213
}
167
214
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPDATE: {
168
- fillOps ( rowIdx);
215
+ FillOps (scheme, userTable, tableInfo, validatedOperation, rowIdx, ops );
169
216
userDb.UpdateRow (fullTableId, key, ops);
170
217
break ;
171
218
}
@@ -175,6 +222,8 @@ class TExecuteWriteUnit : public TExecutionUnit {
175
222
}
176
223
}
177
224
225
+ // Counters
226
+
178
227
switch (operationType) {
179
228
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_UPSERT:
180
229
case NKikimrDataEvents::TEvWrite::TOperation::OPERATION_REPLACE:
@@ -214,6 +263,7 @@ class TExecuteWriteUnit : public TExecutionUnit {
214
263
}
215
264
216
265
const TValidatedWriteTx::TPtr& writeTx = writeOp->GetWriteTx ();
266
+ size_t validatedOperationIndex = SIZE_MAX;
217
267
218
268
DataShard.ReleaseCache (*writeOp);
219
269
@@ -357,12 +407,13 @@ class TExecuteWriteUnit : public TExecutionUnit {
357
407
358
408
KqpCommitLocks (tabletId, kqpLocks, sysLocks, writeVersion, userDb);
359
409
360
- TValidatedWriteTx::TPtr& writeTx = writeOp->GetWriteTx ();
361
410
if (writeTx->HasOperations ()) {
362
- for (const auto & validatedOperation : writeTx->GetOperations ()) {
411
+ for (validatedOperationIndex = 0 ; validatedOperationIndex < writeTx->GetOperations ().size (); ++validatedOperationIndex) {
412
+ const TValidatedWriteTxOperation& validatedOperation = writeTx->GetOperations ()[validatedOperationIndex];
363
413
DoUpdateToUserDb (userDb, validatedOperation, txc);
364
414
LOG_DEBUG_S (ctx, NKikimrServices::TX_DATASHARD, " Executed write operation for " << *writeOp << " at " << DataShard.TabletID () << " , row count=" << validatedOperation.GetMatrix ().GetRowCount ());
365
415
}
416
+ validatedOperationIndex = SIZE_MAX;
366
417
} else {
367
418
LOG_DEBUG_S (ctx, NKikimrServices::TX_DATASHARD, " Skip empty write operation for " << *writeOp << " at " << DataShard.TabletID ());
368
419
}
@@ -448,7 +499,7 @@ class TExecuteWriteUnit : public TExecutionUnit {
448
499
}
449
500
return EExecutionStatus::Continue;
450
501
} catch (const TNotReadyTabletException&) {
451
- return OnTabletNotReadyException (userDb, *writeOp, txc, ctx);
502
+ return OnTabletNotReadyException (userDb, *writeOp, validatedOperationIndex, txc, ctx);
452
503
} catch (const TLockedWriteLimitException&) {
453
504
userDb.ResetCollectedChanges ();
454
505
0 commit comments