diff --git a/bootstrap.go b/bootstrap.go new file mode 100644 index 0000000000..cc89b776bf --- /dev/null +++ b/bootstrap.go @@ -0,0 +1,62 @@ +// Copyright 2013 The ql Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSES/QL-LICENSE file. + +// Copyright 2015 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package tidb + +import ( + "fmt" + + "github.com/ngaut/log" + mysql "github.com/pingcap/tidb/mysqldef" + "github.com/pingcap/tidb/util/errors" + "github.com/pingcap/tidb/util/errors2" +) + +// Bootstrap initiates system DB for a store. +func bootstrap(s *session) { + // Create a test database. + _, err := s.Execute("CREATE DATABASE IF NOT EXISTS test") + if err != nil { + log.Fatal(err) + } + + // Check if system db exists. + _, err = s.Execute(fmt.Sprintf("USE %s;", mysql.SystemDB)) + if err == nil { + // We have already finished bootstrap. + return + } else if !errors2.ErrorEqual(err, errors.ErrDatabaseNotExist) { + log.Fatal(err) + } + _, err = s.Execute(fmt.Sprintf("CREATE DATABASE %s;", mysql.SystemDB)) + if err != nil { + log.Fatal(err) + } + initUserTable(s) +} + +func initUserTable(s *session) { + _, err := s.Execute(mysql.CreateUserTable) + if err != nil { + log.Fatal(err) + } + // Insert a default user with empty password. + _, err = s.Execute(`INSERT INTO mysql.user VALUES ("localhost", "root", ""), ("127.0.0.1", "root", "");`) + if err != nil { + log.Fatal(err) + } +} diff --git a/plan/plans/info_test.go b/plan/plans/info_test.go index b04c33d9ed..ddff3704f5 100644 --- a/plan/plans/info_test.go +++ b/plan/plans/info_test.go @@ -83,7 +83,7 @@ func (p *testInfoSchemaSuit) TestInfoSchema(c *C) { cnt = mustQuery(c, testDB, "select * from information_schema.columns") c.Assert(cnt, Greater, 0) cnt = mustQuery(c, testDB, "select * from information_schema.statistics") - c.Assert(cnt, Equals, 0) + c.Assert(cnt, Equals, 2) cnt = mustQuery(c, testDB, "select * from information_schema.character_sets") c.Assert(cnt, Greater, 0) cnt = mustQuery(c, testDB, "select * from information_schema.collations") diff --git a/session.go b/session.go index addecd44ab..33ec018de8 100644 --- a/session.go +++ b/session.go @@ -398,5 +398,11 @@ func CreateSession(store kv.Storage) (Session, error) { variable.BindSessionVars(s) variable.GetSessionVars(s).SetStatusFlag(mysql.ServerStatusAutocommit, true) + b, ok := storeBootstrapped[store.UUID()] + if !ok || !b { + bootstrap(s) + storeBootstrapped[store.UUID()] = true + } + // Add auth here return s, nil } diff --git a/table/tables/tables_test.go b/table/tables/tables_test.go index ce53b91e92..042f5fb11c 100644 --- a/table/tables/tables_test.go +++ b/table/tables/tables_test.go @@ -41,13 +41,11 @@ type testSuite struct { func (ts *testSuite) SetUpSuite(c *C) { driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}} - store, err := driver.Open("memory") + store, err := driver.Open("memory-tables-test") c.Check(err, IsNil) ts.store = store ts.se, err = tidb.CreateSession(ts.store) c.Assert(err, IsNil) - _, err = ts.se.Execute("CREATE DATABASE test") - c.Assert(err, IsNil) } func (ts *testSuite) TestBasic(c *C) { diff --git a/tidb-server/main.go b/tidb-server/main.go index 3dc0a4c3ad..1d5d4dbf9a 100644 --- a/tidb-server/main.go +++ b/tidb-server/main.go @@ -52,7 +52,6 @@ func main() { if err != nil { log.Fatal(err) } - server.Bootstrap(store) var driver server.IDriver driver = server.NewTiDBDriver(store) diff --git a/tidb-server/server/driver_tidb.go b/tidb-server/server/driver_tidb.go index 5a1e1706e3..25c3870eb2 100644 --- a/tidb-server/server/driver_tidb.go +++ b/tidb-server/server/driver_tidb.go @@ -15,13 +15,11 @@ package server import ( "github.com/juju/errors" - "github.com/ngaut/log" "github.com/pingcap/tidb" "github.com/pingcap/tidb/field" "github.com/pingcap/tidb/kv" mysql "github.com/pingcap/tidb/mysqldef" "github.com/pingcap/tidb/rset" - tidberrors "github.com/pingcap/tidb/util/errors" "github.com/pingcap/tidb/util/errors2" ) @@ -274,40 +272,3 @@ func convertColumnInfo(fld *field.ResultField) (ci *ColumnInfo) { ci.Type = uint8(fld.Tp) return } - -// Bootstrap initiates TiDB server. -func Bootstrap(store kv.Storage) { - td := NewTiDBDriver(store) - tc, err := td.OpenCtx(defaultCapability, mysql.DefaultCollationID, "") - defer tc.Close() - if err != nil { - log.Fatal(err) - } - // Create a test database. - _, err = tc.Execute("CREATE DATABASE IF NOT EXISTS test") - if err != nil { - log.Fatal(err) - } - - // Check if mysql db exists. - _, err = tc.Execute("USE mysql;") - if err == nil { - // We have already finished bootstrap. - return - } else if !errors2.ErrorEqual(err, tidberrors.ErrDatabaseNotExist) { - log.Fatal(err) - } - _, err = tc.Execute("CREATE DATABASE mysql;") - if err != nil { - log.Fatal(err) - } - _, err = tc.Execute("CREATE TABLE mysql.user (Host CHAR(64), User CHAR(16), Password CHAR(41), PRIMARY KEY (Host, User));") - if err != nil { - log.Fatal(err) - } - // Insert a default user with empty password. - _, err = tc.Execute(`INSERT INTO mysql.user VALUES ("localhost", "root", ""), ("127.0.0.1", "root", "");`) - if err != nil { - log.Fatal(err) - } -} diff --git a/tidb-server/server/server_test.go b/tidb-server/server/server_test.go index fa1288d1fe..63c12675fd 100644 --- a/tidb-server/server/server_test.go +++ b/tidb-server/server/server_test.go @@ -219,24 +219,3 @@ func runTestConcurrentUpdate(c *C) { c.Assert(err, IsNil) }) } - -func runTestBootstrap(c *C) { - runTests(c, dsn, func(dbt *DBTest) { - dbt.mustExec("USE mysql;") - rows := dbt.mustQuery("select * from mysql.user;") - c.Assert(rows.Next(), IsTrue) - var host, user, password string - err := rows.Scan(&host, &user, &password) - c.Assert(err, IsNil) - c.Assert(host, Equals, "localhost") - c.Assert(user, Equals, "root") - c.Assert(password, Equals, "") - - c.Assert(rows.Next(), IsTrue) - err = rows.Scan(&host, &user, &password) - c.Assert(err, IsNil) - c.Assert(host, Equals, "127.0.0.1") - c.Assert(user, Equals, "root") - c.Assert(password, Equals, "") - }) -} diff --git a/tidb-server/server/tidb_test.go b/tidb-server/server/tidb_test.go index cedd8555a7..9e5fea33ee 100644 --- a/tidb-server/server/tidb_test.go +++ b/tidb-server/server/tidb_test.go @@ -30,7 +30,6 @@ var _ = Suite(new(TidbTestSuite)) func (ts *TidbTestSuite) SetUpSuite(c *C) { store, err := tidb.NewStore("memory:///tmp/tidb") c.Assert(err, IsNil) - Bootstrap(store) ts.tidbdrv = NewTiDBDriver(store) cfg := &Config{ Addr: ":4001", @@ -70,7 +69,3 @@ func (ts *TidbTestSuite) TestPreparedString(c *C) { func (ts *TidbTestSuite) TestConcurrentUpdate(c *C) { runTestConcurrentUpdate(c) } - -func (ts *TidbTestSuite) TestBootstrap(c *C) { - runTestBootstrap(c) -} diff --git a/tidb.go b/tidb.go index 263c775fa6..5d54c26522 100644 --- a/tidb.go +++ b/tidb.go @@ -81,6 +81,8 @@ var ( Debug = true // PprofAddr is the pprof url. PprofAddr = "localhost:8888" + // store.UUID()-> IfBootstrapped + storeBootstrapped = make(map[string]bool) ) // Compile is safe for concurrent use by multiple goroutines. @@ -237,7 +239,7 @@ func NewStore(uri string) (kv.Storage, error) { } s, err := d.Open(schema) - + storeBootstrapped[s.UUID()] = false return s, errors.Trace(err) } diff --git a/tidb_test.go b/tidb_test.go index 4347b6cc1c..5b6439005d 100644 --- a/tidb_test.go +++ b/tidb_test.go @@ -834,6 +834,22 @@ func (s *testSessionSuite) TestBit(c *C) { c.Assert(err, NotNil) } +func (s *testSessionSuite) TestBootstrap(c *C) { + store := newStore(c, s.dbName) + se := newSession(c, store, s.dbName) + mustExecSQL(c, se, "USE mysql;") + r := mustExecSQL(c, se, `select * from user;`) + row, err := r.Next() + c.Assert(err, IsNil) + c.Assert(row, NotNil) + match(c, row.Data, "localhost", "root", "") + row, err = r.Next() + c.Assert(err, IsNil) + c.Assert(row, NotNil) + match(c, row.Data, "127.0.0.1", "root", "") + mustExecSQL(c, se, "USE test;") +} + func newSession(c *C, store kv.Storage, dbName string) Session { se, err := CreateSession(store) c.Assert(err, IsNil)