Skip to content

Commit

Permalink
Merge branch 'master' into coocood/index-point-lookup
Browse files Browse the repository at this point in the history
Conflicts:
	tidb_test.go
  • Loading branch information
coocood committed Nov 12, 2015
2 parents c8ea306 + f49d073 commit b41d64c
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 79 deletions.
52 changes: 2 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,59 +31,11 @@ __Please do not use it in production.__

## Roadmap

Read the [Roadmap](./ROADMAP.md).
Read the [Roadmap](./docs/ROADMAP.md).

## Quick start

#### __Pre-requirement__

Go environment. Currently a 64-bit version of go >= 1.5 is required.
```
git clone https://github.com/pingcap/tidb.git $GOPATH/src/github.com/pingcap/tidb
cd $GOPATH/src/github.com/pingcap/tidb
make
```

#### __Run command line interpreter__

Interpreter is an interactive command line TiDB client.
You can just enter some SQL statements and get the result.
```
make interpreter
cd interpreter && ./interpreter
```
Press `Ctrl+C` to quit.

#### __Run as go library__

See [USAGE.md](./docs/USAGE.md) for detailed instructions to use TiDB as library in Go code.

#### __Run as MySQL protocol server__

```
make server
cd tidb-server && ./tidb-server
```

In case you want to compile a specific location:

```
make server TARGET=$GOPATH/bin/tidb-server
```

The default server port is `4000` and can be changed by flag `-P <port>`.

Run `./tidb-server -h` to see more flag options.

After you started tidb-server, you can use official mysql client to connect to TiDB.

```
mysql -h 127.0.0.1 -P 4000 -u root -D test
```

#### __Run as MySQL protocol server with distributed transactional KV storage engine__

Comming soon.
Read the [Quick Start](./docs/QUICKSTART.md)

## Architecture

Expand Down
72 changes: 72 additions & 0 deletions docs/QUICKSTART.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Quick Start

#### Run tidb with docker

You can quickly test tidb with docker, the source repository contains the Dockerfile,
You can build TiDB docker image and then run TiDB in a docker container.

To install docker on your system, you can read the document on https://docs.docker.com/

```
git clone https://github.com/pingcap/tidb.git
cd tidb
docker build --rm -t tidb-server .
docker images
docker run -d -p 4000:4000 --name tidb-server tidb-server
```

Then you can use official mysql client to connect to TiDB.

```
mysql -h 127.0.0.1 -P 4000 -u root -D test
```

#### __Pre-requirement__

Go environment. Currently a 64-bit version of go >= 1.5 is required.
```
git clone https://github.com/pingcap/tidb.git $GOPATH/src/github.com/pingcap/tidb
cd $GOPATH/src/github.com/pingcap/tidb
make
```

#### __Run command line interpreter__

Interpreter is an interactive command line TiDB client.
You can just enter some SQL statements and get the result.
```
make interpreter
cd interpreter && ./interpreter
```
Press `Ctrl+C` to quit.

#### __Run as go library__

See [USAGE.md](./USAGE.md) for detailed instructions to use TiDB as library in Go code.

#### __Run as MySQL protocol server__

```
make server
cd tidb-server && ./tidb-server
```

In case you want to compile a specific location:

```
make server TARGET=$GOPATH/bin/tidb-server
```

The default server port is `4000` and can be changed by flag `-P <port>`.

Run `./tidb-server -h` to see more flag options.

After you started tidb-server, you can use official mysql client to connect to TiDB.

```
mysql -h 127.0.0.1 -P 4000 -u root -D test
```

#### __Run as MySQL protocol server with distributed transactional KV storage engine__

Comming soon.
File renamed without changes.
8 changes: 2 additions & 6 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (
"sync"

"github.com/juju/errors"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/rset"
Expand Down Expand Up @@ -250,15 +249,12 @@ func (c *driverConn) Commit() error {
}
_, err := c.s.Execute(txCommitSQL)

if terror.ErrorEqual(err, kv.ErrConditionNotMatch) {
return c.s.Retry()
}

if err != nil {
return errors.Trace(err)
}

return errors.Trace(c.s.FinishTxn(false))
err = c.s.FinishTxn(false)
return errors.Trace(err)
}

func (c *driverConn) Rollback() error {
Expand Down
21 changes: 17 additions & 4 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,13 @@ func (s *session) FinishTxn(rollback bool) error {

err := s.txn.Commit()
if err != nil {
log.Warnf("txn:%s, %v", s.txn, err)
return errors.Trace(err)
if kv.IsRetryableError(err) {
err = s.Retry()
}
if err != nil {
log.Warnf("txn:%s, %v", s.txn, err)
return errors.Trace(err)
}
}

s.resetHistory()
Expand Down Expand Up @@ -228,7 +233,10 @@ func (s *session) Retry() error {
}
}
if success {
break
err = s.FinishTxn(false)
if err == nil {
break
}
}
}

