@@ -545,8 +545,8 @@ func (sender *copIteratorTaskSender) sendToTaskCh(t *copTask) (exit bool) {
545
545
return
546
546
}
547
547
548
- func (worker * copIteratorWorker ) sendToRespCh (resp * copResponse , respCh chan <- * copResponse ) (exit bool ) {
549
- if worker .memTracker != nil {
548
+ func (worker * copIteratorWorker ) sendToRespCh (resp * copResponse , respCh chan <- * copResponse , checkOOM bool ) (exit bool ) {
549
+ if worker .memTracker != nil && checkOOM {
550
550
worker .memTracker .Consume (int64 (resp .MemSize ()))
551
551
}
552
552
select {
@@ -607,12 +607,24 @@ func (it *copIterator) Next(ctx context.Context) (kv.ResultSubset, error) {
607
607
608
608
// handleTask handles single copTask, sends the result to channel, retry automatically on error.
609
609
func (worker * copIteratorWorker ) handleTask (bo * Backoffer , task * copTask , respCh chan <- * copResponse ) {
610
+ defer func () {
611
+ r := recover ()
612
+ if r != nil {
613
+ logutil .Logger (context .Background ()).Error ("copIteratorWork meet panic" ,
614
+ zap .Reflect ("r" , r ),
615
+ zap .Stack ("stack trace" ))
616
+ resp := & copResponse {err : errors .Errorf ("%v" , r )}
617
+ // if panic has happened, set checkOOM to false to avoid another panic.
618
+ worker .sendToRespCh (resp , task .respChan , false )
619
+ }
620
+ }()
621
+
610
622
remainTasks := []* copTask {task }
611
623
for len (remainTasks ) > 0 {
612
624
tasks , err := worker .handleTaskOnce (bo , remainTasks [0 ], respCh )
613
625
if err != nil {
614
626
resp := & copResponse {err : errors .Trace (err )}
615
- worker .sendToRespCh (resp , respCh )
627
+ worker .sendToRespCh (resp , respCh , true )
616
628
return
617
629
}
618
630
if len (tasks ) > 0 {
@@ -803,7 +815,7 @@ func (worker *copIteratorWorker) handleCopResponse(bo *Backoffer, resp *copRespo
803
815
}
804
816
}
805
817
}
806
- worker .sendToRespCh (resp , ch )
818
+ worker .sendToRespCh (resp , ch , true )
807
819
return nil , nil
808
820
}
809
821
0 commit comments