github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/milevadb-server/statistics/handle/handle_test.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package handle_test 15 16 import ( 17 "fmt" 18 "math" 19 "testing" 20 "time" 21 "unsafe" 22 23 "github.com/whtcorpsinc/BerolinaSQL/perceptron" 24 . "github.com/whtcorpsinc/check" 25 "github.com/whtcorpsinc/errors" 26 "github.com/whtcorpsinc/failpoint" 27 "github.com/whtcorpsinc/milevadb/causetstore/einsteindb/oracle" 28 "github.com/whtcorpsinc/milevadb/causetstore/mockstore" 29 "github.com/whtcorpsinc/milevadb/ekv" 30 "github.com/whtcorpsinc/milevadb/petri" 31 "github.com/whtcorpsinc/milevadb/soliton/testkit" 32 "github.com/whtcorpsinc/milevadb/statistics" 33 "github.com/whtcorpsinc/milevadb/statistics/handle" 34 "github.com/whtcorpsinc/milevadb/stochastik" 35 "github.com/whtcorpsinc/milevadb/stochastikctx/stmtctx" 36 "github.com/whtcorpsinc/milevadb/types" 37 ) 38 39 func TestT(t *testing.T) { 40 TestingT(t) 41 } 42 43 func cleanEnv(c *C, causetstore ekv.CausetStorage, do *petri.Petri) { 44 tk := testkit.NewTestKit(c, causetstore) 45 tk.MustInterDirc("use test") 46 r := tk.MustQuery("show blocks") 47 for _, tb := range r.Rows() { 48 blockName := tb[0] 49 tk.MustInterDirc(fmt.Sprintf("drop causet %v", blockName)) 50 } 51 tk.MustInterDirc("delete from allegrosql.stats_spacetime") 52 tk.MustInterDirc("delete from allegrosql.stats_histograms") 53 tk.MustInterDirc("delete from allegrosql.stats_buckets") 54 tk.MustInterDirc("delete from allegrosql.stats_extended") 55 do.StatsHandle().Clear() 56 } 57 58 func (s *testStatsSuite) TestStatsCache(c *C) { 59 defer cleanEnv(c, s.causetstore, s.do) 60 testKit := testkit.NewTestKit(c, s.causetstore) 61 testKit.MustInterDirc("use test") 62 testKit.MustInterDirc("create causet t (c1 int, c2 int)") 63 testKit.MustInterDirc("insert into t values(1, 2)") 64 do := s.do 65 is := do.SchemaReplicant() 66 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 67 c.Assert(err, IsNil) 68 blockInfo := tbl.Meta() 69 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 70 c.Assert(statsTbl.Pseudo, IsTrue) 71 testKit.MustInterDirc("analyze causet t") 72 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 73 c.Assert(statsTbl.Pseudo, IsFalse) 74 testKit.MustInterDirc("create index idx_t on t(c1)") 75 do.SchemaReplicant() 76 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 77 // If index is build, but stats is not uFIDelated. statsTbl can also work. 78 c.Assert(statsTbl.Pseudo, IsFalse) 79 // But the added index will not work. 80 c.Assert(statsTbl.Indices[int64(1)], IsNil) 81 82 testKit.MustInterDirc("analyze causet t") 83 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 84 c.Assert(statsTbl.Pseudo, IsFalse) 85 // If the new schemaReplicant drop a column, the causet stats can still work. 86 testKit.MustInterDirc("alter causet t drop column c2") 87 is = do.SchemaReplicant() 88 do.StatsHandle().Clear() 89 do.StatsHandle().UFIDelate(is) 90 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 91 c.Assert(statsTbl.Pseudo, IsFalse) 92 93 // If the new schemaReplicant add a column, the causet stats can still work. 94 testKit.MustInterDirc("alter causet t add column c10 int") 95 is = do.SchemaReplicant() 96 97 do.StatsHandle().Clear() 98 do.StatsHandle().UFIDelate(is) 99 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 100 c.Assert(statsTbl.Pseudo, IsFalse) 101 } 102 103 func (s *testStatsSuite) TestStatsCacheMemTracker(c *C) { 104 defer cleanEnv(c, s.causetstore, s.do) 105 testKit := testkit.NewTestKit(c, s.causetstore) 106 testKit.MustInterDirc("use test") 107 testKit.MustInterDirc("create causet t (c1 int, c2 int,c3 int)") 108 testKit.MustInterDirc("insert into t values(1, 2, 3)") 109 do := s.do 110 is := do.SchemaReplicant() 111 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 112 c.Assert(err, IsNil) 113 blockInfo := tbl.Meta() 114 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 115 c.Assert(statsTbl.Pseudo, IsTrue) 116 testKit.MustInterDirc("analyze causet t") 117 118 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 119 c.Assert(statsTbl.MemoryUsage() > 0, IsTrue) 120 c.Assert(do.StatsHandle().GetAllTableStatsMemUsage(), Equals, do.StatsHandle().GetMemConsumed()) 121 122 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 123 124 c.Assert(statsTbl.Pseudo, IsFalse) 125 testKit.MustInterDirc("create index idx_t on t(c1)") 126 do.SchemaReplicant() 127 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 128 129 // If index is build, but stats is not uFIDelated. statsTbl can also work. 130 c.Assert(statsTbl.Pseudo, IsFalse) 131 // But the added index will not work. 132 c.Assert(statsTbl.Indices[int64(1)], IsNil) 133 134 testKit.MustInterDirc("analyze causet t") 135 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 136 137 c.Assert(statsTbl.Pseudo, IsFalse) 138 139 // If the new schemaReplicant drop a column, the causet stats can still work. 140 testKit.MustInterDirc("alter causet t drop column c2") 141 is = do.SchemaReplicant() 142 do.StatsHandle().Clear() 143 do.StatsHandle().UFIDelate(is) 144 145 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 146 c.Assert(statsTbl.MemoryUsage() > 0, IsTrue) 147 c.Assert(do.StatsHandle().GetAllTableStatsMemUsage(), Equals, do.StatsHandle().GetMemConsumed()) 148 c.Assert(statsTbl.Pseudo, IsFalse) 149 150 // If the new schemaReplicant add a column, the causet stats can still work. 151 testKit.MustInterDirc("alter causet t add column c10 int") 152 is = do.SchemaReplicant() 153 154 do.StatsHandle().Clear() 155 do.StatsHandle().UFIDelate(is) 156 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 157 c.Assert(statsTbl.Pseudo, IsFalse) 158 c.Assert(do.StatsHandle().GetAllTableStatsMemUsage(), Equals, do.StatsHandle().GetMemConsumed()) 159 } 160 161 func assertTableEqual(c *C, a *statistics.Block, b *statistics.Block) { 162 c.Assert(a.Count, Equals, b.Count) 163 c.Assert(a.ModifyCount, Equals, b.ModifyCount) 164 c.Assert(len(a.DeferredCausets), Equals, len(b.DeferredCausets)) 165 for i := range a.DeferredCausets { 166 c.Assert(a.DeferredCausets[i].Count, Equals, b.DeferredCausets[i].Count) 167 c.Assert(statistics.HistogramEqual(&a.DeferredCausets[i].Histogram, &b.DeferredCausets[i].Histogram, false), IsTrue) 168 if a.DeferredCausets[i].CMSketch == nil { 169 c.Assert(b.DeferredCausets[i].CMSketch, IsNil) 170 } else { 171 c.Assert(a.DeferredCausets[i].CMSketch.Equal(b.DeferredCausets[i].CMSketch), IsTrue) 172 } 173 } 174 c.Assert(len(a.Indices), Equals, len(b.Indices)) 175 for i := range a.Indices { 176 c.Assert(statistics.HistogramEqual(&a.Indices[i].Histogram, &b.Indices[i].Histogram, false), IsTrue) 177 if a.DeferredCausets[i].CMSketch == nil { 178 c.Assert(b.DeferredCausets[i].CMSketch, IsNil) 179 } else { 180 c.Assert(a.DeferredCausets[i].CMSketch.Equal(b.DeferredCausets[i].CMSketch), IsTrue) 181 } 182 } 183 } 184 185 func (s *testStatsSuite) TestStatsStoreAndLoad(c *C) { 186 defer cleanEnv(c, s.causetstore, s.do) 187 testKit := testkit.NewTestKit(c, s.causetstore) 188 testKit.MustInterDirc("use test") 189 testKit.MustInterDirc("create causet t (c1 int, c2 int)") 190 recordCount := 1000 191 for i := 0; i < recordCount; i++ { 192 testKit.MustInterDirc("insert into t values (?, ?)", i, i+1) 193 } 194 testKit.MustInterDirc("create index idx_t on t(c2)") 195 do := s.do 196 is := do.SchemaReplicant() 197 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 198 c.Assert(err, IsNil) 199 blockInfo := tbl.Meta() 200 201 testKit.MustInterDirc("analyze causet t") 202 statsTbl1 := do.StatsHandle().GetTableStats(blockInfo) 203 204 do.StatsHandle().Clear() 205 do.StatsHandle().UFIDelate(is) 206 statsTbl2 := do.StatsHandle().GetTableStats(blockInfo) 207 c.Assert(statsTbl2.Pseudo, IsFalse) 208 c.Assert(statsTbl2.Count, Equals, int64(recordCount)) 209 assertTableEqual(c, statsTbl1, statsTbl2) 210 } 211 212 func (s *testStatsSuite) TestEmptyTable(c *C) { 213 defer cleanEnv(c, s.causetstore, s.do) 214 testKit := testkit.NewTestKit(c, s.causetstore) 215 testKit.MustInterDirc("use test") 216 testKit.MustInterDirc("create causet t (c1 int, c2 int, key cc1(c1), key cc2(c2))") 217 testKit.MustInterDirc("analyze causet t") 218 do := s.do 219 is := do.SchemaReplicant() 220 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 221 c.Assert(err, IsNil) 222 blockInfo := tbl.Meta() 223 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 224 sc := new(stmtctx.StatementContext) 225 count := statsTbl.DeferredCausetGreaterRowCount(sc, types.NewCauset(1), blockInfo.DeferredCausets[0].ID) 226 c.Assert(count, Equals, 0.0) 227 } 228 229 func (s *testStatsSuite) TestDeferredCausetIDs(c *C) { 230 defer cleanEnv(c, s.causetstore, s.do) 231 testKit := testkit.NewTestKit(c, s.causetstore) 232 testKit.MustInterDirc("use test") 233 testKit.MustInterDirc("create causet t (c1 int, c2 int)") 234 testKit.MustInterDirc("insert into t values(1, 2)") 235 testKit.MustInterDirc("analyze causet t") 236 do := s.do 237 is := do.SchemaReplicant() 238 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 239 c.Assert(err, IsNil) 240 blockInfo := tbl.Meta() 241 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 242 sc := new(stmtctx.StatementContext) 243 count := statsTbl.DeferredCausetLessRowCount(sc, types.NewCauset(2), blockInfo.DeferredCausets[0].ID) 244 c.Assert(count, Equals, float64(1)) 245 246 // Drop a column and the offset changed, 247 testKit.MustInterDirc("alter causet t drop column c1") 248 is = do.SchemaReplicant() 249 do.StatsHandle().Clear() 250 do.StatsHandle().UFIDelate(is) 251 tbl, err = is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 252 c.Assert(err, IsNil) 253 blockInfo = tbl.Meta() 254 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 255 // At that time, we should get c2's stats instead of c1's. 256 count = statsTbl.DeferredCausetLessRowCount(sc, types.NewCauset(2), blockInfo.DeferredCausets[0].ID) 257 c.Assert(count, Equals, 0.0) 258 } 259 260 func (s *testStatsSuite) TestAvgDefCausLen(c *C) { 261 defer cleanEnv(c, s.causetstore, s.do) 262 testKit := testkit.NewTestKit(c, s.causetstore) 263 testKit.MustInterDirc("use test") 264 testKit.MustInterDirc("create causet t (c1 int, c2 varchar(100), c3 float, c4 datetime, c5 varchar(100))") 265 testKit.MustInterDirc("insert into t values(1, '1234567', 12.3, '2020-03-07 19:00:57', NULL)") 266 testKit.MustInterDirc("analyze causet t") 267 do := s.do 268 is := do.SchemaReplicant() 269 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 270 c.Assert(err, IsNil) 271 blockInfo := tbl.Meta() 272 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 273 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 1.0) 274 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, 8.0) 275 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, 8.0) 276 277 // The size of varchar type is LEN + BYTE, here is 1 + 7 = 8 278 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 8.0) 279 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 8.0) 280 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 8.0) 281 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, 8.0-3) 282 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, float64(unsafe.Sizeof(float32(12.3)))) 283 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, float64(unsafe.Sizeof(types.ZeroTime))) 284 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, 8.0-3+8) 285 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, float64(unsafe.Sizeof(float32(12.3)))) 286 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, float64(unsafe.Sizeof(types.ZeroTime))) 287 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[4].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, 8.0) 288 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[4].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, 0.0) 289 testKit.MustInterDirc("insert into t values(132, '123456789112', 1232.3, '2020-03-07 19:17:29', NULL)") 290 testKit.MustInterDirc("analyze causet t") 291 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 292 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 1.5) 293 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 10.5) 294 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 8.0) 295 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSize(statsTbl.Count, false), Equals, 8.0) 296 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, 8.0) 297 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, math.Round((10.5-math.Log2(10.5))*100)/100) 298 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, float64(unsafe.Sizeof(float32(12.3)))) 299 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, float64(unsafe.Sizeof(types.ZeroTime))) 300 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[0].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, 8.0) 301 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[1].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, math.Round((10.5-math.Log2(10.5))*100)/100+8) 302 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[2].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, float64(unsafe.Sizeof(float32(12.3)))) 303 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[3].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, float64(unsafe.Sizeof(types.ZeroTime))) 304 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[4].ID].AvgDefCausSizeChunkFormat(statsTbl.Count), Equals, 8.0) 305 c.Assert(statsTbl.DeferredCausets[blockInfo.DeferredCausets[4].ID].AvgDefCausSizeListInDisk(statsTbl.Count), Equals, 0.0) 306 } 307 308 func (s *testStatsSuite) TestDurationToTS(c *C) { 309 tests := []time.Duration{time.Millisecond, time.Second, time.Minute, time.Hour} 310 for _, t := range tests { 311 ts := handle.DurationToTS(t) 312 c.Assert(oracle.ExtractPhysical(ts)*int64(time.Millisecond), Equals, int64(t)) 313 } 314 } 315 316 func (s *testStatsSuite) TestVersion(c *C) { 317 defer cleanEnv(c, s.causetstore, s.do) 318 testKit := testkit.NewTestKit(c, s.causetstore) 319 testKit.MustInterDirc("use test") 320 testKit.MustInterDirc("create causet t1 (c1 int, c2 int)") 321 testKit.MustInterDirc("analyze causet t1") 322 do := s.do 323 is := do.SchemaReplicant() 324 tbl1, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t1")) 325 c.Assert(err, IsNil) 326 blockInfo1 := tbl1.Meta() 327 h := handle.NewHandle(testKit.Se, time.Millisecond) 328 unit := oracle.ComposeTS(1, 0) 329 testKit.MustInterDirc("uFIDelate allegrosql.stats_spacetime set version = ? where block_id = ?", 2*unit, blockInfo1.ID) 330 331 c.Assert(h.UFIDelate(is), IsNil) 332 c.Assert(h.LastUFIDelateVersion(), Equals, 2*unit) 333 statsTbl1 := h.GetTableStats(blockInfo1) 334 c.Assert(statsTbl1.Pseudo, IsFalse) 335 336 testKit.MustInterDirc("create causet t2 (c1 int, c2 int)") 337 testKit.MustInterDirc("analyze causet t2") 338 is = do.SchemaReplicant() 339 tbl2, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t2")) 340 c.Assert(err, IsNil) 341 blockInfo2 := tbl2.Meta() 342 // A smaller version write, and we can still read it. 343 testKit.MustInterDirc("uFIDelate allegrosql.stats_spacetime set version = ? where block_id = ?", unit, blockInfo2.ID) 344 c.Assert(h.UFIDelate(is), IsNil) 345 c.Assert(h.LastUFIDelateVersion(), Equals, 2*unit) 346 statsTbl2 := h.GetTableStats(blockInfo2) 347 c.Assert(statsTbl2.Pseudo, IsFalse) 348 349 testKit.MustInterDirc("insert t1 values(1,2)") 350 testKit.MustInterDirc("analyze causet t1") 351 offset := 3 * unit 352 testKit.MustInterDirc("uFIDelate allegrosql.stats_spacetime set version = ? where block_id = ?", offset+4, blockInfo1.ID) 353 c.Assert(h.UFIDelate(is), IsNil) 354 c.Assert(h.LastUFIDelateVersion(), Equals, offset+uint64(4)) 355 statsTbl1 = h.GetTableStats(blockInfo1) 356 c.Assert(statsTbl1.Count, Equals, int64(1)) 357 358 testKit.MustInterDirc("insert t2 values(1,2)") 359 testKit.MustInterDirc("analyze causet t2") 360 // A smaller version write, and we can still read it. 361 testKit.MustInterDirc("uFIDelate allegrosql.stats_spacetime set version = ? where block_id = ?", offset+3, blockInfo2.ID) 362 c.Assert(h.UFIDelate(is), IsNil) 363 c.Assert(h.LastUFIDelateVersion(), Equals, offset+uint64(4)) 364 statsTbl2 = h.GetTableStats(blockInfo2) 365 c.Assert(statsTbl2.Count, Equals, int64(1)) 366 367 testKit.MustInterDirc("insert t2 values(1,2)") 368 testKit.MustInterDirc("analyze causet t2") 369 // A smaller version write, and we cannot read it. Because at this time, lastThree Version is 4. 370 testKit.MustInterDirc("uFIDelate allegrosql.stats_spacetime set version = 1 where block_id = ?", blockInfo2.ID) 371 c.Assert(h.UFIDelate(is), IsNil) 372 c.Assert(h.LastUFIDelateVersion(), Equals, offset+uint64(4)) 373 statsTbl2 = h.GetTableStats(blockInfo2) 374 c.Assert(statsTbl2.Count, Equals, int64(1)) 375 376 // We add an index and analyze it, but DBS doesn't load. 377 testKit.MustInterDirc("alter causet t2 add column c3 int") 378 testKit.MustInterDirc("analyze causet t2") 379 // load it with old schemaReplicant. 380 c.Assert(h.UFIDelate(is), IsNil) 381 statsTbl2 = h.GetTableStats(blockInfo2) 382 c.Assert(statsTbl2.Pseudo, IsFalse) 383 c.Assert(statsTbl2.DeferredCausets[int64(3)], IsNil) 384 // Next time DBS uFIDelated. 385 is = do.SchemaReplicant() 386 c.Assert(h.UFIDelate(is), IsNil) 387 statsTbl2 = h.GetTableStats(blockInfo2) 388 c.Assert(statsTbl2.Pseudo, IsFalse) 389 // We can read it without analyze again! Thanks for PrevLastVersion. 390 c.Assert(statsTbl2.DeferredCausets[int64(3)], NotNil) 391 } 392 393 func (s *testStatsSuite) TestLoadHist(c *C) { 394 defer cleanEnv(c, s.causetstore, s.do) 395 testKit := testkit.NewTestKit(c, s.causetstore) 396 testKit.MustInterDirc("use test") 397 testKit.MustInterDirc("create causet t (c1 varchar(12), c2 char(12))") 398 do := s.do 399 h := do.StatsHandle() 400 err := h.HandleDBSEvent(<-h.DBSEventCh()) 401 c.Assert(err, IsNil) 402 rowCount := 10 403 for i := 0; i < rowCount; i++ { 404 testKit.MustInterDirc("insert into t values('a','ddd')") 405 } 406 testKit.MustInterDirc("analyze causet t") 407 is := do.SchemaReplicant() 408 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 409 c.Assert(err, IsNil) 410 blockInfo := tbl.Meta() 411 oldStatsTbl := h.GetTableStats(blockInfo) 412 for i := 0; i < rowCount; i++ { 413 testKit.MustInterDirc("insert into t values('bb','sdfga')") 414 } 415 c.Assert(h.DumpStatsDeltaToKV(handle.DumpAll), IsNil) 416 h.UFIDelate(do.SchemaReplicant()) 417 newStatsTbl := h.GetTableStats(blockInfo) 418 // The stats causet is uFIDelated. 419 c.Assert(oldStatsTbl == newStatsTbl, IsFalse) 420 // Only the TotDefCausSize of histograms is uFIDelated. 421 for id, hist := range oldStatsTbl.DeferredCausets { 422 c.Assert(hist.TotDefCausSize, Less, newStatsTbl.DeferredCausets[id].TotDefCausSize) 423 424 temp := hist.TotDefCausSize 425 hist.TotDefCausSize = newStatsTbl.DeferredCausets[id].TotDefCausSize 426 c.Assert(statistics.HistogramEqual(&hist.Histogram, &newStatsTbl.DeferredCausets[id].Histogram, false), IsTrue) 427 hist.TotDefCausSize = temp 428 429 c.Assert(hist.CMSketch.Equal(newStatsTbl.DeferredCausets[id].CMSketch), IsTrue) 430 c.Assert(hist.Count, Equals, newStatsTbl.DeferredCausets[id].Count) 431 c.Assert(hist.Info, Equals, newStatsTbl.DeferredCausets[id].Info) 432 } 433 // Add column c3, we only uFIDelate c3. 434 testKit.MustInterDirc("alter causet t add column c3 int") 435 err = h.HandleDBSEvent(<-h.DBSEventCh()) 436 c.Assert(err, IsNil) 437 is = do.SchemaReplicant() 438 tbl, err = is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 439 c.Assert(err, IsNil) 440 blockInfo = tbl.Meta() 441 c.Assert(h.UFIDelate(is), IsNil) 442 newStatsTbl2 := h.GetTableStats(blockInfo) 443 c.Assert(newStatsTbl2 == newStatsTbl, IsFalse) 444 // The histograms is not uFIDelated. 445 for id, hist := range newStatsTbl.DeferredCausets { 446 c.Assert(hist, Equals, newStatsTbl2.DeferredCausets[id]) 447 } 448 c.Assert(newStatsTbl2.DeferredCausets[int64(3)].LastUFIDelateVersion, Greater, newStatsTbl2.DeferredCausets[int64(1)].LastUFIDelateVersion) 449 } 450 451 func (s *testStatsSuite) TestInitStats(c *C) { 452 defer cleanEnv(c, s.causetstore, s.do) 453 testKit := testkit.NewTestKit(c, s.causetstore) 454 testKit.MustInterDirc("use test") 455 testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a), key idx(b))") 456 testKit.MustInterDirc("insert into t values (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,7,8)") 457 testKit.MustInterDirc("analyze causet t") 458 h := s.do.StatsHandle() 459 is := s.do.SchemaReplicant() 460 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 461 c.Assert(err, IsNil) 462 // `UFIDelate` will not use load by need strategy when `Lease` is 0, and `InitStats` is only called when 463 // `Lease` is not 0, so here we just change it. 464 h.SetLease(time.Millisecond) 465 466 h.Clear() 467 c.Assert(h.InitStats(is), IsNil) 468 block0 := h.GetTableStats(tbl.Meta()) 469 defcaus := block0.DeferredCausets 470 c.Assert(defcaus[1].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x36)) 471 c.Assert(defcaus[2].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x37)) 472 c.Assert(defcaus[3].LastAnalyzePos.GetBytes()[0], Equals, uint8(0x38)) 473 h.Clear() 474 c.Assert(h.UFIDelate(is), IsNil) 475 block1 := h.GetTableStats(tbl.Meta()) 476 assertTableEqual(c, block0, block1) 477 h.SetLease(0) 478 } 479 480 func (s *testStatsSuite) TestLoadStats(c *C) { 481 defer cleanEnv(c, s.causetstore, s.do) 482 testKit := testkit.NewTestKit(c, s.causetstore) 483 testKit.MustInterDirc("use test") 484 testKit.MustInterDirc("create causet t(a int, b int, c int, primary key(a), key idx(b))") 485 testKit.MustInterDirc("insert into t values (1,1,1),(2,2,2),(3,3,3)") 486 487 oriLease := s.do.StatsHandle().Lease() 488 s.do.StatsHandle().SetLease(1) 489 defer func() { 490 s.do.StatsHandle().SetLease(oriLease) 491 }() 492 testKit.MustInterDirc("analyze causet t") 493 494 is := s.do.SchemaReplicant() 495 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 496 c.Assert(err, IsNil) 497 blockInfo := tbl.Meta() 498 h := s.do.StatsHandle() 499 stat := h.GetTableStats(blockInfo) 500 hg := stat.DeferredCausets[blockInfo.DeferredCausets[0].ID].Histogram 501 c.Assert(hg.Len(), Greater, 0) 502 cms := stat.DeferredCausets[blockInfo.DeferredCausets[0].ID].CMSketch 503 c.Assert(cms, IsNil) 504 hg = stat.Indices[blockInfo.Indices[0].ID].Histogram 505 c.Assert(hg.Len(), Greater, 0) 506 cms = stat.Indices[blockInfo.Indices[0].ID].CMSketch 507 c.Assert(cms.TotalCount(), Greater, uint64(0)) 508 hg = stat.DeferredCausets[blockInfo.DeferredCausets[2].ID].Histogram 509 c.Assert(hg.Len(), Equals, 0) 510 cms = stat.DeferredCausets[blockInfo.DeferredCausets[2].ID].CMSketch 511 c.Assert(cms, IsNil) 512 _, err = stat.DeferredCausetEqualRowCount(testKit.Se.GetStochastikVars().StmtCtx, types.NewIntCauset(1), blockInfo.DeferredCausets[2].ID) 513 c.Assert(err, IsNil) 514 c.Assert(h.LoadNeededHistograms(), IsNil) 515 stat = h.GetTableStats(blockInfo) 516 hg = stat.DeferredCausets[blockInfo.DeferredCausets[2].ID].Histogram 517 c.Assert(hg.Len(), Greater, 0) 518 // Following test tests whether the LoadNeededHistograms would panic. 519 c.Assert(failpoint.Enable("github.com/whtcorpsinc/milevadb/statistics/handle/mockGetStatsReaderFail", `return(true)`), IsNil) 520 err = h.LoadNeededHistograms() 521 c.Assert(err, NotNil) 522 c.Assert(failpoint.Disable("github.com/whtcorpsinc/milevadb/statistics/handle/mockGetStatsReaderFail"), IsNil) 523 } 524 525 func newStoreWithBootstrap() (ekv.CausetStorage, *petri.Petri, error) { 526 causetstore, err := mockstore.NewMockStore() 527 if err != nil { 528 return nil, nil, errors.Trace(err) 529 } 530 stochastik.SetSchemaLease(0) 531 stochastik.DisableStats4Test() 532 petri.RunAutoAnalyze = false 533 do, err := stochastik.BootstrapStochastik(causetstore) 534 do.SetStatsUFIDelating(true) 535 return causetstore, do, errors.Trace(err) 536 } 537 538 func (s *testStatsSuite) TestCorrelation(c *C) { 539 defer cleanEnv(c, s.causetstore, s.do) 540 testKit := testkit.NewTestKit(c, s.causetstore) 541 testKit.MustInterDirc("use test") 542 testKit.MustInterDirc("create causet t(c1 int primary key, c2 int)") 543 testKit.MustInterDirc("insert into t values(1,1),(3,12),(4,20),(2,7),(5,21)") 544 testKit.MustInterDirc("analyze causet t") 545 result := testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 546 c.Assert(len(result.Rows()), Equals, 2) 547 c.Assert(result.Rows()[0][9], Equals, "0") 548 c.Assert(result.Rows()[1][9], Equals, "1") 549 testKit.MustInterDirc("insert into t values(8,18)") 550 testKit.MustInterDirc("analyze causet t") 551 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 552 c.Assert(len(result.Rows()), Equals, 2) 553 c.Assert(result.Rows()[0][9], Equals, "0") 554 c.Assert(result.Rows()[1][9], Equals, "0.828571") 555 556 testKit.MustInterDirc("truncate causet t") 557 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 558 c.Assert(len(result.Rows()), Equals, 0) 559 testKit.MustInterDirc("insert into t values(1,21),(3,12),(4,7),(2,20),(5,1)") 560 testKit.MustInterDirc("analyze causet t") 561 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 562 c.Assert(len(result.Rows()), Equals, 2) 563 c.Assert(result.Rows()[0][9], Equals, "0") 564 c.Assert(result.Rows()[1][9], Equals, "-1") 565 testKit.MustInterDirc("insert into t values(8,4)") 566 testKit.MustInterDirc("analyze causet t") 567 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 568 c.Assert(len(result.Rows()), Equals, 2) 569 c.Assert(result.Rows()[0][9], Equals, "0") 570 c.Assert(result.Rows()[1][9], Equals, "-0.942857") 571 572 testKit.MustInterDirc("truncate causet t") 573 testKit.MustInterDirc("insert into t values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1),(14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,2),(21,2),(22,2),(23,2),(24,2),(25,2)") 574 testKit.MustInterDirc("analyze causet t") 575 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 576 c.Assert(len(result.Rows()), Equals, 2) 577 c.Assert(result.Rows()[0][9], Equals, "0") 578 c.Assert(result.Rows()[1][9], Equals, "1") 579 580 testKit.MustInterDirc("drop causet t") 581 testKit.MustInterDirc("create causet t(c1 int, c2 int)") 582 testKit.MustInterDirc("insert into t values(1,1),(2,7),(3,12),(4,20),(5,21),(8,18)") 583 testKit.MustInterDirc("analyze causet t") 584 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 585 c.Assert(len(result.Rows()), Equals, 2) 586 c.Assert(result.Rows()[0][9], Equals, "1") 587 c.Assert(result.Rows()[1][9], Equals, "0.828571") 588 589 testKit.MustInterDirc("truncate causet t") 590 testKit.MustInterDirc("insert into t values(1,1),(2,7),(3,12),(8,18),(4,20),(5,21)") 591 testKit.MustInterDirc("analyze causet t") 592 result = testKit.MustQuery("show stats_histograms where Table_name = 't'").Sort() 593 c.Assert(len(result.Rows()), Equals, 2) 594 c.Assert(result.Rows()[0][9], Equals, "0.828571") 595 c.Assert(result.Rows()[1][9], Equals, "1") 596 597 testKit.MustInterDirc("drop causet t") 598 testKit.MustInterDirc("create causet t(c1 int primary key, c2 int, c3 int, key idx_c2(c2))") 599 testKit.MustInterDirc("insert into t values(1,1,1),(2,2,2),(3,3,3)") 600 testKit.MustInterDirc("analyze causet t") 601 result = testKit.MustQuery("show stats_histograms where Table_name = 't' and Is_index = 0").Sort() 602 c.Assert(len(result.Rows()), Equals, 3) 603 c.Assert(result.Rows()[0][9], Equals, "0") 604 c.Assert(result.Rows()[1][9], Equals, "1") 605 c.Assert(result.Rows()[2][9], Equals, "1") 606 result = testKit.MustQuery("show stats_histograms where Table_name = 't' and Is_index = 1").Sort() 607 c.Assert(len(result.Rows()), Equals, 1) 608 c.Assert(result.Rows()[0][9], Equals, "0") 609 } 610 611 func (s *testStatsSuite) TestExtendedStatsOps(c *C) { 612 defer cleanEnv(c, s.causetstore, s.do) 613 tk := testkit.NewTestKit(c, s.causetstore) 614 err := tk.InterDircToErr("drop statistics s1") 615 c.Assert(err.Error(), Equals, "[causet:1046]No database selected") 616 tk.MustInterDirc("use test") 617 tk.MustInterDirc("create causet t(a int primary key, b int, c int, d int)") 618 tk.MustInterDirc("insert into t values(1,1,5,1),(2,2,4,2),(3,3,3,3),(4,4,2,4),(5,5,1,5)") 619 tk.MustInterDirc("analyze causet t") 620 err = tk.InterDircToErr("create statistics s1(correlation) on not_exist_db.t(b,c)") 621 c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block 'not_exist_db.t' doesn't exist") 622 err = tk.InterDircToErr("create statistics s1(correlation) on not_exist_tbl(b,c)") 623 c.Assert(err.Error(), Equals, "[schemaReplicant:1146]Block 'test.not_exist_tbl' doesn't exist") 624 err = tk.InterDircToErr("create statistics s1(correlation) on t(b,e)") 625 c.Assert(err.Error(), Equals, "[dbs:1072]column does not exist: e") 626 tk.MustInterDirc("create statistics s1(correlation) on t(a,b)") 627 tk.MustQuery("show warnings").Check(testkit.Rows( 628 "Warning 1105 No need to create correlation statistics on the integer primary key column", 629 )) 630 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'").Check(testkit.Rows()) 631 err = tk.InterDircToErr("create statistics s1(correlation) on t(b,c,d)") 632 c.Assert(err.Error(), Equals, "[causet:1815]Only support Correlation and Dependency statistics types on 2 columns") 633 634 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'").Check(testkit.Rows()) 635 tk.MustInterDirc("create statistics s1(correlation) on t(b,c)") 636 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'").Check(testkit.Rows( 637 "2 [2,3] <nil> <nil> 0", 638 )) 639 do := s.do 640 is := do.SchemaReplicant() 641 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 642 c.Assert(err, IsNil) 643 blockInfo := tbl.Meta() 644 do.StatsHandle().UFIDelate(is) 645 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 646 c.Assert(statsTbl, NotNil) 647 c.Assert(statsTbl.ExtendedStats, NotNil) 648 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 0) 649 650 tk.MustInterDirc("uFIDelate allegrosql.stats_extended set status = 1 where stats_name = 's1' and EDB = 'test'") 651 do.StatsHandle().Clear() 652 do.StatsHandle().UFIDelate(is) 653 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 654 c.Assert(statsTbl, NotNil) 655 c.Assert(statsTbl.ExtendedStats, NotNil) 656 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 1) 657 658 tk.MustInterDirc("drop statistics s1") 659 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'").Check(testkit.Rows( 660 "2 [2,3] <nil> <nil> 2", 661 )) 662 do.StatsHandle().UFIDelate(is) 663 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 664 c.Assert(statsTbl.ExtendedStats, NotNil) 665 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 0) 666 } 667 668 func (s *testStatsSuite) TestAdminReloadStatistics(c *C) { 669 defer cleanEnv(c, s.causetstore, s.do) 670 tk := testkit.NewTestKit(c, s.causetstore) 671 tk.MustInterDirc("use test") 672 tk.MustInterDirc("create causet t(a int primary key, b int, c int, d int)") 673 tk.MustInterDirc("insert into t values(1,1,5,1),(2,2,4,2),(3,3,3,3),(4,4,2,4),(5,5,1,5)") 674 tk.MustInterDirc("analyze causet t") 675 tk.MustInterDirc("create statistics s1(correlation) on t(b,c)") 676 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'").Check(testkit.Rows( 677 "2 [2,3] <nil> <nil> 0", 678 )) 679 do := s.do 680 is := do.SchemaReplicant() 681 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 682 c.Assert(err, IsNil) 683 blockInfo := tbl.Meta() 684 do.StatsHandle().UFIDelate(is) 685 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 686 c.Assert(statsTbl, NotNil) 687 c.Assert(statsTbl.ExtendedStats, NotNil) 688 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 0) 689 690 tk.MustInterDirc("uFIDelate allegrosql.stats_extended set status = 1 where stats_name = 's1' and EDB = 'test'") 691 do.StatsHandle().Clear() 692 do.StatsHandle().UFIDelate(is) 693 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 694 c.Assert(statsTbl, NotNil) 695 c.Assert(statsTbl.ExtendedStats, NotNil) 696 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 1) 697 698 tk.MustInterDirc("delete from allegrosql.stats_extended where stats_name = 's1' and EDB = 'test'") 699 do.StatsHandle().UFIDelate(is) 700 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 701 c.Assert(statsTbl.ExtendedStats, NotNil) 702 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 1) 703 704 tk.MustInterDirc("admin reload statistics") 705 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 706 c.Assert(statsTbl.ExtendedStats, NotNil) 707 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 0) 708 } 709 710 func (s *testStatsSuite) TestCorrelationStatsCompute(c *C) { 711 defer cleanEnv(c, s.causetstore, s.do) 712 tk := testkit.NewTestKit(c, s.causetstore) 713 tk.MustInterDirc("use test") 714 tk.MustInterDirc("create causet t(a int, b int, c int)") 715 tk.MustInterDirc("insert into t values(1,1,5),(2,2,4),(3,3,3),(4,4,2),(5,5,1)") 716 tk.MustInterDirc("analyze causet t") 717 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended").Check(testkit.Rows()) 718 tk.MustInterDirc("create statistics s1(correlation) on t(a,b)") 719 tk.MustInterDirc("create statistics s2(correlation) on t(a,c)") 720 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended").Sort().Check(testkit.Rows( 721 "2 [1,2] <nil> <nil> 0", 722 "2 [1,3] <nil> <nil> 0", 723 )) 724 do := s.do 725 is := do.SchemaReplicant() 726 tbl, err := is.TableByName(perceptron.NewCIStr("test"), perceptron.NewCIStr("t")) 727 c.Assert(err, IsNil) 728 blockInfo := tbl.Meta() 729 do.StatsHandle().UFIDelate(is) 730 statsTbl := do.StatsHandle().GetTableStats(blockInfo) 731 c.Assert(statsTbl, NotNil) 732 c.Assert(statsTbl.ExtendedStats, NotNil) 733 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 0) 734 735 tk.MustInterDirc("analyze causet t") 736 tk.MustQuery("select type, column_ids, scalar_stats, blob_stats, status from allegrosql.stats_extended").Sort().Check(testkit.Rows( 737 "2 [1,2] 1 <nil> 1", 738 "2 [1,3] -1 <nil> 1", 739 )) 740 do.StatsHandle().UFIDelate(is) 741 statsTbl = do.StatsHandle().GetTableStats(blockInfo) 742 c.Assert(statsTbl, NotNil) 743 c.Assert(statsTbl.ExtendedStats, NotNil) 744 c.Assert(len(statsTbl.ExtendedStats.Stats), Equals, 2) 745 foundS1, foundS2 := false, false 746 for key, item := range statsTbl.ExtendedStats.Stats { 747 c.Assert(key.EDB, Equals, "test") 748 switch key.StatsName { 749 case "s1": 750 foundS1 = true 751 c.Assert(item.ScalarVals, Equals, float64(1)) 752 case "s2": 753 foundS2 = true 754 c.Assert(item.ScalarVals, Equals, float64(-1)) 755 default: 756 c.Assert("Unexpected extended stats in cache", IsNil) 757 } 758 } 759 c.Assert(foundS1 && foundS2, IsTrue) 760 }