Skip to content

Commit

Permalink
statistics: fix data race in HandleUpdateStats (#33260)
Browse files Browse the repository at this point in the history
ref #32867, ref #33001, close #33108
  • Loading branch information
xuyifangreeneyes authored Mar 25, 2022
1 parent 843b0f4 commit 9b9051f
Showing 1 changed file with 18 additions and 37 deletions.
55 changes: 18 additions & 37 deletions statistics/handle/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/pingcap/tidb/metrics"
"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/parser/mysql"
"github.com/pingcap/tidb/parser/terror"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/stmtctx"
"github.com/pingcap/tidb/sessionctx/variable"
Expand Down Expand Up @@ -737,50 +736,32 @@ func (h *Handle) HandleUpdateStats(is infoschema.InfoSchema) error {
}

for _, ptbl := range tables {
// this func lets `defer` works normally, where `Close()` should be called before any return
err = func() error {
tbl := ptbl.GetInt64(0)
const sql = "select table_id, hist_id, is_index, feedback from mysql.stats_feedback where table_id=%? order by hist_id, is_index"
rc, err := h.mu.ctx.(sqlexec.SQLExecutor).ExecuteInternal(context.TODO(), sql, tbl)
tableID, histID, isIndex := ptbl.GetInt64(0), int64(-1), int64(-1)
for {
// fetch at most 100000 rows each time to avoid OOM
const sql = "select table_id, hist_id, is_index, feedback from mysql.stats_feedback where table_id = %? and is_index >= %? and hist_id > %? order by is_index, hist_id limit 100000"
rows, _, err := h.execRestrictedSQL(ctx, sql, tableID, histID, isIndex)
if err != nil {
return errors.Trace(err)
}
defer terror.Call(rc.Close)
tableID, histID, isIndex := int64(-1), int64(-1), int64(-1)
var rows []chunk.Row
for {
req := rc.NewChunk(nil)
iter := chunk.NewIterator4Chunk(req)
err := rc.Next(context.TODO(), req)
if err != nil {
return errors.Trace(err)
}
if req.NumRows() == 0 {
if len(rows) > 0 {
if err := h.handleSingleHistogramUpdate(is, rows); err != nil {
if len(rows) == 0 {
break
}
startIdx := 0
for i, row := range rows {
if row.GetInt64(1) != histID || row.GetInt64(2) != isIndex {
if i > 0 {
if err = h.handleSingleHistogramUpdate(is, rows[startIdx:i]); err != nil {
return errors.Trace(err)
}
}
break
}
for row := iter.Begin(); row != iter.End(); row = iter.Next() {
// len(rows) > 100000 limits the rows to avoid OOM
if row.GetInt64(0) != tableID || row.GetInt64(1) != histID || row.GetInt64(2) != isIndex || len(rows) > 100000 {
if len(rows) > 0 {
if err := h.handleSingleHistogramUpdate(is, rows); err != nil {
return errors.Trace(err)
}
}
tableID, histID, isIndex = row.GetInt64(0), row.GetInt64(1), row.GetInt64(2)
rows = rows[:0]
}
rows = append(rows, row)
histID, isIndex = row.GetInt64(1), row.GetInt64(2)
startIdx = i
}
}
return nil
}()
if err != nil {
return err
if err = h.handleSingleHistogramUpdate(is, rows[startIdx:]); err != nil {
return errors.Trace(err)
}
}
}
return nil
Expand Down

0 comments on commit 9b9051f

Please sign in to comment.