Expand Down Expand Up @@ -488,7 +496,12 @@ func (s *session) GetTxn(forceNew bool) (kv.Transaction, error) {
err = s.txn.Commit()
variable.GetSessionVars(s).SetStatusFlag(mysql.ServerStatusInTrans, false)
if err != nil {
return nil, err
if kv.IsRetryableError(err) {
err = s.Retry()
}
if err != nil {
return nil, errors.Trace(err)
}
}
s.resetHistory()
s.txn, err = s.store.Begin()
Expand Down
60 changes: 53 additions & 7 deletions tidb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/autocommit"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/terror"
)

var store = flag.String("store", "memory", "registered store name, [memory, goleveldb, boltdb]")
Expand Down Expand Up @@ -609,13 +608,14 @@ func (s *testSessionSuite) TestRowLock(c *C) {
mustExecSQL(c, se2, "commit")

_, err := exec(c, se1, "commit")
// row lock conflict but can still success
if terror.ErrorNotEqual(err, kv.ErrConditionNotMatch) {
c.Fail()
}
// Retry should success
err = se.Retry()
// se1 will retry and the final value is 21
c.Assert(err, IsNil)
// Check the result is correct
se3 := newSession(c, store, s.dbName)
r := mustExecSQL(c, se3, "select c2 from t where c1=11")
rows, err := r.Rows(-1, 0)
fmt.Println(rows)
matches(c, rows, [][]interface{}{{21}})

mustExecSQL(c, se1, "begin")
mustExecSQL(c, se1, "update t set c2=21 where c1=11")
Expand Down Expand Up @@ -1386,6 +1386,52 @@ func (s *testSessionSuite) TestIndexPointLookup(c *C) {
mustExecSQL(c, se, "drop table t")
}

// For https://github.com/pingcap/tidb/issues/571
func (s *testSessionSuite) TestIssue571(c *C) {
store := newStore(c, s.dbName)
se := newSession(c, store, s.dbName)

mustExecSQL(c, se, "begin")
mustExecSQL(c, se, "drop table if exists t")
mustExecSQL(c, se, "create table t (c int)")
mustExecSQL(c, se, "insert t values (1), (2), (3)")
mustExecSQL(c, se, "commit")

se1 := newSession(c, store, s.dbName)
mustExecSQL(c, se1, "SET SESSION autocommit=1;")
se2 := newSession(c, store, s.dbName)
mustExecSQL(c, se2, "SET SESSION autocommit=1;")
se3 := newSession(c, store, s.dbName)
mustExecSQL(c, se3, "SET SESSION autocommit=0;")

var wg sync.WaitGroup
wg.Add(3)
f1 := func() {
defer wg.Done()
for i := 0; i < 30; i++ {
mustExecSQL(c, se1, "update t set c = 1;")
}
}
f2 := func() {
defer wg.Done()
for i := 0; i < 30; i++ {
mustExecSQL(c, se2, "update t set c = 1;")
}
}
f3 := func() {
defer wg.Done()
for i := 0; i < 30; i++ {
mustExecSQL(c, se3, "begin")
mustExecSQL(c, se3, "update t set c = 1;")
mustExecSQL(c, se3, "commit")
}
}
go f1()
go f2()
go f3()
wg.Wait()
}

func newSession(c *C, store kv.Storage, dbName string) Session {
se, err := CreateSession(store)
c.Assert(err, IsNil)
Expand Down
16 changes: 4 additions & 12 deletions util/types/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,11 @@ import (
// RoundFloat uses default rounding mode, see http://www.gnu.org/software/libc/manual/html_node/Rounding.html
// so we will choose the even number if the result is midway between two representable value.
// e.g, 1.5 -> 2, 2.5 -> 2.
func RoundFloat(val float64) float64 {
v, frac := math.Modf(val)
if val >= 0.0 {
if frac > 0.5 || (frac == 0.5 && uint64(v)%2 != 0) {
v += 1.0
}
} else {
if frac < -0.5 || (frac == -0.5 && uint64(v)%2 != 0) {
v -= 1.0
}
func RoundFloat(f float64) float64 {
if math.Remainder(f, 1.0) < 0 {
return math.Ceil(f)
}

return v
return math.Floor(f)
}

func getMaxFloat(flen int, decimal int) float64 {
Expand Down

0 comments on commit b41d64c

Please sign in to comment.