diff --git a/statistics/cmsketch.go b/statistics/cmsketch.go index 9d14ed5d96f6d..9473ae616d427 100644 --- a/statistics/cmsketch.go +++ b/statistics/cmsketch.go @@ -445,7 +445,9 @@ func LoadCMSketchWithTopN(exec sqlexec.RestrictedSQLExecutor, tableID, isIndex, } topN := make([]*TopNMeta, 0, len(topNRows)) for _, row := range topNRows { - topN = append(topN, &TopNMeta{Data: row.GetBytes(0), Count: row.GetUint64(1)}) + data := make([]byte, len(row.GetBytes(0))) + copy(data, row.GetBytes(0)) + topN = append(topN, &TopNMeta{Data: data, Count: row.GetUint64(1)}) } return decodeCMSketch(cms, topN) } diff --git a/statistics/handle/bootstrap.go b/statistics/handle/bootstrap.go index d3fcb05082d0b..e4e83963017ac 100644 --- a/statistics/handle/bootstrap.go +++ b/statistics/handle/bootstrap.go @@ -91,6 +91,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat continue } id, ndv, nullCount, version, totColSize := row.GetInt64(2), row.GetInt64(3), row.GetInt64(5), row.GetUint64(4), row.GetInt64(7) + lastAnalyzePos := row.GetDatum(11, types.NewFieldType(mysql.TypeBlob)) tbl, _ := h.getTableByPhysicalID(is, table.PhysicalID) if row.GetInt64(1) > 0 { var idxInfo *model.IndexInfo @@ -109,7 +110,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat terror.Log(errors.Trace(err)) } hist := statistics.NewHistogram(id, ndv, nullCount, version, types.NewFieldType(mysql.TypeBlob), chunk.InitialCapacity, 0) - 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))} + table.Indices[hist.ID] = &statistics.Index{Histogram: *hist, CMSketch: cms, Info: idxInfo, StatsVer: row.GetInt64(8), Flag: row.GetInt64(10), LastAnalyzePos: *lastAnalyzePos.Copy()} } else { var colInfo *model.ColumnInfo for _, col := range tbl.Meta().Columns { @@ -130,7 +131,7 @@ func (h *Handle) initStatsHistograms4Chunk(is infoschema.InfoSchema, tables Stat Count: nullCount, IsHandle: tbl.Meta().PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag), Flag: row.GetInt64(10), - LastAnalyzePos: row.GetDatum(11, types.NewFieldType(mysql.TypeBlob)), + LastAnalyzePos: *lastAnalyzePos.Copy(), } } } diff --git a/statistics/handle/handle.go b/statistics/handle/handle.go index 7cd5c8fca1a9a..bdf16a79405e3 100644 --- a/statistics/handle/handle.go +++ b/statistics/handle/handle.go @@ -83,7 +83,8 @@ func (h *Handle) Clear() { } h.feedback = h.feedback[:0] h.mu.ctx.GetSessionVars().InitChunkSize = 1 - h.mu.ctx.GetSessionVars().MaxChunkSize = 32 + h.mu.ctx.GetSessionVars().MaxChunkSize = 1 + h.mu.ctx.GetSessionVars().ProjectionConcurrency = 0 h.listHead = &SessionStatsCollector{mapper: make(tableDeltaMap), rateMap: make(errorRateDeltaMap)} h.globalMap = make(tableDeltaMap) h.mu.rateMap = make(errorRateDeltaMap) @@ -353,6 +354,7 @@ func (h *Handle) indexStatsFromStorage(row chunk.Row, table *statistics.Table, t idx := table.Indices[histID] errorRate := statistics.ErrorRate{} flag := row.GetInt64(8) + lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)) if statistics.IsAnalyzed(flag) { h.mu.Lock() h.mu.rateMap.clear(table.PhysicalID, histID, true) @@ -373,7 +375,7 @@ func (h *Handle) indexStatsFromStorage(row chunk.Row, table *statistics.Table, t if err != nil { return errors.Trace(err) } - 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))} + idx = &statistics.Index{Histogram: *hg, CMSketch: cms, Info: idxInfo, ErrorRate: errorRate, StatsVer: row.GetInt64(7), Flag: flag, LastAnalyzePos: *lastAnalyzePos.Copy()} } break } @@ -392,6 +394,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table, nullCount := row.GetInt64(5) totColSize := row.GetInt64(6) correlation := row.GetFloat64(9) + lastAnalyzePos := row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)) col := table.Columns[histID] errorRate := statistics.ErrorRate{} flag := row.GetInt64(8) @@ -429,7 +432,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table, ErrorRate: errorRate, IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag), Flag: flag, - LastAnalyzePos: row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)), + LastAnalyzePos: *lastAnalyzePos.Copy(), } col.Histogram.Correlation = correlation break @@ -452,7 +455,7 @@ func (h *Handle) columnStatsFromStorage(row chunk.Row, table *statistics.Table, ErrorRate: errorRate, IsHandle: tableInfo.PKIsHandle && mysql.HasPriKeyFlag(colInfo.Flag), Flag: flag, - LastAnalyzePos: row.GetDatum(10, types.NewFieldType(mysql.TypeBlob)), + LastAnalyzePos: *lastAnalyzePos.Copy(), } break } diff --git a/statistics/handle/handle_test.go b/statistics/handle/handle_test.go index 1d53e53ed2e16..bb3b08cb5490e 100644 --- a/statistics/handle/handle_test.go +++ b/statistics/handle/handle_test.go @@ -371,7 +371,7 @@ func (s *testStatsSuite) TestInitStats(c *C) { testKit := testkit.NewTestKit(c, s.store) testKit.MustExec("use test") testKit.MustExec("create table t(a int, b int, c int, primary key(a), key idx(b))") - testKit.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6)") + testKit.MustExec("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,7,8)") testKit.MustExec("analyze table t") h := s.do.StatsHandle() is := s.do.InfoSchema() @@ -384,6 +384,10 @@ func (s *testStatsSuite) TestInitStats(c *C) { h.Clear() c.Assert(h.InitStats(is), IsNil) table0 := h.GetTableStats(tbl.Meta()) + cols := table0.Columns + c.Assert(cols[1].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x36)) + c.Assert(cols[2].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x37)) + c.Assert(cols[3].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x38)) h.Clear() c.Assert(h.Update(is), IsNil) table1 := h.GetTableStats(tbl.Meta())