Skip to content

Commit c6bbf0f

Browse files
authored
stats: fix shallow copy bugs (pingcap#12691) (pingcap#12817)
1 parent a663cc9 commit c6bbf0f

File tree

4 files changed

+18
-8
lines changed

4 files changed

+18
-8
lines changed

statistics/cmsketch.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,9 @@ func LoadCMSketchWithTopN(exec sqlexec.RestrictedSQLExecutor, tableID, isIndex,
445445
}
446446
topN := make([]*TopNMeta, 0, len(topNRows))
447447
for _, row := range topNRows {
448-
topN = append(topN, &TopNMeta{Data: row.GetBytes(0), Count: row.GetUint64(1)})
448+
data := make([]byte, len(row.GetBytes(0)))
449+
copy(data, row.GetBytes(0))
450+
topN = append(topN, &TopNMeta{Data: data, Count: row.GetUint64(1)})
449451
}
450452
return decodeCMSketch(cms, topN)
451453
}

statistics/handle/bootstrap.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat
9191
continue
9292
}
9393
id, ndv, nullCount, version, totColSize := row.GetInt64(2), row.GetInt64(3), row.GetInt64(5), row.GetUint64(4), row.GetInt64(7)
94+
lastAnalyzePos := row.GetDatum(11, types.NewFieldType(mysql.TypeBlob))
9495
tbl, _ := h.getTableByPhysicalID(is, table.PhysicalID)
9596
if row.GetInt64(1) > 0 {
9697
var idxInfo *model.IndexInfo
@@ -109,7 +110,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat
109110
terror.Log(errors.Trace(err))
110111
}
111112
hist := statistics.NewHistogram(id, ndv, nullCount, version, types.NewFieldType(mysql.TypeBlob), chunk.InitialCapacity, 0)
112-
table.Indices[hist.ID] = &statistics.Index{Histogram: *hist, CMSketch: cms, Info: idxInfo, StatsVer: row.GetInt64(8), Flag: row.GetInt64(10), LastAnalyzePos: row.GetDatum(11, types.NewFieldType(mysql.TypeBlob))}
113+
table.Indices[hist.ID] = &statistics.Index{Histogram: *hist, CMSketch: cms, Info: idxInfo, StatsVer: row.GetInt64(8), Flag: row.GetInt64(10), LastAnalyzePos: *lastAnalyzePos.Copy()}
113114
} else {
114115
var colInfo *model.ColumnInfo
115116
for _, col := range tbl.Meta().Columns {
@@ -130,7 +131,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat
130131
Count: nullCount,
131132
IsHandle: tbl.Meta().PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag),
132133
Flag: row.GetInt64(10),
133-
LastAnalyzePos: row.GetDatum(11, types.NewFieldType(mysql.TypeBlob)),
134+
LastAnalyzePos: *lastAnalyzePos.Copy(),
134135
}
135136
}
136137
}

statistics/handle/handle.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ func (h *Handle) Clear() {
8383
}
8484
h.feedback = h.feedback[:0]
8585
h.mu.ctx.GetSessionVars().InitChunkSize = 1
86-
h.mu.ctx.GetSessionVars().MaxChunkSize = 32
86+
h.mu.ctx.GetSessionVars().MaxChunkSize = 1
87+
h.mu.ctx.GetSessionVars().ProjectionConcurrency = 0
8788
h.listHead = &SessionStatsCollector{mapper: make(tableDeltaMap), rateMap: make(errorRateDeltaMap)}
8889
h.globalMap = make(tableDeltaMap)
8990
h.mu.rateMap = make(errorRateDeltaMap)
@@ -353,6 +354,7 @@ func (h *Handle) indexStatsFromStorage(row chunk.Row, table *statistics.Table, t
353354
idx := table.Indices[histID]
354355
errorRate := statistics.ErrorRate{}
355356
flag := row.GetInt64(8)
357+
lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob))
356358
if statistics.IsAnalyzed(flag) {
357359
h.mu.Lock()
358360
h.mu.rateMap.clear(table.PhysicalID, histID, true)
@@ -373,7 +375,7 @@ func (h *Handle) indexStatsFromStorage(row chunk.Row, table *statistics.Table, t
373375
if err != nil {
374376
return errors.Trace(err)
375377
}
376-
idx = &statistics.Index{Histogram: *hg, CMSketch: cms, Info: idxInfo, ErrorRate: errorRate, StatsVer: row.GetInt64(7), Flag: flag, LastAnalyzePos: row.GetDatum(10, types.NewFieldType(mysql.TypeBlob))}
378+
idx = &statistics.Index{Histogram: *hg, CMSketch: cms, Info: idxInfo, ErrorRate: errorRate, StatsVer: row.GetInt64(7), Flag: flag, LastAnalyzePos: *lastAnalyzePos.Copy()}
377379
}
378380
break
379381
}
@@ -392,6 +394,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table,
392394
nullCount := row.GetInt64(5)
393395
totColSize := row.GetInt64(6)
394396
correlation := row.GetFloat64(9)
397+
lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob))
395398
col := table.Columns[histID]
396399
errorRate := statistics.ErrorRate{}
397400
flag := row.GetInt64(8)
@@ -429,7 +432,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table,
429432
ErrorRate: errorRate,
430433
IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag),
431434
Flag: flag,
432-
LastAnalyzePos: row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)),
435+
LastAnalyzePos: *lastAnalyzePos.Copy(),
433436
}
434437
col.Histogram.Correlation = correlation
435438
break
@@ -452,7 +455,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table,
452455
ErrorRate: errorRate,
453456
IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag),
454457
Flag: flag,
455-
LastAnalyzePos: row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)),
458+
LastAnalyzePos: *lastAnalyzePos.Copy(),
456459
}
457460
break
458461
}

statistics/handle/handle_test.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ func (s *testStatsSuite) TestInitStats(c *C) {
371371
testKit := testkit.NewTestKit(c, s.store)
372372
testKit.MustExec("use test")
373373
testKit.MustExec("create table t(a int, b int, c int, primary key(a), key idx(b))")
374-
testKit.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6)")
374+
testKit.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,7,8)")
375375
testKit.MustExec("analyze table t")
376376
h := s.do.StatsHandle()
377377
is := s.do.InfoSchema()
@@ -384,6 +384,10 @@ func (s *testStatsSuite) TestInitStats(c *C) {
384384
h.Clear()
385385
c.Assert(h.InitStats(is), IsNil)
386386
table0 := h.GetTableStats(tbl.Meta())
387+
cols := table0.Columns
388+
c.Assert(cols[1].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x36))
389+
c.Assert(cols[2].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x37))
390+
c.Assert(cols[3].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x38))
387391
h.Clear()
388392
c.Assert(h.Update(is), IsNil)
389393
table1 := h.GetTableStats(tbl.Meta())

0 commit comments

Comments
 (0)