Skip to content

Commit

Permalink
This is an automated cherry-pick of pingcap#54315
Browse files Browse the repository at this point in the history
Signed-off-by: ti-chi-bot <ti-community-prow-bot@tidb.io>
  • Loading branch information
Defined2014 authored and ti-chi-bot committed Jul 8, 2024
1 parent 4c7f6a1 commit 3c855e2
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 6 deletions.
4 changes: 4 additions & 0 deletions pkg/statistics/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ go_test(
data = glob(["testdata/**"]),
embed = [":statistics"],
flaky = True,
<<<<<<< HEAD
shard_count = 34,
=======
shard_count = 38,
>>>>>>> 878fa328ea4 (statistics: update stats_history table when it meets duplicate (#54315))
deps = [
"//pkg/config",
"//pkg/parser/ast",
Expand Down
10 changes: 4 additions & 6 deletions pkg/statistics/handle/history/history_stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,7 @@ func RecordHistoricalStatsToStorage(sctx sessionctx.Context, physicalID int64, j
version = js.Version
} else {
for _, p := range js.Partitions {
version = p.Version
if version != 0 {
break
}
version = max(version, p.Version)
}
}
blocks, err := storage.JSONTableToBlocks(js, maxColumnSize)
Expand All @@ -147,9 +144,10 @@ func RecordHistoricalStatsToStorage(sctx sessionctx.Context, physicalID int64, j
}

ts := time.Now().Format("2006-01-02 15:04:05.999999")
const sql = "INSERT INTO mysql.stats_history(table_id, stats_data, seq_no, version, create_time) VALUES (%?, %?, %?, %?, %?)"
const sql = "INSERT INTO mysql.stats_history(table_id, stats_data, seq_no, version, create_time) VALUES (%?, %?, %?, %?, %?)" +
"ON DUPLICATE KEY UPDATE stats_data=%?, create_time=%?"
for i := 0; i < len(blocks); i++ {
if _, err := util.Exec(sctx, sql, physicalID, blocks[i], i, version, ts); err != nil {
if _, err = util.Exec(sctx, sql, physicalID, blocks[i], i, version, ts, blocks[i], ts); err != nil {
return 0, errors.Trace(err)
}
}
Expand Down
125 changes: 125 additions & 0 deletions pkg/statistics/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,128 @@ func TestIssue44369(t *testing.T) {
tk.MustExec("alter table t rename column b to bb;")
tk.MustExec("select * from t where a = 10 and bb > 20;")
}
<<<<<<< HEAD
=======

// Test the case that after ALTER TABLE happens, the pointer to the column info/index info should be refreshed.
func TestColAndIdxExistenceMapChangedAfterAlterTable(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
h := dom.StatsHandle()
tk := testkit.NewTestKit(t, store)
tk.MustExec("use test")
tk.MustExec("create table t(a int, b int, index iab(a,b));")
require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh()))
tk.MustExec("insert into t value(1,1);")
require.NoError(t, h.DumpStatsDeltaToKV(true))
tk.MustExec("analyze table t;")
is := dom.InfoSchema()
require.NoError(t, h.Update(is))
tbl, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
tblInfo := tbl.Meta()
statsTbl := h.GetTableStats(tblInfo)
colA := tblInfo.Columns[0]
colInfo := statsTbl.ColAndIdxExistenceMap.GetCol(colA.ID)
require.Equal(t, colA, colInfo)

tk.MustExec("alter table t modify column a double")
require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh()))
is = dom.InfoSchema()
require.NoError(t, h.Update(is))
tbl, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
tblInfo = tbl.Meta()
newColA := tblInfo.Columns[0]
require.NotEqual(t, colA.ID, newColA.ID)
statsTbl = h.GetTableStats(tblInfo)
colInfo = statsTbl.ColAndIdxExistenceMap.GetCol(newColA.ID)
require.Equal(t, newColA, colInfo)
tk.MustExec("analyze table t;")
require.NoError(t, h.Update(is))
statsTbl = h.GetTableStats(tblInfo)
colInfo = statsTbl.ColAndIdxExistenceMap.GetCol(newColA.ID)
require.Equal(t, newColA, colInfo)
}

func TestTableLastAnalyzeVersion(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
h := dom.StatsHandle()
tk := testkit.NewTestKit(t, store)

// Only create table should not set the last_analyze_version
tk.MustExec("use test")
tk.MustExec("create table t(a int);")
require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh()))
is := dom.InfoSchema()
require.NoError(t, h.Update(is))
tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
statsTbl, found := h.Get(tbl.Meta().ID)
require.True(t, found)
require.Equal(t, uint64(0), statsTbl.LastAnalyzeVersion)

