Skip to content

Commit 3c02c2a

Browse files
authored
statistics: fix wrong NDV in the global stats when to disable async-merge-global-stats (#53762) (#53805)
close #53752
1 parent 8e3a55e commit 3c02c2a

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

pkg/statistics/handle/globalstats/global_stats.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,10 +406,15 @@ func blockingMergePartitionStats2GlobalStats(
406406
}
407407
// FMSketch use many memory, so we first deal with it and then destroy it.
408408
// Merge FMSketch.
409+
// NOTE: allFms maybe contain empty.
409410
globalStats.Fms[i] = allFms[i][0]
410411
for j := 1; j < len(allFms[i]); j++ {
411-
globalStats.Fms[i].MergeFMSketch(allFms[i][j])
412-
allFms[i][j].DestroyAndPutToPool()
412+
if globalStats.Fms[i] == nil {
413+
globalStats.Fms[i] = allFms[i][j]
414+
} else {
415+
globalStats.Fms[i].MergeFMSketch(allFms[i][j])
416+
allFms[i][j].DestroyAndPutToPool()
417+
}
413418
}
414419

415420
// Update the global NDV.

tests/realtikvtest/statisticstest/statistics_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,50 @@ func TestNewCollationStatsWithPrefixIndex(t *testing.T) {
185185
"1 3 15 0 2 0",
186186
))
187187
}
188+
189+
func TestBlockMergeFMSketch(t *testing.T) {
190+
store := realtikvtest.CreateMockStoreAndSetup(t)
191+
tk := testkit.NewTestKit(t, store)
192+
tk.MustExec("use test")
193+
tk.MustExec("set @@tidb_enable_async_merge_global_stats=OFF;")
194+
defer func() {
195+
tk.MustExec("set @@tidb_enable_async_merge_global_stats=ON;")
196+
}()
197+
checkFMSketch(tk)
198+
}
199+
200+
func TestAsyncMergeFMSketch(t *testing.T) {
201+
store := realtikvtest.CreateMockStoreAndSetup(t)
202+
tk := testkit.NewTestKit(t, store)
203+
tk.MustExec("use test")
204+
tk.MustExec("set @@tidb_enable_async_merge_global_stats=ON;")
205+
checkFMSketch(tk)
206+
}
207+
208+
func checkFMSketch(tk *testkit.TestKit) {
209+
tk.MustExec(`CREATE TABLE employees (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,fname VARCHAR(25) NOT NULL,lname VARCHAR(25) NOT NULL,store_id INT NOT NULL,department_id INT NOT NULL
210+
) PARTITION BY RANGE(id) (
211+
PARTITION p0 VALUES LESS THAN (5),
212+
PARTITION p1 VALUES LESS THAN (10),
213+
PARTITION p2 VALUES LESS THAN (15),
214+
PARTITION p3 VALUES LESS THAN MAXVALUE
215+
);`)
216+
tk.MustExec(`INSERT INTO employees(FNAME,LNAME,STORE_ID,DEPARTMENT_ID) VALUES
217+
('Bob', 'Taylor', 3, 2), ('Frank', 'Williams', 1, 2),
218+
('Ellen', 'Johnson', 3, 4), ('Jim', 'Smith', 2, 4),
219+
('Mary', 'Jones', 1, 1), ('Linda', 'Black', 2, 3),
220+
('Ed', 'Jones', 2, 1), ('June', 'Wilson', 3, 1),
221+
('Andy', 'Smith', 1, 3), ('Lou', 'Waters', 2, 4),
222+
('Jill', 'Stone', 1, 4), ('Roger', 'White', 3, 2),
223+
('Howard', 'Andrews', 1, 2), ('Fred', 'Goldberg', 3, 3),
224+
('Barbara', 'Brown', 2, 3), ('Alice', 'Rogers', 2, 2),
225+
('Mark', 'Morgan', 3, 3), ('Karen', 'Cole', 3, 2);`)
226+
tk.MustExec("ANALYZE TABLE employees;")
227+
tk.MustExec("select * from employees;")
228+
tk.MustExec("alter table employees truncate partition p0;")
229+
tk.MustExec("select * from employees;")
230+
tk.MustExec("analyze table employees partition p3;")
231+
tk.MustExec("select * from employees;")
232+
tk.MustQuery(`SHOW STATS_HISTOGRAMS WHERE TABLE_NAME='employees' and partition_name="global" and column_name="id"`).CheckAt([]int{6}, [][]any{
233+
{"14"}})
234+
}

0 commit comments

Comments
 (0)