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  }