github.com/whtcorpsinc/milevadb-prod@v0.0.0-20211104133533-f57f4be3b597/causetstore/stochastik/bootstrap_test.go (about)

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