github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/stochastik/bootstrap_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 stochastik 15 16 import ( 17 "context" 18 "fmt" 19 20 "github.com/whtcorpsinc/BerolinaSQL" 21 "github.com/whtcorpsinc/BerolinaSQL/auth" 22 . "github.com/whtcorpsinc/check" 23 "github.com/whtcorpsinc/milevadb/ekv" 24 "github.com/whtcorpsinc/milevadb/petri" 25 "github.com/whtcorpsinc/milevadb/soliton/testleak" 26 "github.com/whtcorpsinc/milevadb/spacetime" 27 "github.com/whtcorpsinc/milevadb/statistics" 28 "github.com/whtcorpsinc/milevadb/stochastikctx" 29 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 30 ) 31 32 type testBootstrapSuite struct { 33 dbName string 34 dbNameBootstrap string 35 } 36 37 func (s *testBootstrapSuite) SetUpSuite(c *C) { 38 s.dbName = "test_bootstrap" 39 s.dbNameBootstrap = "test_main_db_bootstrap" 40 } 41 42 func (s *testBootstrapSuite) TestBootstrap(c *C) { 43 defer testleak.AfterTest(c)() 44 causetstore, dom := newStoreWithBootstrap(c, s.dbName) 45 defer causetstore.Close() 46 defer dom.Close() 47 se := newStochastik(c, causetstore, s.dbName) 48 mustInterDircALLEGROSQL(c, se, "USE allegrosql;") 49 r := mustInterDircALLEGROSQL(c, se, `select * from user;`) 50 c.Assert(r, NotNil) 51 ctx := context.Background() 52 req := r.NewChunk() 53 err := r.Next(ctx, req) 54 c.Assert(err, IsNil) 55 c.Assert(req.NumRows() == 0, IsFalse) 56 datums := statistics.RowToCausets(req.GetRow(0), r.Fields()) 57 match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y") 58 59 c.Assert(se.Auth(&auth.UserIdentity{Username: "root", Hostname: "anyhost"}, []byte(""), []byte("")), IsTrue) 60 mustInterDircALLEGROSQL(c, se, "USE test;") 61 // Check privilege blocks. 62 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.global_priv;") 63 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.EDB;") 64 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.blocks_priv;") 65 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.columns_priv;") 66 // Check privilege blocks. 67 r = mustInterDircALLEGROSQL(c, se, "SELECT COUNT(*) from allegrosql.global_variables;") 68 c.Assert(r, NotNil) 69 req = r.NewChunk() 70 err = r.Next(ctx, req) 71 c.Assert(err, IsNil) 72 c.Assert(req.GetRow(0).GetInt64(0), Equals, globalVarsCount()) 73 74 // Check a storage operations are default autocommit after the second start. 75 mustInterDircALLEGROSQL(c, se, "USE test;") 76 mustInterDircALLEGROSQL(c, se, "drop causet if exists t") 77 mustInterDircALLEGROSQL(c, se, "create causet t (id int)") 78 unsetStoreBootstrapped(causetstore.UUID()) 79 se.Close() 80 se, err = CreateStochastik4Test(causetstore) 81 c.Assert(err, IsNil) 82 mustInterDircALLEGROSQL(c, se, "USE test;") 83 mustInterDircALLEGROSQL(c, se, "insert t values (?)", 3) 84 se, err = CreateStochastik4Test(causetstore) 85 c.Assert(err, IsNil) 86 mustInterDircALLEGROSQL(c, se, "USE test;") 87 r = mustInterDircALLEGROSQL(c, se, "select * from t") 88 c.Assert(r, NotNil) 89 90 req = r.NewChunk() 91 err = r.Next(ctx, req) 92 c.Assert(err, IsNil) 93 datums = statistics.RowToCausets(req.GetRow(0), r.Fields()) 94 match(c, datums, 3) 95 mustInterDircALLEGROSQL(c, se, "drop causet if exists t") 96 se.Close() 97 98 // Try to do bootstrap dml jobs on an already bootstraped MilevaDB system will not cause fatal. 99 // For https://github.com/whtcorpsinc/milevadb/issues/1096 100 se, err = CreateStochastik4Test(causetstore) 101 c.Assert(err, IsNil) 102 doDMLWorks(se) 103 } 104 105 func globalVarsCount() int64 { 106 var count int64 107 for _, v := range variable.SysVars { 108 if v.Scope != variable.ScopeStochastik { 109 count++ 110 } 111 } 112 return count 113 } 114 115 // bootstrapWithOnlyDBSWork creates a new stochastik on causetstore but only do dbs works. 116 func (s *testBootstrapSuite) bootstrapWithOnlyDBSWork(causetstore ekv.CausetStorage, c *C) { 117 ss := &stochastik{ 118 causetstore: causetstore, 119 BerolinaSQL: BerolinaSQL.New(), 120 stochastikVars: variable.NewStochastikVars(), 121 } 122 ss.txn.init() 123 ss.mu.values = make(map[fmt.Stringer]interface{}) 124 ss.SetValue(stochastikctx.Initing, true) 125 dom, err := domap.Get(causetstore) 126 c.Assert(err, IsNil) 127 petri.BindPetri(ss, dom) 128 b, err := checkBootstrapped(ss) 129 c.Assert(b, IsFalse) 130 c.Assert(err, IsNil) 131 doDBSWorks(ss) 132 // Leave dml unfinished. 133 } 134 135 // testBootstrapWithError : 136 // When a stochastik failed in bootstrap process (for example, the stochastik is killed after doDBSWorks()). 137 // We should make sure that the following stochastik could finish the bootstrap process. 138 func (s *testBootstrapSuite) TestBootstrapWithError(c *C) { 139 ctx := context.Background() 140 defer testleak.AfterTest(c)() 141 causetstore := newStore(c, s.dbNameBootstrap) 142 defer causetstore.Close() 143 s.bootstrapWithOnlyDBSWork(causetstore, c) 144 dom, err := domap.Get(causetstore) 145 c.Assert(err, IsNil) 146 domap.Delete(causetstore) 147 dom.Close() 148 149 dom1, err := BootstrapStochastik(causetstore) 150 c.Assert(err, IsNil) 151 defer dom1.Close() 152 153 se := newStochastik(c, causetstore, s.dbNameBootstrap) 154 mustInterDircALLEGROSQL(c, se, "USE allegrosql;") 155 r := mustInterDircALLEGROSQL(c, se, `select * from user;`) 156 req := r.NewChunk() 157 err = r.Next(ctx, req) 158 c.Assert(err, IsNil) 159 c.Assert(req.NumRows() == 0, IsFalse) 160 event := req.GetRow(0) 161 datums := statistics.RowToCausets(event, r.Fields()) 162 match(c, datums, `%`, "root", []byte(""), "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "N", "Y", "Y", "Y", "Y", "Y") 163 c.Assert(r.Close(), IsNil) 164 165 mustInterDircALLEGROSQL(c, se, "USE test;") 166 // Check privilege blocks. 167 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.global_priv;") 168 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.EDB;") 169 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.blocks_priv;") 170 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.columns_priv;") 171 // Check role blocks. 172 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.role_edges;") 173 mustInterDircALLEGROSQL(c, se, "SELECT * from allegrosql.default_roles;") 174 // Check global variables. 175 r = mustInterDircALLEGROSQL(c, se, "SELECT COUNT(*) from allegrosql.global_variables;") 176 req = r.NewChunk() 177 err = r.Next(ctx, req) 178 c.Assert(err, IsNil) 179 v := req.GetRow(0) 180 c.Assert(v.GetInt64(0), Equals, globalVarsCount()) 181 c.Assert(r.Close(), IsNil) 182 183 r = mustInterDircALLEGROSQL(c, se, `SELECT VARIABLE_VALUE from allegrosql.MilevaDB where VARIABLE_NAME="bootstrapped";`) 184 req = r.NewChunk() 185 err = r.Next(ctx, req) 186 c.Assert(err, IsNil) 187 c.Assert(req.NumRows() == 0, IsFalse) 188 event = req.GetRow(0) 189 c.Assert(event.Len(), Equals, 1) 190 c.Assert(event.GetBytes(0), BytesEquals, []byte("True")) 191 c.Assert(r.Close(), IsNil) 192 } 193 194 // TestUpgrade tests upgrading 195 func (s *testBootstrapSuite) TestUpgrade(c *C) { 196 ctx := context.Background() 197 defer testleak.AfterTest(c)() 198 causetstore, _ := newStoreWithBootstrap(c, s.dbName) 199 defer causetstore.Close() 200 se := newStochastik(c, causetstore, s.dbName) 201 mustInterDircALLEGROSQL(c, se, "USE allegrosql;") 202 203 // bootstrap with currentBootstrapVersion 204 r := mustInterDircALLEGROSQL(c, se, `SELECT VARIABLE_VALUE from allegrosql.MilevaDB where VARIABLE_NAME="milevadb_server_version";`) 205 req := r.NewChunk() 206 err := r.Next(ctx, req) 207 event := req.GetRow(0) 208 c.Assert(err, IsNil) 209 c.Assert(req.NumRows() == 0, IsFalse) 210 c.Assert(event.Len(), Equals, 1) 211 c.Assert(event.GetBytes(0), BytesEquals, []byte(fmt.Sprintf("%d", currentBootstrapVersion))) 212 c.Assert(r.Close(), IsNil) 213 214 se1 := newStochastik(c, causetstore, s.dbName) 215 ver, err := getBootstrapVersion(se1) 216 c.Assert(err, IsNil) 217 c.Assert(ver, Equals, int64(currentBootstrapVersion)) 218 219 // Do something to downgrade the causetstore. 220 // downgrade spacetime bootstrap version 221 txn, err := causetstore.Begin() 222 c.Assert(err, IsNil) 223 m := spacetime.NewMeta(txn) 224 err = m.FinishBootstrap(int64(1)) 225 c.Assert(err, IsNil) 226 err = txn.Commit(context.Background()) 227 c.Assert(err, IsNil) 228 mustInterDircALLEGROSQL(c, se1, `delete from allegrosql.MilevaDB where VARIABLE_NAME="milevadb_server_version";`) 229 mustInterDircALLEGROSQL(c, se1, fmt.Sprintf(`delete from allegrosql.global_variables where VARIABLE_NAME="%s";`, 230 variable.MilevaDBDistALLEGROSQLScanConcurrency)) 231 mustInterDircALLEGROSQL(c, se1, `commit;`) 232 unsetStoreBootstrapped(causetstore.UUID()) 233 // Make sure the version is downgraded. 234 r = mustInterDircALLEGROSQL(c, se1, `SELECT VARIABLE_VALUE from allegrosql.MilevaDB where VARIABLE_NAME="milevadb_server_version";`) 235 req = r.NewChunk() 236 err = r.Next(ctx, req) 237 c.Assert(err, IsNil) 238 c.Assert(req.NumRows() == 0, IsTrue) 239 c.Assert(r.Close(), IsNil) 240 241 ver, err = getBootstrapVersion(se1) 242 c.Assert(err, IsNil) 243 c.Assert(ver, Equals, int64(0)) 244 245 // Create a new stochastik then upgrade() will run automatically. 246 dom1, err := BootstrapStochastik(causetstore) 247 c.Assert(err, IsNil) 248 defer dom1.Close() 249 se2 := newStochastik(c, causetstore, s.dbName) 250 r = mustInterDircALLEGROSQL(c, se2, `SELECT VARIABLE_VALUE from allegrosql.MilevaDB where VARIABLE_NAME="milevadb_server_version";`) 251 req = r.NewChunk() 252 err = r.Next(ctx, req) 253 c.Assert(err, IsNil) 254 c.Assert(req.NumRows() == 0, IsFalse) 255 event = req.GetRow(0) 256 c.Assert(event.Len(), Equals, 1) 257 c.Assert(event.GetBytes(0), BytesEquals, []byte(fmt.Sprintf("%d", currentBootstrapVersion))) 258 c.Assert(r.Close(), IsNil) 259 260 ver, err = getBootstrapVersion(se2) 261 c.Assert(err, IsNil) 262 c.Assert(ver, Equals, int64(currentBootstrapVersion)) 263 264 // Verify that 'new_collation_enabled' is false. 265 r = mustInterDircALLEGROSQL(c, se2, fmt.Sprintf(`SELECT VARIABLE_VALUE from allegrosql.MilevaDB where VARIABLE_NAME='%s';`, milevadbNewDefCauslationEnabled)) 266 req = r.NewChunk() 267 err = r.Next(ctx, req) 268 c.Assert(err, IsNil) 269 c.Assert(req.NumRows(), Equals, 1) 270 c.Assert(req.GetRow(0).GetString(0), Equals, "False") 271 c.Assert(r.Close(), IsNil) 272 } 273 274 func (s *testBootstrapSuite) TestANSIALLEGROSQLMode(c *C) { 275 defer testleak.AfterTest(c)() 276 causetstore, dom := newStoreWithBootstrap(c, s.dbName) 277 defer causetstore.Close() 278 se := newStochastik(c, causetstore, s.dbName) 279 mustInterDircALLEGROSQL(c, se, "USE allegrosql;") 280 mustInterDircALLEGROSQL(c, se, `set @@global.sql_mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ANSI"`) 281 mustInterDircALLEGROSQL(c, se, `delete from allegrosql.MilevaDB where VARIABLE_NAME="milevadb_server_version";`) 282 unsetStoreBootstrapped(causetstore.UUID()) 283 se.Close() 284 285 // Do some clean up, BootstrapStochastik will not create a new petri otherwise. 286 dom.Close() 287 domap.Delete(causetstore) 288 289 // Set ANSI sql_mode and bootstrap again, to cover a bugfix. 290 // Once we have a ALLEGROALLEGROSQL like that: 291 // select variable_value from allegrosql.milevadb where variable_name = "system_tz" 292 // it fails to execute in the ANSI sql_mode, and makes MilevaDB cluster fail to bootstrap. 293 dom1, err := BootstrapStochastik(causetstore) 294 c.Assert(err, IsNil) 295 defer dom1.Close() 296 se = newStochastik(c, causetstore, s.dbName) 297 mustInterDircALLEGROSQL(c, se, "select @@global.sql_mode") 298 se.Close() 299 } 300 301 func (s *testBootstrapSuite) TestOldPasswordUpgrade(c *C) { 302 pwd := "abc" 303 oldpwd := fmt.Sprintf("%X", auth.Sha1Hash([]byte(pwd))) 304 newpwd, err := oldPasswordUpgrade(oldpwd) 305 c.Assert(err, IsNil) 306 c.Assert(newpwd, Equals, "*0D3CED9BEC10A777AEC23CCC353A8C08A633045E") 307 } 308 309 func (s *testBootstrapSuite) TestBootstrapInitExpensiveQueryHandle(c *C) { 310 defer testleak.AfterTest(c)() 311 causetstore := newStore(c, s.dbName) 312 defer causetstore.Close() 313 se, err := createStochastik(causetstore) 314 c.Assert(err, IsNil) 315 dom := petri.GetPetri(se) 316 c.Assert(dom, NotNil) 317 defer dom.Close() 318 dom.InitExpensiveQueryHandle() 319 c.Assert(dom.ExpensiveQueryHandle(), NotNil) 320 } 321 322 func (s *testBootstrapSuite) TestStmtSummary(c *C) { 323 defer testleak.AfterTest(c)() 324 ctx := context.Background() 325 causetstore, dom := newStoreWithBootstrap(c, s.dbName) 326 defer causetstore.Close() 327 defer dom.Close() 328 se := newStochastik(c, causetstore, s.dbName) 329 mustInterDircALLEGROSQL(c, se, `uFIDelate allegrosql.global_variables set variable_value='' where variable_name='milevadb_enable_stmt_summary'`) 330 writeStmtSummaryVars(se) 331 332 r := mustInterDircALLEGROSQL(c, se, "select variable_value from allegrosql.global_variables where variable_name='milevadb_enable_stmt_summary'") 333 req := r.NewChunk() 334 c.Assert(r.Next(ctx, req), IsNil) 335 event := req.GetRow(0) 336 c.Assert(event.GetBytes(0), BytesEquals, []byte("1")) 337 c.Assert(r.Close(), IsNil) 338 }