// Only alter table should not set the last_analyze_version
tk.MustExec("alter table t add column b int default 0")
is = dom.InfoSchema()
tbl, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
require.NoError(t, err)
require.NoError(t, h.HandleDDLEvent(<-h.DDLEventCh()))
require.NoError(t, h.Update(is))
statsTbl, found = h.Get(tbl.Meta().ID)
require.True(t, found)
require.Equal(t, uint64(0), statsTbl.LastAnalyzeVersion)
tk.MustExec("alter table t add index idx(a)")
is = dom.InfoSchema()
tbl, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
// We don't handle the ADD INDEX event in the HandleDDLEvent.
require.Equal(t, 0, len(h.DDLEventCh()))
require.NoError(t, err)
require.NoError(t, h.Update(is))
statsTbl, found = h.Get(tbl.Meta().ID)
require.True(t, found)
require.Equal(t, uint64(0), statsTbl.LastAnalyzeVersion)

// INSERT and updating the modify_count should not set the last_analyze_version
tk.MustExec("insert into t values(1, 1)")
require.NoError(t, h.DumpStatsDeltaToKV(true))
require.NoError(t, h.Update(is))
statsTbl, found = h.Get(tbl.Meta().ID)
require.True(t, found)
require.Equal(t, uint64(0), statsTbl.LastAnalyzeVersion)

// After analyze, last_analyze_version is set.
tk.MustExec("analyze table t")
require.NoError(t, h.Update(is))
statsTbl, found = h.Get(tbl.Meta().ID)
require.True(t, found)
require.NotEqual(t, uint64(0), statsTbl.LastAnalyzeVersion)
}

func TestGlobalIndexWithAnalyzeVersion1AndHistoricalStats(t *testing.T) {
store, dom := testkit.CreateMockStoreAndDomain(t)
tk := testkit.NewTestKit(t, store)

tk.MustExec("set tidb_enable_global_index = true")
tk.MustExec("set tidb_analyze_version = 1")
tk.MustExec("set global tidb_enable_historical_stats = true")
defer tk.MustExec("set global tidb_enable_historical_stats = default")

tk.MustExec("use test")
tk.MustExec(`CREATE TABLE t ( a int, b int, c int default 0)
PARTITION BY RANGE (a) (
PARTITION p0 VALUES LESS THAN (10),
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (30),
PARTITION p3 VALUES LESS THAN (40))`)
tk.MustExec("ALTER TABLE t ADD UNIQUE INDEX idx(b)")
tk.MustExec("INSERT INTO t(a, b) values(1, 1), (2, 2), (3, 3), (15, 15), (25, 25), (35, 35)")

tblID := dom.MustGetTableID(t, "test", "t")

for i := 0; i < 10; i++ {
tk.MustExec("analyze table t")
}
// Each analyze will only generate one record
tk.MustQuery(fmt.Sprintf("select count(*) from mysql.stats_history where table_id=%d", tblID)).Equal(testkit.Rows("10"))
}
>>>>>>> 878fa328ea4 (statistics: update stats_history table when it meets duplicate (#54315))

0 comments on commit 3c855e2

Please sign in to comment.