github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/stochastik/bootstrap.go (about) 1 // Copyright 2020 The ql Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSES/QL-LICENSE file. 4 5 // Copyright 2020 WHTCORPS INC, Inc. 6 // 7 // Licensed under the Apache License, Version 2.0 (the "License"); 8 // you may not use this file except in compliance with the License. 9 // You may obtain a copy of the License at 10 // 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // 13 // Unless required by applicable law or agreed to in writing, software 14 // distributed under the License is distributed on an "AS IS" BASIS, 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package stochastik 19 20 import ( 21 "context" 22 "encoding/hex" 23 "flag" 24 "fmt" 25 "runtime/debug" 26 "strconv" 27 "strings" 28 "time" 29 30 "github.com/whtcorpsinc/BerolinaSQL/allegrosql" 31 "github.com/whtcorpsinc/BerolinaSQL/auth" 32 "github.com/whtcorpsinc/BerolinaSQL/terror" 33 "github.com/whtcorpsinc/errors" 34 "github.com/whtcorpsinc/milevadb/causet/embedded" 35 "github.com/whtcorpsinc/milevadb/config" 36 "github.com/whtcorpsinc/milevadb/dbs" 37 "github.com/whtcorpsinc/milevadb/petri" 38 "github.com/whtcorpsinc/milevadb/schemareplicant" 39 "github.com/whtcorpsinc/milevadb/soliton/chunk" 40 "github.com/whtcorpsinc/milevadb/soliton/logutil" 41 "github.com/whtcorpsinc/milevadb/soliton/timeutil" 42 "github.com/whtcorpsinc/milevadb/stochastikctx/variable" 43 "go.uber.org/zap" 44 ) 45 46 const ( 47 // CreateUserTable is the ALLEGROALLEGROSQL memex creates User causet in system EDB. 48 CreateUserTable = `CREATE TABLE if not exists allegrosql.user ( 49 Host CHAR(64), 50 User CHAR(32), 51 authentication_string TEXT, 52 Select_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 53 Insert_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 54 UFIDelate_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 55 Delete_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 56 Create_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 57 Drop_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 58 Process_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 59 Grant_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 60 References_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 61 Alter_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 62 Show_db_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 63 Super_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 64 Create_tmp_block_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 65 Lock_blocks_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 66 InterDircute_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 67 Create_view_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 68 Show_view_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 69 Create_routine_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 70 Alter_routine_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 71 Index_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 72 Create_user_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 73 Event_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 74 Trigger_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 75 Create_role_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 76 Drop_role_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 77 Account_locked ENUM('N','Y') NOT NULL DEFAULT 'N', 78 Shutdown_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 79 Reload_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 80 FILE_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 81 Config_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 82 Create_Tablespace_Priv ENUM('N','Y') NOT NULL DEFAULT 'N', 83 PRIMARY KEY (Host, User));` 84 // CreateGlobalPrivTable is the ALLEGROALLEGROSQL memex creates Global scope privilege causet in system EDB. 85 CreateGlobalPrivTable = "CREATE TABLE if not exists allegrosql.global_priv (" + 86 "Host char(60) NOT NULL DEFAULT ''," + 87 "User char(80) NOT NULL DEFAULT ''," + 88 "Priv longtext NOT NULL DEFAULT ''," + 89 "PRIMARY KEY (Host, User)" + 90 ")" 91 // CreateDBPrivTable is the ALLEGROALLEGROSQL memex creates EDB scope privilege causet in system EDB. 92 CreateDBPrivTable = `CREATE TABLE if not exists allegrosql.EDB ( 93 Host CHAR(60), 94 EDB CHAR(64), 95 User CHAR(32), 96 Select_priv ENUM('N','Y') Not Null DEFAULT 'N', 97 Insert_priv ENUM('N','Y') Not Null DEFAULT 'N', 98 UFIDelate_priv ENUM('N','Y') Not Null DEFAULT 'N', 99 Delete_priv ENUM('N','Y') Not Null DEFAULT 'N', 100 Create_priv ENUM('N','Y') Not Null DEFAULT 'N', 101 Drop_priv ENUM('N','Y') Not Null DEFAULT 'N', 102 Grant_priv ENUM('N','Y') Not Null DEFAULT 'N', 103 References_priv ENUM('N','Y') Not Null DEFAULT 'N', 104 Index_priv ENUM('N','Y') Not Null DEFAULT 'N', 105 Alter_priv ENUM('N','Y') Not Null DEFAULT 'N', 106 Create_tmp_block_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 107 Lock_blocks_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 108 Create_view_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 109 Show_view_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 110 Create_routine_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 111 Alter_routine_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 112 InterDircute_priv ENUM('N','Y') Not Null DEFAULT 'N', 113 Event_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 114 Trigger_priv ENUM('N','Y') NOT NULL DEFAULT 'N', 115 PRIMARY KEY (Host, EDB, User));` 116 // CreateTablePrivTable is the ALLEGROALLEGROSQL memex creates causet scope privilege causet in system EDB. 117 CreateTablePrivTable = `CREATE TABLE if not exists allegrosql.blocks_priv ( 118 Host CHAR(60), 119 EDB CHAR(64), 120 User CHAR(32), 121 Table_name CHAR(64), 122 Grantor CHAR(77), 123 Timestamp Timestamp DEFAULT CURRENT_TIMESTAMP, 124 Table_priv SET('Select','Insert','UFIDelate','Delete','Create','Drop','Grant','Index','Alter','Create View','Show View','Trigger','References'), 125 DeferredCauset_priv SET('Select','Insert','UFIDelate'), 126 PRIMARY KEY (Host, EDB, User, Table_name));` 127 // CreateDeferredCausetPrivTable is the ALLEGROALLEGROSQL memex creates column scope privilege causet in system EDB. 128 CreateDeferredCausetPrivTable = `CREATE TABLE if not exists allegrosql.columns_priv( 129 Host CHAR(60), 130 EDB CHAR(64), 131 User CHAR(32), 132 Table_name CHAR(64), 133 DeferredCauset_name CHAR(64), 134 Timestamp Timestamp DEFAULT CURRENT_TIMESTAMP, 135 DeferredCauset_priv SET('Select','Insert','UFIDelate'), 136 PRIMARY KEY (Host, EDB, User, Table_name, DeferredCauset_name));` 137 // CreateGlobalVariablesTable is the ALLEGROALLEGROSQL memex creates global variable causet in system EDB. 138 // TODO: MyALLEGROSQL puts GLOBAL_VARIABLES causet in INFORMATION_SCHEMA EDB. 139 // INFORMATION_SCHEMA is a virtual EDB in MilevaDB. So we put this causet in system EDB. 140 // Maybe we will put it back to INFORMATION_SCHEMA. 141 CreateGlobalVariablesTable = `CREATE TABLE if not exists allegrosql.GLOBAL_VARIABLES( 142 VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY, 143 VARIABLE_VALUE VARCHAR(1024) DEFAULT Null);` 144 // CreateMilevaDBTable is the ALLEGROALLEGROSQL memex creates a causet in system EDB. 145 // This causet is a key-value struct contains some information used by MilevaDB. 146 // Currently we only put bootstrapped in it which indicates if the system is already bootstrapped. 147 CreateMilevaDBTable = `CREATE TABLE if not exists allegrosql.milevadb( 148 VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY, 149 VARIABLE_VALUE VARCHAR(1024) DEFAULT Null, 150 COMMENT VARCHAR(1024));` 151 152 // CreateHelpTopic is the ALLEGROALLEGROSQL memex creates help_topic causet in system EDB. 153 // See: https://dev.allegrosql.com/doc/refman/5.5/en/system-database.html#system-database-help-blocks 154 CreateHelpTopic = `CREATE TABLE if not exists allegrosql.help_topic ( 155 help_topic_id int(10) unsigned NOT NULL, 156 name char(64) NOT NULL, 157 help_category_id smallint(5) unsigned NOT NULL, 158 description text NOT NULL, 159 example text NOT NULL, 160 url text NOT NULL, 161 PRIMARY KEY (help_topic_id), 162 UNIQUE KEY name (name) 163 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 STATS_PERSISTENT=0 COMMENT='help topics';` 164 165 // CreateStatsMetaTable stores the spacetime of causet statistics. 166 CreateStatsMetaTable = `CREATE TABLE if not exists allegrosql.stats_spacetime ( 167 version bigint(64) unsigned NOT NULL, 168 block_id bigint(64) NOT NULL, 169 modify_count bigint(64) NOT NULL DEFAULT 0, 170 count bigint(64) unsigned NOT NULL DEFAULT 0, 171 index idx_ver(version), 172 unique index tbl(block_id) 173 );` 174 175 // CreateStatsDefCaussTable stores the statistics of causet columns. 176 CreateStatsDefCaussTable = `CREATE TABLE if not exists allegrosql.stats_histograms ( 177 block_id bigint(64) NOT NULL, 178 is_index tinyint(2) NOT NULL, 179 hist_id bigint(64) NOT NULL, 180 distinct_count bigint(64) NOT NULL, 181 null_count bigint(64) NOT NULL DEFAULT 0, 182 tot_col_size bigint(64) NOT NULL DEFAULT 0, 183 modify_count bigint(64) NOT NULL DEFAULT 0, 184 version bigint(64) unsigned NOT NULL DEFAULT 0, 185 cm_sketch blob, 186 stats_ver bigint(64) NOT NULL DEFAULT 0, 187 flag bigint(64) NOT NULL DEFAULT 0, 188 correlation double NOT NULL DEFAULT 0, 189 last_analyze_pos blob DEFAULT NULL, 190 unique index tbl(block_id, is_index, hist_id) 191 );` 192 193 // CreateStatsBucketsTable stores the histogram info for every causet columns. 194 CreateStatsBucketsTable = `CREATE TABLE if not exists allegrosql.stats_buckets ( 195 block_id bigint(64) NOT NULL, 196 is_index tinyint(2) NOT NULL, 197 hist_id bigint(64) NOT NULL, 198 bucket_id bigint(64) NOT NULL, 199 count bigint(64) NOT NULL, 200 repeats bigint(64) NOT NULL, 201 upper_bound blob NOT NULL, 202 lower_bound blob , 203 unique index tbl(block_id, is_index, hist_id, bucket_id) 204 );` 205 206 // CreateGCDeleteRangeTable stores schemas which can be deleted by DeleteRange. 207 CreateGCDeleteRangeTable = `CREATE TABLE IF NOT EXISTS allegrosql.gc_delete_range ( 208 job_id BIGINT NOT NULL COMMENT "the DBS job ID", 209 element_id BIGINT NOT NULL COMMENT "the schemaReplicant element ID", 210 start_key VARCHAR(255) NOT NULL COMMENT "encoded in hex", 211 end_key VARCHAR(255) NOT NULL COMMENT "encoded in hex", 212 ts BIGINT NOT NULL COMMENT "timestamp in uint64", 213 UNIQUE KEY delete_range_index (job_id, element_id) 214 );` 215 216 // CreateGCDeleteRangeDoneTable stores schemas which are already deleted by DeleteRange. 217 CreateGCDeleteRangeDoneTable = `CREATE TABLE IF NOT EXISTS allegrosql.gc_delete_range_done ( 218 job_id BIGINT NOT NULL COMMENT "the DBS job ID", 219 element_id BIGINT NOT NULL COMMENT "the schemaReplicant element ID", 220 start_key VARCHAR(255) NOT NULL COMMENT "encoded in hex", 221 end_key VARCHAR(255) NOT NULL COMMENT "encoded in hex", 222 ts BIGINT NOT NULL COMMENT "timestamp in uint64", 223 UNIQUE KEY delete_range_done_index (job_id, element_id) 224 );` 225 226 // CreateStatsFeedbackTable stores the feedback info which is used to uFIDelate stats. 227 CreateStatsFeedbackTable = `CREATE TABLE IF NOT EXISTS allegrosql.stats_feedback ( 228 block_id bigint(64) NOT NULL, 229 is_index tinyint(2) NOT NULL, 230 hist_id bigint(64) NOT NULL, 231 feedback blob NOT NULL, 232 index hist(block_id, is_index, hist_id) 233 );` 234 235 // CreateBindInfoTable stores the allegrosql bind info which is used to uFIDelate globalBindCache. 236 CreateBindInfoTable = `CREATE TABLE IF NOT EXISTS allegrosql.bind_info ( 237 original_sql text NOT NULL , 238 bind_sql text NOT NULL , 239 default_db text NOT NULL, 240 status text NOT NULL, 241 create_time timestamp(3) NOT NULL, 242 uFIDelate_time timestamp(3) NOT NULL, 243 charset text NOT NULL, 244 collation text NOT NULL, 245 source varchar(10) NOT NULL default 'unknown', 246 INDEX sql_index(original_sql(1024),default_db(1024)) COMMENT "accelerate the speed when add global binding query", 247 INDEX time_index(uFIDelate_time) COMMENT "accelerate the speed when querying with last uFIDelate time" 248 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;` 249 250 // CreateRoleEdgesTable stores the role and user relationship information. 251 CreateRoleEdgesTable = `CREATE TABLE IF NOT EXISTS allegrosql.role_edges ( 252 FROM_HOST char(60) COLLATE utf8_bin NOT NULL DEFAULT '', 253 FROM_USER char(32) COLLATE utf8_bin NOT NULL DEFAULT '', 254 TO_HOST char(60) COLLATE utf8_bin NOT NULL DEFAULT '', 255 TO_USER char(32) COLLATE utf8_bin NOT NULL DEFAULT '', 256 WITH_ADMIN_OPTION enum('N','Y') CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'N', 257 PRIMARY KEY (FROM_HOST,FROM_USER,TO_HOST,TO_USER) 258 );` 259 260 // CreateDefaultRolesTable stores the active roles for a user. 261 CreateDefaultRolesTable = `CREATE TABLE IF NOT EXISTS allegrosql.default_roles ( 262 HOST char(60) COLLATE utf8_bin NOT NULL DEFAULT '', 263 USER char(32) COLLATE utf8_bin NOT NULL DEFAULT '', 264 DEFAULT_ROLE_HOST char(60) COLLATE utf8_bin NOT NULL DEFAULT '%', 265 DEFAULT_ROLE_USER char(32) COLLATE utf8_bin NOT NULL DEFAULT '', 266 PRIMARY KEY (HOST,USER,DEFAULT_ROLE_HOST,DEFAULT_ROLE_USER) 267 )` 268 269 // CreateStatsTopNTable stores topn data of a cmsketch with top n. 270 CreateStatsTopNTable = `CREATE TABLE if not exists allegrosql.stats_top_n ( 271 block_id bigint(64) NOT NULL, 272 is_index tinyint(2) NOT NULL, 273 hist_id bigint(64) NOT NULL, 274 value longblob, 275 count bigint(64) UNSIGNED NOT NULL, 276 index tbl(block_id, is_index, hist_id) 277 );` 278 279 // CreateExprPushdownBlacklist stores the memexs which are not allowed to be pushed down. 280 CreateExprPushdownBlacklist = `CREATE TABLE IF NOT EXISTS allegrosql.expr_pushdown_blacklist ( 281 name char(100) NOT NULL, 282 store_type char(100) NOT NULL DEFAULT 'einsteindb,tiflash,milevadb', 283 reason varchar(200) 284 );` 285 286 // CreateOptMemruleBlacklist stores the list of disabled optimizing operations. 287 CreateOptMemruleBlacklist = `CREATE TABLE IF NOT EXISTS allegrosql.opt_rule_blacklist ( 288 name char(100) NOT NULL 289 );` 290 291 // CreateStatsExtended stores the registered extended statistics. 292 CreateStatsExtended = `CREATE TABLE IF NOT EXISTS allegrosql.stats_extended ( 293 stats_name varchar(32) NOT NULL, 294 EDB varchar(32) NOT NULL, 295 type tinyint(4) NOT NULL, 296 block_id bigint(64) NOT NULL, 297 column_ids varchar(32) NOT NULL, 298 scalar_stats double DEFAULT NULL, 299 blob_stats blob DEFAULT NULL, 300 version bigint(64) unsigned NOT NULL, 301 status tinyint(4) NOT NULL, 302 PRIMARY KEY(stats_name, EDB), 303 KEY idx_1 (block_id, status, version), 304 KEY idx_2 (status, version) 305 );` 306 307 // CreateSchemaIndexUsageTable stores the index usage information. 308 CreateSchemaIndexUsageTable = `CREATE TABLE IF NOT EXISTS allegrosql.schema_index_usage ( 309 TABLE_SCHEMA varchar(64), 310 TABLE_NAME varchar(64), 311 INDEX_NAME varchar(64), 312 QUERY_COUNT bigint(64), 313 ROWS_SELECTED bigint(64), 314 LAST_USED_AT timestamp, 315 LAST_UFIDelATED_AT timestamp, 316 PRIMARY KEY(TABLE_SCHEMA, TABLE_NAME, INDEX_NAME) 317 );` 318 ) 319 320 // bootstrap initiates system EDB for a causetstore. 321 func bootstrap(s Stochastik) { 322 startTime := time.Now() 323 dom := petri.GetPetri(s) 324 for { 325 b, err := checkBootstrapped(s) 326 if err != nil { 327 logutil.BgLogger().Fatal("check bootstrap error", 328 zap.Error(err)) 329 } 330 // For rolling upgrade, we can't do upgrade only in the tenant. 331 if b { 332 upgrade(s) 333 logutil.BgLogger().Info("upgrade successful in bootstrap", 334 zap.Duration("take time", time.Since(startTime))) 335 return 336 } 337 // To reduce conflict when multiple MilevaDB-server start at the same time. 338 // Actually only one server need to do the bootstrap. So we chose DBS tenant to do this. 339 if dom.DBS().TenantManager().IsTenant() { 340 doDBSWorks(s) 341 doDMLWorks(s) 342 logutil.BgLogger().Info("bootstrap successful", 343 zap.Duration("take time", time.Since(startTime))) 344 return 345 } 346 time.Sleep(200 * time.Millisecond) 347 } 348 } 349 350 const ( 351 // varTrue is the true value in allegrosql.MilevaDB causet for boolean columns. 352 varTrue = "True" 353 // varFalse is the false value in allegrosql.MilevaDB causet for boolean columns. 354 varFalse = "False" 355 // The variable name in allegrosql.MilevaDB causet. 356 // It is used for checking if the causetstore is bootstrapped by any MilevaDB server. 357 // If the value is `True`, the causetstore is already bootstrapped by a MilevaDB server. 358 bootstrappedVar = "bootstrapped" 359 // The variable name in allegrosql.MilevaDB causet. 360 // It is used for getting the version of the MilevaDB server which bootstrapped the causetstore. 361 milevadbServerVersionVar = "milevadb_server_version" 362 // The variable name in allegrosql.milevadb causet and it will be used when we want to know 363 // system timezone. 364 milevadbSystemTZ = "system_tz" 365 // The variable name in allegrosql.milevadb causet and it will indicate if the new collations are enabled in the MilevaDB cluster. 366 milevadbNewDefCauslationEnabled = "new_collation_enabled" 367 // Const for MilevaDB server version 2. 368 version2 = 2 369 version3 = 3 370 version4 = 4 371 version5 = 5 372 version6 = 6 373 version7 = 7 374 version8 = 8 375 version9 = 9 376 version10 = 10 377 version11 = 11 378 version12 = 12 379 version13 = 13 380 version14 = 14 381 version15 = 15 382 version16 = 16 383 version17 = 17 384 version18 = 18 385 version19 = 19 386 version20 = 20 387 version21 = 21 388 version22 = 22 389 version23 = 23 390 version24 = 24 391 version25 = 25 392 version26 = 26 393 version27 = 27 394 version28 = 28 395 // version29 is not needed. 396 version30 = 30 397 version31 = 31 398 version32 = 32 399 version33 = 33 400 version34 = 34 401 version35 = 35 402 version36 = 36 403 version37 = 37 404 version38 = 38 405 version39 = 39 406 // version40 is the version that introduce new collation in MilevaDB, 407 // see https://github.com/whtcorpsinc/milevadb/pull/14574 for more details. 408 version40 = 40 409 version41 = 41 410 // version42 add storeType and reason column in expr_pushdown_blacklist 411 version42 = 42 412 // version43 uFIDelates global variables related to memex summary. 413 version43 = 43 414 // version44 delete milevadb_isolation_read_engines from allegrosql.global_variables to avoid unexpected behavior after upgrade. 415 version44 = 44 416 // version45 introduces CONFIG_PRIV for SET CONFIG memexs. 417 version45 = 45 418 // version46 fix a bug in v3.1.1. 419 version46 = 46 420 // version47 add Source to bindings to indicate the way binding created. 421 version47 = 47 422 // version48 reset all deprecated concurrency related system-variables if they were all default value. 423 version48 = 48 424 // version49 introduces allegrosql.stats_extended causet. 425 version49 = 49 426 // version50 add allegrosql.schema_index_usage causet. 427 version50 = 50 428 // version51 introduces CreateTablespacePriv to allegrosql.user. 429 version51 = 51 430 ) 431 432 var ( 433 bootstrapVersion = []func(Stochastik, int64){ 434 upgradeToVer2, 435 upgradeToVer3, 436 upgradeToVer4, 437 upgradeToVer5, 438 upgradeToVer6, 439 upgradeToVer7, 440 upgradeToVer8, 441 upgradeToVer9, 442 upgradeToVer10, 443 upgradeToVer11, 444 upgradeToVer12, 445 upgradeToVer13, 446 upgradeToVer14, 447 upgradeToVer15, 448 upgradeToVer16, 449 upgradeToVer17, 450 upgradeToVer18, 451 upgradeToVer19, 452 upgradeToVer20, 453 upgradeToVer21, 454 upgradeToVer22, 455 upgradeToVer23, 456 upgradeToVer24, 457 upgradeToVer25, 458 upgradeToVer26, 459 upgradeToVer27, 460 upgradeToVer28, 461 upgradeToVer29, 462 upgradeToVer30, 463 upgradeToVer31, 464 upgradeToVer32, 465 upgradeToVer33, 466 upgradeToVer34, 467 upgradeToVer35, 468 upgradeToVer36, 469 upgradeToVer37, 470 upgradeToVer38, 471 upgradeToVer39, 472 upgradeToVer40, 473 upgradeToVer41, 474 upgradeToVer42, 475 upgradeToVer43, 476 upgradeToVer44, 477 upgradeToVer45, 478 upgradeToVer46, 479 upgradeToVer47, 480 upgradeToVer48, 481 upgradeToVer49, 482 upgradeToVer50, 483 upgradeToVer51, 484 } 485 ) 486 487 func checkBootstrapped(s Stochastik) (bool, error) { 488 // Check if system EDB exists. 489 _, err := s.InterDircute(context.Background(), fmt.Sprintf("USE %s;", allegrosql.SystemDB)) 490 if err != nil && schemareplicant.ErrDatabaseNotExists.NotEqual(err) { 491 logutil.BgLogger().Fatal("check bootstrap error", 492 zap.Error(err)) 493 } 494 // Check bootstrapped variable value in MilevaDB causet. 495 sVal, _, err := getMilevaDBVar(s, bootstrappedVar) 496 if err != nil { 497 if schemareplicant.ErrTableNotExists.Equal(err) { 498 return false, nil 499 } 500 return false, errors.Trace(err) 501 } 502 isBootstrapped := sVal == varTrue 503 if isBootstrapped { 504 // Make sure that doesn't affect the following operations. 505 if err = s.CommitTxn(context.Background()); err != nil { 506 return false, errors.Trace(err) 507 } 508 } 509 return isBootstrapped, nil 510 } 511 512 // getMilevaDBVar gets variable value from allegrosql.milevadb causet. 513 // Those variables are used by MilevaDB server. 514 func getMilevaDBVar(s Stochastik, name string) (sVal string, isNull bool, e error) { 515 allegrosql := fmt.Sprintf(`SELECT HIGH_PRIORITY VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s"`, 516 allegrosql.SystemDB, allegrosql.MilevaDBTable, name) 517 ctx := context.Background() 518 rs, err := s.InterDircute(ctx, allegrosql) 519 if err != nil { 520 return "", true, errors.Trace(err) 521 } 522 if len(rs) != 1 { 523 return "", true, errors.New("Wrong number of Recordset") 524 } 525 r := rs[0] 526 defer terror.Call(r.Close) 527 req := r.NewChunk() 528 err = r.Next(ctx, req) 529 if err != nil || req.NumRows() == 0 { 530 return "", true, errors.Trace(err) 531 } 532 event := req.GetRow(0) 533 if event.IsNull(0) { 534 return "", true, nil 535 } 536 return event.GetString(0), false, nil 537 } 538 539 // upgrade function will do some upgrade works, when the system is bootstrapped by low version MilevaDB server 540 // For example, add new system variables into allegrosql.global_variables causet. 541 func upgrade(s Stochastik) { 542 ver, err := getBootstrapVersion(s) 543 terror.MustNil(err) 544 if ver >= currentBootstrapVersion { 545 // It is already bootstrapped/upgraded by a higher version MilevaDB server. 546 return 547 } 548 // Do upgrade works then uFIDelate bootstrap version. 549 for _, upgrade := range bootstrapVersion { 550 upgrade(s, ver) 551 } 552 553 uFIDelateBootstrapVer(s) 554 _, err = s.InterDircute(context.Background(), "COMMIT") 555 556 if err != nil { 557 sleepTime := 1 * time.Second 558 logutil.BgLogger().Info("uFIDelate bootstrap ver failed", 559 zap.Error(err), zap.Duration("sleeping time", sleepTime)) 560 time.Sleep(sleepTime) 561 // Check if MilevaDB is already upgraded. 562 v, err1 := getBootstrapVersion(s) 563 if err1 != nil { 564 logutil.BgLogger().Fatal("upgrade failed", zap.Error(err1)) 565 } 566 if v >= currentBootstrapVersion { 567 // It is already bootstrapped/upgraded by a higher version MilevaDB server. 568 return 569 } 570 logutil.BgLogger().Fatal("[Upgrade] upgrade failed", 571 zap.Int64("from", ver), 572 zap.Int("to", currentBootstrapVersion), 573 zap.Error(err)) 574 } 575 } 576 577 // upgradeToVer2 uFIDelates to version 2. 578 func upgradeToVer2(s Stochastik, ver int64) { 579 if ver >= version2 { 580 return 581 } 582 // Version 2 add two system variable for DistALLEGROSQL concurrency controlling. 583 // Insert allegrosql related system variable. 584 distALLEGROSQLVars := []string{variable.MilevaDBDistALLEGROSQLScanConcurrency} 585 values := make([]string, 0, len(distALLEGROSQLVars)) 586 for _, v := range distALLEGROSQLVars { 587 value := fmt.Sprintf(`("%s", "%s")`, v, variable.SysVars[v].Value) 588 values = append(values, value) 589 } 590 allegrosql := fmt.Sprintf("INSERT HIGH_PRIORITY IGNORE INTO %s.%s VALUES %s;", allegrosql.SystemDB, allegrosql.GlobalVariablesTable, 591 strings.Join(values, ", ")) 592 mustInterDircute(s, allegrosql) 593 } 594 595 // upgradeToVer3 uFIDelates to version 3. 596 func upgradeToVer3(s Stochastik, ver int64) { 597 if ver >= version3 { 598 return 599 } 600 // Version 3 fix tx_read_only variable value. 601 allegrosql := fmt.Sprintf("UFIDelATE HIGH_PRIORITY %s.%s set variable_value = '0' where variable_name = 'tx_read_only';", 602 allegrosql.SystemDB, allegrosql.GlobalVariablesTable) 603 mustInterDircute(s, allegrosql) 604 } 605 606 // upgradeToVer4 uFIDelates to version 4. 607 func upgradeToVer4(s Stochastik, ver int64) { 608 if ver >= version4 { 609 return 610 } 611 allegrosql := CreateStatsMetaTable 612 mustInterDircute(s, allegrosql) 613 } 614 615 func upgradeToVer5(s Stochastik, ver int64) { 616 if ver >= version5 { 617 return 618 } 619 mustInterDircute(s, CreateStatsDefCaussTable) 620 mustInterDircute(s, CreateStatsBucketsTable) 621 } 622 623 func upgradeToVer6(s Stochastik, ver int64) { 624 if ver >= version6 { 625 return 626 } 627 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Super_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Show_db_priv`", schemareplicant.ErrDeferredCausetExists) 628 // For reasons of compatibility, set the non-exists privilege column value to 'Y', as MilevaDB doesn't check them in older versions. 629 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Super_priv='Y'") 630 } 631 632 func upgradeToVer7(s Stochastik, ver int64) { 633 if ver >= version7 { 634 return 635 } 636 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Process_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Drop_priv`", schemareplicant.ErrDeferredCausetExists) 637 // For reasons of compatibility, set the non-exists privilege column value to 'Y', as MilevaDB doesn't check them in older versions. 638 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Process_priv='Y'") 639 } 640 641 func upgradeToVer8(s Stochastik, ver int64) { 642 if ver >= version8 { 643 return 644 } 645 // This is a dummy upgrade, it checks whether upgradeToVer7 success, if not, do it again. 646 if _, err := s.InterDircute(context.Background(), "SELECT HIGH_PRIORITY `Process_priv` from allegrosql.user limit 0"); err == nil { 647 return 648 } 649 upgradeToVer7(s, ver) 650 } 651 652 func upgradeToVer9(s Stochastik, ver int64) { 653 if ver >= version9 { 654 return 655 } 656 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_user_priv`", schemareplicant.ErrDeferredCausetExists) 657 // For reasons of compatibility, set the non-exists privilege column value to 'Y', as MilevaDB doesn't check them in older versions. 658 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Trigger_priv='Y'") 659 } 660 661 func doReentrantDBS(s Stochastik, allegrosql string, ignorableErrs ...error) { 662 _, err := s.InterDircute(context.Background(), allegrosql) 663 for _, ignorableErr := range ignorableErrs { 664 if terror.ErrorEqual(err, ignorableErr) { 665 return 666 } 667 } 668 if err != nil { 669 logutil.BgLogger().Fatal("doReentrantDBS error", zap.Error(err)) 670 } 671 } 672 673 func upgradeToVer10(s Stochastik, ver int64) { 674 if ver >= version10 { 675 return 676 } 677 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_buckets CHANGE COLUMN `value` `upper_bound` BLOB NOT NULL", schemareplicant.ErrDeferredCausetNotExists, schemareplicant.ErrDeferredCausetExists) 678 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_buckets ADD COLUMN `lower_bound` BLOB", schemareplicant.ErrDeferredCausetExists) 679 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `null_count` bigint(64) NOT NULL DEFAULT 0", schemareplicant.ErrDeferredCausetExists) 680 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms DROP COLUMN distinct_ratio", dbs.ErrCantDropFieldOrKey) 681 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms DROP COLUMN use_count_to_estimate", dbs.ErrCantDropFieldOrKey) 682 } 683 684 func upgradeToVer11(s Stochastik, ver int64) { 685 if ver >= version11 { 686 return 687 } 688 _, err := s.InterDircute(context.Background(), "ALTER TABLE allegrosql.user ADD COLUMN `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Grant_priv`") 689 if err != nil { 690 if terror.ErrorEqual(err, schemareplicant.ErrDeferredCausetExists) { 691 return 692 } 693 logutil.BgLogger().Fatal("upgradeToVer11 error", zap.Error(err)) 694 } 695 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET References_priv='Y'") 696 } 697 698 func upgradeToVer12(s Stochastik, ver int64) { 699 if ver >= version12 { 700 return 701 } 702 ctx := context.Background() 703 _, err := s.InterDircute(ctx, "BEGIN") 704 terror.MustNil(err) 705 allegrosql := "SELECT HIGH_PRIORITY user, host, password FROM allegrosql.user WHERE password != ''" 706 rs, err := s.InterDircute(ctx, allegrosql) 707 if terror.ErrorEqual(err, embedded.ErrUnknownDeferredCauset) { 708 allegrosql := "SELECT HIGH_PRIORITY user, host, authentication_string FROM allegrosql.user WHERE authentication_string != ''" 709 rs, err = s.InterDircute(ctx, allegrosql) 710 } 711 terror.MustNil(err) 712 r := rs[0] 713 sqls := make([]string, 0, 1) 714 defer terror.Call(r.Close) 715 req := r.NewChunk() 716 it := chunk.NewIterator4Chunk(req) 717 err = r.Next(ctx, req) 718 for err == nil && req.NumRows() != 0 { 719 for event := it.Begin(); event != it.End(); event = it.Next() { 720 user := event.GetString(0) 721 host := event.GetString(1) 722 pass := event.GetString(2) 723 var newPass string 724 newPass, err = oldPasswordUpgrade(pass) 725 terror.MustNil(err) 726 uFIDelateALLEGROSQL := fmt.Sprintf(`UFIDelATE HIGH_PRIORITY allegrosql.user set password = "%s" where user="%s" and host="%s"`, newPass, user, host) 727 sqls = append(sqls, uFIDelateALLEGROSQL) 728 } 729 err = r.Next(ctx, req) 730 } 731 terror.MustNil(err) 732 733 for _, allegrosql := range sqls { 734 mustInterDircute(s, allegrosql) 735 } 736 737 allegrosql = fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES ("%s", "%d", "MilevaDB bootstrap version.") ON DUPLICATE KEY UFIDelATE VARIABLE_VALUE="%d"`, 738 allegrosql.SystemDB, allegrosql.MilevaDBTable, milevadbServerVersionVar, version12, version12) 739 mustInterDircute(s, allegrosql) 740 741 mustInterDircute(s, "COMMIT") 742 } 743 744 func upgradeToVer13(s Stochastik, ver int64) { 745 if ver >= version13 { 746 return 747 } 748 sqls := []string{ 749 "ALTER TABLE allegrosql.user ADD COLUMN `Create_tmp_block_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Super_priv`", 750 "ALTER TABLE allegrosql.user ADD COLUMN `Lock_blocks_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_tmp_block_priv`", 751 "ALTER TABLE allegrosql.user ADD COLUMN `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `InterDircute_priv`", 752 "ALTER TABLE allegrosql.user ADD COLUMN `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_view_priv`", 753 "ALTER TABLE allegrosql.user ADD COLUMN `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Show_view_priv`", 754 "ALTER TABLE allegrosql.user ADD COLUMN `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_routine_priv`", 755 "ALTER TABLE allegrosql.user ADD COLUMN `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_user_priv`", 756 } 757 ctx := context.Background() 758 for _, allegrosql := range sqls { 759 _, err := s.InterDircute(ctx, allegrosql) 760 if err != nil { 761 if terror.ErrorEqual(err, schemareplicant.ErrDeferredCausetExists) { 762 continue 763 } 764 logutil.BgLogger().Fatal("upgradeToVer13 error", zap.Error(err)) 765 } 766 } 767 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_tmp_block_priv='Y',Lock_blocks_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y',Event_priv='Y' WHERE Super_priv='Y'") 768 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_view_priv='Y',Show_view_priv='Y' WHERE Create_priv='Y'") 769 } 770 771 func upgradeToVer14(s Stochastik, ver int64) { 772 if ver >= version14 { 773 return 774 } 775 sqls := []string{ 776 "ALTER TABLE allegrosql.EDB ADD COLUMN `References_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Grant_priv`", 777 "ALTER TABLE allegrosql.EDB ADD COLUMN `Create_tmp_block_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Alter_priv`", 778 "ALTER TABLE allegrosql.EDB ADD COLUMN `Lock_blocks_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_tmp_block_priv`", 779 "ALTER TABLE allegrosql.EDB ADD COLUMN `Create_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Lock_blocks_priv`", 780 "ALTER TABLE allegrosql.EDB ADD COLUMN `Show_view_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_view_priv`", 781 "ALTER TABLE allegrosql.EDB ADD COLUMN `Create_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Show_view_priv`", 782 "ALTER TABLE allegrosql.EDB ADD COLUMN `Alter_routine_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Create_routine_priv`", 783 "ALTER TABLE allegrosql.EDB ADD COLUMN `Event_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `InterDircute_priv`", 784 "ALTER TABLE allegrosql.EDB ADD COLUMN `Trigger_priv` enum('N','Y') CHARACTER SET utf8 NOT NULL DEFAULT 'N' AFTER `Event_priv`", 785 } 786 ctx := context.Background() 787 for _, allegrosql := range sqls { 788 _, err := s.InterDircute(ctx, allegrosql) 789 if err != nil { 790 if terror.ErrorEqual(err, schemareplicant.ErrDeferredCausetExists) { 791 continue 792 } 793 logutil.BgLogger().Fatal("upgradeToVer14 error", zap.Error(err)) 794 } 795 } 796 } 797 798 func upgradeToVer15(s Stochastik, ver int64) { 799 if ver >= version15 { 800 return 801 } 802 var err error 803 _, err = s.InterDircute(context.Background(), CreateGCDeleteRangeTable) 804 if err != nil { 805 logutil.BgLogger().Fatal("upgradeToVer15 error", zap.Error(err)) 806 } 807 } 808 809 func upgradeToVer16(s Stochastik, ver int64) { 810 if ver >= version16 { 811 return 812 } 813 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `cm_sketch` blob", schemareplicant.ErrDeferredCausetExists) 814 } 815 816 func upgradeToVer17(s Stochastik, ver int64) { 817 if ver >= version17 { 818 return 819 } 820 doReentrantDBS(s, "ALTER TABLE allegrosql.user MODIFY User CHAR(32)") 821 } 822 823 func upgradeToVer18(s Stochastik, ver int64) { 824 if ver >= version18 { 825 return 826 } 827 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `tot_col_size` bigint(64) NOT NULL DEFAULT 0", schemareplicant.ErrDeferredCausetExists) 828 } 829 830 func upgradeToVer19(s Stochastik, ver int64) { 831 if ver >= version19 { 832 return 833 } 834 doReentrantDBS(s, "ALTER TABLE allegrosql.EDB MODIFY User CHAR(32)") 835 doReentrantDBS(s, "ALTER TABLE allegrosql.blocks_priv MODIFY User CHAR(32)") 836 doReentrantDBS(s, "ALTER TABLE allegrosql.columns_priv MODIFY User CHAR(32)") 837 } 838 839 func upgradeToVer20(s Stochastik, ver int64) { 840 if ver >= version20 { 841 return 842 } 843 doReentrantDBS(s, CreateStatsFeedbackTable) 844 } 845 846 func upgradeToVer21(s Stochastik, ver int64) { 847 if ver >= version21 { 848 return 849 } 850 mustInterDircute(s, CreateGCDeleteRangeDoneTable) 851 852 doReentrantDBS(s, "ALTER TABLE allegrosql.gc_delete_range DROP INDEX job_id", dbs.ErrCantDropFieldOrKey) 853 doReentrantDBS(s, "ALTER TABLE allegrosql.gc_delete_range ADD UNIQUE INDEX delete_range_index (job_id, element_id)", dbs.ErrDupKeyName) 854 doReentrantDBS(s, "ALTER TABLE allegrosql.gc_delete_range DROP INDEX element_id", dbs.ErrCantDropFieldOrKey) 855 } 856 857 func upgradeToVer22(s Stochastik, ver int64) { 858 if ver >= version22 { 859 return 860 } 861 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `stats_ver` bigint(64) NOT NULL DEFAULT 0", schemareplicant.ErrDeferredCausetExists) 862 } 863 864 func upgradeToVer23(s Stochastik, ver int64) { 865 if ver >= version23 { 866 return 867 } 868 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `flag` bigint(64) NOT NULL DEFAULT 0", schemareplicant.ErrDeferredCausetExists) 869 } 870 871 // writeSystemTZ writes system timezone info into allegrosql.milevadb 872 func writeSystemTZ(s Stochastik) { 873 allegrosql := fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES ("%s", "%s", "MilevaDB Global System Timezone.") ON DUPLICATE KEY UFIDelATE VARIABLE_VALUE="%s"`, 874 allegrosql.SystemDB, allegrosql.MilevaDBTable, milevadbSystemTZ, timeutil.InferSystemTZ(), timeutil.InferSystemTZ()) 875 mustInterDircute(s, allegrosql) 876 } 877 878 // upgradeToVer24 initializes `System` timezone according to docs/design/2020-09-10-adding-tz-env.md 879 func upgradeToVer24(s Stochastik, ver int64) { 880 if ver >= version24 { 881 return 882 } 883 writeSystemTZ(s) 884 } 885 886 // upgradeToVer25 uFIDelates milevadb_max_chunk_size to new low bound value 32 if previous value is small than 32. 887 func upgradeToVer25(s Stochastik, ver int64) { 888 if ver >= version25 { 889 return 890 } 891 allegrosql := fmt.Sprintf("UFIDelATE HIGH_PRIORITY %[1]s.%[2]s SET VARIABLE_VALUE = '%[4]d' WHERE VARIABLE_NAME = '%[3]s' AND VARIABLE_VALUE < %[4]d", 892 allegrosql.SystemDB, allegrosql.GlobalVariablesTable, variable.MilevaDBMaxChunkSize, variable.DefInitChunkSize) 893 mustInterDircute(s, allegrosql) 894 } 895 896 func upgradeToVer26(s Stochastik, ver int64) { 897 if ver >= version26 { 898 return 899 } 900 mustInterDircute(s, CreateRoleEdgesTable) 901 mustInterDircute(s, CreateDefaultRolesTable) 902 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Create_role_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 903 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Drop_role_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 904 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Account_locked` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 905 // user with Create_user_Priv privilege should have Create_view_priv and Show_view_priv after upgrade to v3.0 906 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_role_priv='Y',Drop_role_priv='Y' WHERE Create_user_priv='Y'") 907 // user with Create_Priv privilege should have Create_view_priv and Show_view_priv after upgrade to v3.0 908 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_view_priv='Y',Show_view_priv='Y' WHERE Create_priv='Y'") 909 } 910 911 func upgradeToVer27(s Stochastik, ver int64) { 912 if ver >= version27 { 913 return 914 } 915 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `correlation` double NOT NULL DEFAULT 0", schemareplicant.ErrDeferredCausetExists) 916 } 917 918 func upgradeToVer28(s Stochastik, ver int64) { 919 if ver >= version28 { 920 return 921 } 922 doReentrantDBS(s, CreateBindInfoTable) 923 } 924 925 func upgradeToVer29(s Stochastik, ver int64) { 926 // upgradeToVer29 only need to be run when the current version is 28. 927 if ver != version28 { 928 return 929 } 930 doReentrantDBS(s, "ALTER TABLE allegrosql.bind_info change create_time create_time timestamp(3)") 931 doReentrantDBS(s, "ALTER TABLE allegrosql.bind_info change uFIDelate_time uFIDelate_time timestamp(3)") 932 doReentrantDBS(s, "ALTER TABLE allegrosql.bind_info add index sql_index (original_sql(1024),default_db(1024))", dbs.ErrDupKeyName) 933 } 934 935 func upgradeToVer30(s Stochastik, ver int64) { 936 if ver >= version30 { 937 return 938 } 939 mustInterDircute(s, CreateStatsTopNTable) 940 } 941 942 func upgradeToVer31(s Stochastik, ver int64) { 943 if ver >= version31 { 944 return 945 } 946 doReentrantDBS(s, "ALTER TABLE allegrosql.stats_histograms ADD COLUMN `last_analyze_pos` blob default null", schemareplicant.ErrDeferredCausetExists) 947 } 948 949 func upgradeToVer32(s Stochastik, ver int64) { 950 if ver >= version32 { 951 return 952 } 953 doReentrantDBS(s, "ALTER TABLE allegrosql.blocks_priv MODIFY block_priv SET('Select','Insert','UFIDelate','Delete','Create','Drop','Grant', 'Index', 'Alter', 'Create View', 'Show View', 'Trigger', 'References')") 954 } 955 956 func upgradeToVer33(s Stochastik, ver int64) { 957 if ver >= version33 { 958 return 959 } 960 doReentrantDBS(s, CreateExprPushdownBlacklist) 961 } 962 963 func upgradeToVer34(s Stochastik, ver int64) { 964 if ver >= version34 { 965 return 966 } 967 doReentrantDBS(s, CreateOptMemruleBlacklist) 968 } 969 970 func upgradeToVer35(s Stochastik, ver int64) { 971 if ver >= version35 { 972 return 973 } 974 allegrosql := fmt.Sprintf("UFIDelATE HIGH_PRIORITY %s.%s SET VARIABLE_NAME = '%s' WHERE VARIABLE_NAME = 'milevadb_back_off_weight'", 975 allegrosql.SystemDB, allegrosql.GlobalVariablesTable, variable.MilevaDBBackOffWeight) 976 mustInterDircute(s, allegrosql) 977 } 978 979 func upgradeToVer36(s Stochastik, ver int64) { 980 if ver >= version36 { 981 return 982 } 983 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Shutdown_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 984 // A root user will have those privileges after upgrading. 985 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Shutdown_priv='Y' where Super_priv='Y'") 986 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_tmp_block_priv='Y',Lock_blocks_priv='Y',Create_routine_priv='Y',Alter_routine_priv='Y',Event_priv='Y' WHERE Super_priv='Y'") 987 } 988 989 func upgradeToVer37(s Stochastik, ver int64) { 990 if ver >= version37 { 991 return 992 } 993 // when upgrade from old milevadb and no 'milevadb_enable_window_function' in GLOBAL_VARIABLES, init it with 0. 994 allegrosql := fmt.Sprintf("INSERT IGNORE INTO %s.%s (`VARIABLE_NAME`, `VARIABLE_VALUE`) VALUES ('%s', '%d')", 995 allegrosql.SystemDB, allegrosql.GlobalVariablesTable, variable.MilevaDBEnableWindowFunction, 0) 996 mustInterDircute(s, allegrosql) 997 } 998 999 func upgradeToVer38(s Stochastik, ver int64) { 1000 if ver >= version38 { 1001 return 1002 } 1003 var err error 1004 _, err = s.InterDircute(context.Background(), CreateGlobalPrivTable) 1005 if err != nil { 1006 logutil.BgLogger().Fatal("upgradeToVer38 error", zap.Error(err)) 1007 } 1008 } 1009 1010 func upgradeToVer39(s Stochastik, ver int64) { 1011 if ver >= version39 { 1012 return 1013 } 1014 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Reload_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1015 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `File_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1016 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Reload_priv='Y' where Super_priv='Y'") 1017 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET File_priv='Y' where Super_priv='Y'") 1018 } 1019 1020 func writeNewDefCauslationParameter(s Stochastik, flag bool) { 1021 comment := "If the new collations are enabled. Do not edit it." 1022 b := varFalse 1023 if flag { 1024 b = varTrue 1025 } 1026 allegrosql := fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES ("%s", '%s', '%s') ON DUPLICATE KEY UFIDelATE VARIABLE_VALUE='%s'`, 1027 allegrosql.SystemDB, allegrosql.MilevaDBTable, milevadbNewDefCauslationEnabled, b, comment, b) 1028 mustInterDircute(s, allegrosql) 1029 } 1030 1031 func upgradeToVer40(s Stochastik, ver int64) { 1032 if ver >= version40 { 1033 return 1034 } 1035 // There is no way to enable new collation for an existing MilevaDB cluster. 1036 writeNewDefCauslationParameter(s, false) 1037 } 1038 1039 func upgradeToVer41(s Stochastik, ver int64) { 1040 if ver >= version41 { 1041 return 1042 } 1043 doReentrantDBS(s, "ALTER TABLE allegrosql.user CHANGE `password` `authentication_string` TEXT", schemareplicant.ErrDeferredCausetExists, schemareplicant.ErrDeferredCausetNotExists) 1044 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `password` TEXT as (`authentication_string`)", schemareplicant.ErrDeferredCausetExists) 1045 } 1046 1047 // writeDefaultExprPushDownBlacklist writes default expr pushdown blacklist into allegrosql.expr_pushdown_blacklist 1048 func writeDefaultExprPushDownBlacklist(s Stochastik) { 1049 mustInterDircute(s, "INSERT HIGH_PRIORITY INTO allegrosql.expr_pushdown_blacklist VALUES"+ 1050 "('date_add','tiflash', 'DST(daylight saving time) does not take effect in TiFlash date_add'),"+ 1051 "('cast','tiflash', 'Behavior of some corner cases(overflow, truncate etc) is different in TiFlash and MilevaDB')") 1052 } 1053 1054 func upgradeToVer42(s Stochastik, ver int64) { 1055 if ver >= version42 { 1056 return 1057 } 1058 doReentrantDBS(s, "ALTER TABLE allegrosql.expr_pushdown_blacklist ADD COLUMN `store_type` char(100) NOT NULL DEFAULT 'einsteindb,tiflash,milevadb'", schemareplicant.ErrDeferredCausetExists) 1059 doReentrantDBS(s, "ALTER TABLE allegrosql.expr_pushdown_blacklist ADD COLUMN `reason` varchar(200)", schemareplicant.ErrDeferredCausetExists) 1060 writeDefaultExprPushDownBlacklist(s) 1061 } 1062 1063 // Convert memex summary global variables to non-empty values. 1064 func writeStmtSummaryVars(s Stochastik) { 1065 allegrosql := fmt.Sprintf("UFIDelATE %s.%s SET variable_value='%%s' WHERE variable_name='%%s' AND variable_value=''", allegrosql.SystemDB, allegrosql.GlobalVariablesTable) 1066 stmtSummaryConfig := config.GetGlobalConfig().StmtSummary 1067 mustInterDircute(s, fmt.Sprintf(allegrosql, variable.BoolToIntStr(stmtSummaryConfig.Enable), variable.MilevaDBEnableStmtSummary)) 1068 mustInterDircute(s, fmt.Sprintf(allegrosql, variable.BoolToIntStr(stmtSummaryConfig.EnableInternalQuery), variable.MilevaDBStmtSummaryInternalQuery)) 1069 mustInterDircute(s, fmt.Sprintf(allegrosql, strconv.Itoa(stmtSummaryConfig.RefreshInterval), variable.MilevaDBStmtSummaryRefreshInterval)) 1070 mustInterDircute(s, fmt.Sprintf(allegrosql, strconv.Itoa(stmtSummaryConfig.HistorySize), variable.MilevaDBStmtSummaryHistorySize)) 1071 mustInterDircute(s, fmt.Sprintf(allegrosql, strconv.FormatUint(uint64(stmtSummaryConfig.MaxStmtCount), 10), variable.MilevaDBStmtSummaryMaxStmtCount)) 1072 mustInterDircute(s, fmt.Sprintf(allegrosql, strconv.FormatUint(uint64(stmtSummaryConfig.MaxALLEGROSQLLength), 10), variable.MilevaDBStmtSummaryMaxALLEGROSQLLength)) 1073 } 1074 1075 func upgradeToVer43(s Stochastik, ver int64) { 1076 if ver >= version43 { 1077 return 1078 } 1079 writeStmtSummaryVars(s) 1080 } 1081 1082 func upgradeToVer44(s Stochastik, ver int64) { 1083 if ver >= version44 { 1084 return 1085 } 1086 mustInterDircute(s, "DELETE FROM allegrosql.global_variables where variable_name = \"milevadb_isolation_read_engines\"") 1087 } 1088 1089 func upgradeToVer45(s Stochastik, ver int64) { 1090 if ver >= version45 { 1091 return 1092 } 1093 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Config_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1094 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Config_priv='Y' where Super_priv='Y'") 1095 } 1096 1097 // In v3.1.1, we wrongly replace the context of upgradeToVer39 with upgradeToVer44. If we upgrade from v3.1.1 to a newer version, 1098 // upgradeToVer39 will be missed. So we redo upgradeToVer39 here to make sure the upgrading from v3.1.1 succeed. 1099 func upgradeToVer46(s Stochastik, ver int64) { 1100 if ver >= version46 { 1101 return 1102 } 1103 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Reload_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1104 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `File_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1105 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Reload_priv='Y' where Super_priv='Y'") 1106 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET File_priv='Y' where Super_priv='Y'") 1107 } 1108 1109 func upgradeToVer47(s Stochastik, ver int64) { 1110 if ver >= version47 { 1111 return 1112 } 1113 doReentrantDBS(s, "ALTER TABLE allegrosql.bind_info ADD COLUMN `source` varchar(10) NOT NULL default 'unknown'", schemareplicant.ErrDeferredCausetExists) 1114 } 1115 1116 func upgradeToVer48(s Stochastik, ver int64) { 1117 if ver >= version48 { 1118 return 1119 } 1120 defValues := map[string]string{ 1121 variable.MilevaDBIndexLookupConcurrency: "4", 1122 variable.MilevaDBIndexLookupJoinConcurrency: "4", 1123 variable.MilevaDBHashAggFinalConcurrency: "4", 1124 variable.MilevaDBHashAggPartialConcurrency: "4", 1125 variable.MilevaDBWindowConcurrency: "4", 1126 variable.MilevaDBProjectionConcurrency: "4", 1127 variable.MilevaDBHashJoinConcurrency: "5", 1128 } 1129 names := make([]string, 0, len(defValues)) 1130 for n := range defValues { 1131 names = append(names, n) 1132 } 1133 1134 selectALLEGROSQL := "select HIGH_PRIORITY * from allegrosql.global_variables where variable_name in ('" + strings.Join(names, quoteCommaQuote) + "')" 1135 ctx := context.Background() 1136 rs, err := s.InterDircute(ctx, selectALLEGROSQL) 1137 terror.MustNil(err) 1138 r := rs[0] 1139 defer terror.Call(r.Close) 1140 req := r.NewChunk() 1141 it := chunk.NewIterator4Chunk(req) 1142 err = r.Next(ctx, req) 1143 for err == nil && req.NumRows() != 0 { 1144 for event := it.Begin(); event != it.End(); event = it.Next() { 1145 n := strings.ToLower(event.GetString(0)) 1146 v := event.GetString(1) 1147 if defValue, ok := defValues[n]; !ok || defValue != v { 1148 return 1149 } 1150 } 1151 err = r.Next(ctx, req) 1152 } 1153 terror.MustNil(err) 1154 1155 mustInterDircute(s, "BEGIN") 1156 v := strconv.Itoa(variable.ConcurrencyUnset) 1157 allegrosql := fmt.Sprintf("UFIDelATE %s.%s SET variable_value='%%s' WHERE variable_name='%%s'", allegrosql.SystemDB, allegrosql.GlobalVariablesTable) 1158 for _, name := range names { 1159 mustInterDircute(s, fmt.Sprintf(allegrosql, v, name)) 1160 } 1161 mustInterDircute(s, "COMMIT") 1162 } 1163 1164 func upgradeToVer49(s Stochastik, ver int64) { 1165 if ver >= version49 { 1166 return 1167 } 1168 doReentrantDBS(s, CreateStatsExtended) 1169 } 1170 1171 func upgradeToVer50(s Stochastik, ver int64) { 1172 if ver >= version50 { 1173 return 1174 } 1175 doReentrantDBS(s, CreateSchemaIndexUsageTable) 1176 } 1177 1178 func upgradeToVer51(s Stochastik, ver int64) { 1179 if ver >= version51 { 1180 return 1181 } 1182 doReentrantDBS(s, "ALTER TABLE allegrosql.user ADD COLUMN `Create_blockspace_priv` ENUM('N','Y') DEFAULT 'N'", schemareplicant.ErrDeferredCausetExists) 1183 mustInterDircute(s, "UFIDelATE HIGH_PRIORITY allegrosql.user SET Create_blockspace_priv='Y' where Super_priv='Y'") 1184 } 1185 1186 // uFIDelateBootstrapVer uFIDelates bootstrap version variable in allegrosql.MilevaDB causet. 1187 func uFIDelateBootstrapVer(s Stochastik) { 1188 // UFIDelate bootstrap version. 1189 allegrosql := fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES ("%s", "%d", "MilevaDB bootstrap version.") ON DUPLICATE KEY UFIDelATE VARIABLE_VALUE="%d"`, 1190 allegrosql.SystemDB, allegrosql.MilevaDBTable, milevadbServerVersionVar, currentBootstrapVersion, currentBootstrapVersion) 1191 mustInterDircute(s, allegrosql) 1192 } 1193 1194 // getBootstrapVersion gets bootstrap version from allegrosql.milevadb causet; 1195 func getBootstrapVersion(s Stochastik) (int64, error) { 1196 sVal, isNull, err := getMilevaDBVar(s, milevadbServerVersionVar) 1197 if err != nil { 1198 return 0, errors.Trace(err) 1199 } 1200 if isNull { 1201 return 0, nil 1202 } 1203 return strconv.ParseInt(sVal, 10, 64) 1204 } 1205 1206 // doDBSWorks executes DBS memexs in bootstrap stage. 1207 func doDBSWorks(s Stochastik) { 1208 // Create a test database. 1209 mustInterDircute(s, "CREATE DATABASE IF NOT EXISTS test") 1210 // Create system EDB. 1211 mustInterDircute(s, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s;", allegrosql.SystemDB)) 1212 // Create user causet. 1213 mustInterDircute(s, CreateUserTable) 1214 // Create privilege blocks. 1215 mustInterDircute(s, CreateGlobalPrivTable) 1216 mustInterDircute(s, CreateDBPrivTable) 1217 mustInterDircute(s, CreateTablePrivTable) 1218 mustInterDircute(s, CreateDeferredCausetPrivTable) 1219 // Create global system variable causet. 1220 mustInterDircute(s, CreateGlobalVariablesTable) 1221 // Create MilevaDB causet. 1222 mustInterDircute(s, CreateMilevaDBTable) 1223 // Create help causet. 1224 mustInterDircute(s, CreateHelpTopic) 1225 // Create stats_spacetime causet. 1226 mustInterDircute(s, CreateStatsMetaTable) 1227 // Create stats_columns causet. 1228 mustInterDircute(s, CreateStatsDefCaussTable) 1229 // Create stats_buckets causet. 1230 mustInterDircute(s, CreateStatsBucketsTable) 1231 // Create gc_delete_range causet. 1232 mustInterDircute(s, CreateGCDeleteRangeTable) 1233 // Create gc_delete_range_done causet. 1234 mustInterDircute(s, CreateGCDeleteRangeDoneTable) 1235 // Create stats_feedback causet. 1236 mustInterDircute(s, CreateStatsFeedbackTable) 1237 // Create role_edges causet. 1238 mustInterDircute(s, CreateRoleEdgesTable) 1239 // Create default_roles causet. 1240 mustInterDircute(s, CreateDefaultRolesTable) 1241 // Create bind_info causet. 1242 mustInterDircute(s, CreateBindInfoTable) 1243 // Create stats_topn_store causet. 1244 mustInterDircute(s, CreateStatsTopNTable) 1245 // Create expr_pushdown_blacklist causet. 1246 mustInterDircute(s, CreateExprPushdownBlacklist) 1247 // Create opt_rule_blacklist causet. 1248 mustInterDircute(s, CreateOptMemruleBlacklist) 1249 // Create stats_extended causet. 1250 mustInterDircute(s, CreateStatsExtended) 1251 // Create schema_index_usage. 1252 mustInterDircute(s, CreateSchemaIndexUsageTable) 1253 } 1254 1255 // doDMLWorks executes DML memexs in bootstrap stage. 1256 // All the memexs run in a single transaction. 1257 func doDMLWorks(s Stochastik) { 1258 mustInterDircute(s, "BEGIN") 1259 1260 // Insert a default user with empty password. 1261 mustInterDircute(s, `INSERT HIGH_PRIORITY INTO allegrosql.user VALUES 1262 ("%", "root", "", "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")`) 1263 1264 // Init global system variables causet. 1265 values := make([]string, 0, len(variable.SysVars)) 1266 for k, v := range variable.SysVars { 1267 // Stochastik only variable should not be inserted. 1268 if v.Scope != variable.ScopeStochastik { 1269 vVal := v.Value 1270 if v.Name == variable.MilevaDBTxnMode && config.GetGlobalConfig().CausetStore == "einsteindb" { 1271 vVal = "pessimistic" 1272 } 1273 if v.Name == variable.MilevaDBRowFormatVersion { 1274 vVal = strconv.Itoa(variable.DefMilevaDBRowFormatV2) 1275 } 1276 if v.Name == variable.MilevaDBEnableClusteredIndex { 1277 vVal = "1" 1278 } 1279 if v.Name == variable.MilevaDBPartitionPruneMode { 1280 vVal = string(variable.StaticOnly) 1281 if flag.Lookup("test.v") != nil || flag.Lookup("check.v") != nil || config.CheckTableBeforeDrop { 1282 // enable Dynamic Prune by default in test case. 1283 vVal = string(variable.DynamicOnly) 1284 } 1285 } 1286 value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), vVal) 1287 values = append(values, value) 1288 } 1289 } 1290 allegrosql := fmt.Sprintf("INSERT HIGH_PRIORITY INTO %s.%s VALUES %s;", allegrosql.SystemDB, allegrosql.GlobalVariablesTable, 1291 strings.Join(values, ", ")) 1292 mustInterDircute(s, allegrosql) 1293 1294 allegrosql = fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES("%s", "%s", "Bootstrap flag. Do not delete.") 1295 ON DUPLICATE KEY UFIDelATE VARIABLE_VALUE="%s"`, 1296 allegrosql.SystemDB, allegrosql.MilevaDBTable, bootstrappedVar, varTrue, varTrue) 1297 mustInterDircute(s, allegrosql) 1298 1299 allegrosql = fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES("%s", "%d", "Bootstrap version. Do not delete.")`, 1300 allegrosql.SystemDB, allegrosql.MilevaDBTable, milevadbServerVersionVar, currentBootstrapVersion) 1301 mustInterDircute(s, allegrosql) 1302 1303 writeSystemTZ(s) 1304 1305 writeNewDefCauslationParameter(s, config.GetGlobalConfig().NewDefCauslationsEnabledOnFirstBootstrap) 1306 1307 writeDefaultExprPushDownBlacklist(s) 1308 1309 writeStmtSummaryVars(s) 1310 1311 _, err := s.InterDircute(context.Background(), "COMMIT") 1312 if err != nil { 1313 sleepTime := 1 * time.Second 1314 logutil.BgLogger().Info("doDMLWorks failed", zap.Error(err), zap.Duration("sleeping time", sleepTime)) 1315 time.Sleep(sleepTime) 1316 // Check if MilevaDB is already bootstrapped. 1317 b, err1 := checkBootstrapped(s) 1318 if err1 != nil { 1319 logutil.BgLogger().Fatal("doDMLWorks failed", zap.Error(err1)) 1320 } 1321 if b { 1322 return 1323 } 1324 logutil.BgLogger().Fatal("doDMLWorks failed", zap.Error(err)) 1325 } 1326 } 1327 1328 func mustInterDircute(s Stochastik, allegrosql string) { 1329 _, err := s.InterDircute(context.Background(), allegrosql) 1330 if err != nil { 1331 debug.PrintStack() 1332 logutil.BgLogger().Fatal("mustInterDircute error", zap.Error(err)) 1333 } 1334 } 1335 1336 // oldPasswordUpgrade upgrade password to MyALLEGROSQL compatible format 1337 func oldPasswordUpgrade(pass string) (string, error) { 1338 hash1, err := hex.DecodeString(pass) 1339 if err != nil { 1340 return "", errors.Trace(err) 1341 } 1342 1343 hash2 := auth.Sha1Hash(hash1) 1344 newpass := fmt.Sprintf("*%X", hash2) 1345 return newpass, nil 1346 }