@@ -126,6 +126,10 @@ class TTxState : public TAtomicRefCount<TTxState> {
126
126
std::atomic<ui64> TxMaxAllocation = 0 ;
127
127
std::atomic<ui64> TxFailedAllocation = 0 ;
128
128
129
+ // TODO(ilezhankin): it's better to use std::atomic<std::shared_ptr<>> which is not supported at the moment.
130
+ std::atomic<TBackTrace*> TxMaxAllocationBacktrace = nullptr ;
131
+ std::atomic<TBackTrace*> TxFailedAllocationBacktrace = nullptr ;
132
+
129
133
public:
130
134
explicit TTxState (ui64 txId, TInstant now, TIntrusivePtr<TKqpCounters> counters, const TString& poolId, const double memoryPoolPercent,
131
135
const TString& database)
@@ -137,6 +141,11 @@ class TTxState : public TAtomicRefCount<TTxState> {
137
141
, Database(database)
138
142
{}
139
143
144
+ ~TTxState () {
145
+ delete TxMaxAllocationBacktrace.load ();
146
+ delete TxFailedAllocationBacktrace.load ();
147
+ }
148
+
140
149
std::pair<TString, TString> MakePoolId () const {
141
150
return std::make_pair (Database, PoolId);
142
151
}
@@ -157,7 +166,14 @@ class TTxState : public TAtomicRefCount<TTxState> {
157
166
<< " , tx largest failed memory allocation: " << HumanReadableSize (TxFailedAllocation.load (), SF_BYTES)
158
167
<< " , tx total execution units: " << TxExecutionUnits.load ()
159
168
<< " , started at: " << CreatedAt
160
- << " }" ;
169
+ << " }" << Endl;
170
+
171
+ if (TxMaxAllocationBacktrace.load ()) {
172
+ res << " TxMaxAllocationBacktrace:" << Endl << TxMaxAllocationBacktrace.load ()->PrintToString ();
173
+ }
174
+ if (TxFailedAllocationBacktrace.load ()) {
175
+ res << " TxFailedAllocationBacktrace:" << Endl << TxFailedAllocationBacktrace.load ()->PrintToString ();
176
+ }
161
177
162
178
return res;
163
179
}
@@ -167,8 +183,23 @@ class TTxState : public TAtomicRefCount<TTxState> {
167
183
}
168
184
169
185
void AckFailedMemoryAlloc (ui64 memory) {
186
+ auto * oldBacktrace = TxFailedAllocationBacktrace.load ();
170
187
ui64 maxAlloc = TxFailedAllocation.load ();
171
- while (maxAlloc < memory && !TxFailedAllocation.compare_exchange_weak (maxAlloc, memory));
188
+ bool exchanged = false ;
189
+
190
+ while (maxAlloc < memory && !exchanged) {
191
+ exchanged = TxFailedAllocation.compare_exchange_weak (maxAlloc, memory);
192
+ }
193
+
194
+ if (exchanged) {
195
+ auto * newBacktrace = new TBackTrace ();
196
+ newBacktrace->Capture ();
197
+ if (TxFailedAllocationBacktrace.compare_exchange_strong (oldBacktrace, newBacktrace)) {
198
+ delete oldBacktrace;
199
+ } else {
200
+ delete newBacktrace;
201
+ }
202
+ }
172
203
}
173
204
174
205
void Released (TIntrusivePtr<TTaskState>& taskState, const TKqpResourcesRequest& resources) {
@@ -186,9 +217,6 @@ class TTxState : public TAtomicRefCount<TTxState> {
186
217
taskState->ScanQueryMemory -= resources.Memory ;
187
218
Counters->RmMemory ->Sub (resources.Memory );
188
219
189
- ui64 maxAlloc = TxMaxAllocation.load ();
190
- while (maxAlloc < resources.Memory && !TxMaxAllocation.compare_exchange_weak (maxAlloc, resources.Memory ));
191
-
192
220
TxExecutionUnits.fetch_sub (resources.ExecutionUnits );
193
221
taskState->ExecutionUnits -= resources.ExecutionUnits ;
194
222
Counters->RmComputeActors ->Sub (resources.ExecutionUnits );
@@ -210,6 +238,24 @@ class TTxState : public TAtomicRefCount<TTxState> {
210
238
Counters->RmExtraMemAllocs ->Inc ();
211
239
}
212
240
241
+ auto * oldBacktrace = TxMaxAllocationBacktrace.load ();
242
+ ui64 maxAlloc = TxMaxAllocation.load ();
243
+ bool exchanged = false ;
244
+
245
+ while (maxAlloc < resources.Memory && !exchanged) {
246
+ exchanged = TxMaxAllocation.compare_exchange_weak (maxAlloc, resources.Memory );
247
+ }
248
+
249
+ if (exchanged) {
250
+ auto * newBacktrace = new TBackTrace ();
251
+ newBacktrace->Capture ();
252
+ if (TxMaxAllocationBacktrace.compare_exchange_strong (oldBacktrace, newBacktrace)) {
253
+ delete oldBacktrace;
254
+ } else {
255
+ delete newBacktrace;
256
+ }
257
+ }
258
+
213
259
TxExecutionUnits.fetch_add (resources.ExecutionUnits );
214
260
taskState->ExecutionUnits += resources.ExecutionUnits ;
215
261
Counters->RmComputeActors ->Add (resources.ExecutionUnits );
0 commit comments