Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gc_worker: Remove timezone name from the times that are saved in mysql.tidb #8745

Merged
merged 10 commits into from
Dec 27, 2018
2 changes: 1 addition & 1 deletion executor/admin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ func (s *testSuite) TestAdminCheckWithSnapshot(c *C) {

// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
safePointName := "tikv_gc_safe_point"
safePointValue := "20060102-15:04:05 -0700 MST"
safePointValue := "20060102-15:04:05 -0700"
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
ON DUPLICATE KEY
Expand Down
2 changes: 1 addition & 1 deletion executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1989,7 +1989,7 @@ func (s *testSuite) TestHistoryRead(c *C) {

// For mocktikv, safe point is not initialized, we manually insert it for snapshot to use.
safePointName := "tikv_gc_safe_point"
safePointValue := "20060102-15:04:05 -0700 MST"
safePointValue := "20060102-15:04:05 -0700"
safePointComment := "All versions after safe point can be accessed. (DO NOT EDIT)"
updateSafePoint := fmt.Sprintf(`INSERT INTO mysql.tidb VALUES ('%[1]s', '%[2]s', '%[3]s')
ON DUPLICATE KEY
Expand Down
6 changes: 3 additions & 3 deletions executor/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"context"
"fmt"
"strings"
"time"

"github.com/pingcap/errors"
"github.com/pingcap/parser/ast"
Expand All @@ -28,6 +27,7 @@ import (
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/sqlexec"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -194,8 +194,8 @@ func validateSnapshot(ctx sessionctx.Context, snapshotTS uint64) error {
return errors.New("can not get 'tikv_gc_safe_point'")
}
safePointString := rows[0].GetString(0)
const gcTimeFormat = "20060102-15:04:05 -0700 MST"
safePointTime, err := time.Parse(gcTimeFormat, safePointString)
const gcTimeFormat = "20060102-15:04:05 -0700"
safePointTime, err := util.ParseTimeFromPrefix(gcTimeFormat, safePointString)
if err != nil {
return errors.Trace(err)
}
Expand Down
6 changes: 3 additions & 3 deletions store/tikv/gcworker/gc_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (w *GCWorker) Close() {
}

const (
gcTimeFormat = "20060102-15:04:05 -0700 MST"
gcTimeFormat = "20060102-15:04:05 -0700"
gcWorkerTickInterval = time.Minute
gcJobLogTickInterval = time.Minute * 10
gcWorkerLease = time.Minute * 2
Expand Down Expand Up @@ -944,7 +944,7 @@ func (w *GCWorker) loadTime(key string) (*time.Time, error) {
if str == "" {
return nil, nil
}
t, err := time.Parse(gcTimeFormat, str)
t, err := tidbutil.ParseTimeFromPrefix(gcTimeFormat, str)
if err != nil {
return nil, errors.Trace(err)
}
Expand Down Expand Up @@ -1078,7 +1078,7 @@ func NewMockGCWorker(store tikv.Storage) (*MockGCWorker, error) {
return &MockGCWorker{worker: worker}, nil
}

// DeleteRanges call deleteRanges internally, just for test.
// DeleteRanges calls deleteRanges internally, just for test.
func (w *MockGCWorker) DeleteRanges(ctx context.Context, safePoint uint64) error {
log.Errorf("deleteRanges is called")
return w.worker.deleteRanges(ctx, safePoint)
Expand Down
25 changes: 25 additions & 0 deletions util/misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,28 @@ func WithRecovery(exec func(), recoverFn func(r interface{})) {
}()
exec()
}

// ParseTimeFromPrefix tries to parse time from a prefix of `value`. The formatted time should be separated from
// other texts. For example, you can parse "20060102-15:04:05 -0700" from a string like "20060102-15:04:05 -0700 FOO"
// but you can't parse from a string like "20060102-15:04:05 -0700FOO".
func ParseTimeFromPrefix(format string, value string) (time.Time, error) {
MyonKeminta marked this conversation as resolved.
Show resolved Hide resolved
t, err := time.Parse(format, value)

i := len(value)
for err != nil && i > 0 {
// Cut from the last space
for i > 0 {
i--
if value[i] == ' ' {
break
}
}

t, err = time.Parse(format, value[0:i])
}

if err != nil {
err = errors.Errorf("string \"%v\" doesn't has a prefix that matches format \"%v\"", value, format)
}
return t, err
}
49 changes: 48 additions & 1 deletion util/misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
package util

import (
"time"

. "github.com/pingcap/check"
"github.com/pingcap/errors"
"github.com/pingcap/tidb/util/testleak"
Expand All @@ -30,7 +32,7 @@ func (s *testMiscSuite) SetUpSuite(c *C) {
func (s *testMiscSuite) TearDownSuite(c *C) {
}

func (s testMiscSuite) TestRunWithRetry(c *C) {
func (s *testMiscSuite) TestRunWithRetry(c *C) {
defer testleak.AfterTest(c)()
// Run succ.
cnt := 0
Expand Down Expand Up @@ -68,3 +70,48 @@ func (s testMiscSuite) TestRunWithRetry(c *C) {
c.Assert(err, NotNil)
c.Assert(cnt, Equals, 1)
}

func (s *testMiscSuite) TestParseTimeFromPrefix(c *C) {
format := "20060102-15:04:05 -0700"

values := []string{
"20181218-19:53:37 +0800 CST",
"20181218-19:53:37 +0800 MST ",
"20181218-19:53:37 +0800 FOO",
"20181218-19:53:37 +0800 aaa bbb ccc 1 2 3 ",
"20181218-19:53:37 +0800 +08",
"20181218-19:53:37 +0800",
"20181218-19:53:37 +0800 ",
"20181218-11:53:37 +0000",
}

invalidValues := []string{
"",
" ",
"foo",
"20181218-11:53:37",
"20181218-19:53:37 +0800CST",
"20181218-19:53:37 +0800FOOOOOOO BAR",
"20181218-19:53:37 ",
}

expectedTime := time.Date(2018, 12, 18, 11, 53, 37, 0, time.UTC)
expectedTimeFormatted := "20181218-19:53:37 +0800"

beijing, err := time.LoadLocation("Asia/Shanghai")
c.Assert(err, IsNil)

for _, value := range values {
t, err := ParseTimeFromPrefix(format, value)
c.Assert(err, IsNil)
c.Assert(t.Equal(expectedTime), Equals, true)

formatted := t.In(beijing).Format(format)
c.Assert(formatted, Equals, expectedTimeFormatted)
}

for _, value := range invalidValues {
_, err := ParseTimeFromPrefix(format, value)
c.Assert(err, NotNil)
}
}