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

*: write system timezone into mysql.tidb in bootstrap stage. #7638

Merged
merged 63 commits into from Sep 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
ec6a822
get tz name from zoneinfo
Sep 7, 2018
40f1caf
remove imports
Sep 7, 2018
ad574a4
add comment
Sep 7, 2018
e76c224
correct a spelling
Sep 7, 2018
a74739c
called once for evalSys
Sep 7, 2018
f0502c8
address comments
Sep 7, 2018
ed136b9
remove unecessary import
Sep 7, 2018
085dc79
Merge branch 'master' into get_tz_name_from_zoneinfo
Sep 8, 2018
8ba623f
rewrite code
Sep 8, 2018
13c7c1b
Merge branch 'get_tz_name_from_zoneinfo' of github.com:zhexuany/tidb …
Sep 8, 2018
e962f82
print localStr out
Sep 8, 2018
26f65f7
set time_zone in test
Sep 8, 2018
d708186
align tz behavior with golang
Sep 8, 2018
ceedc34
when tz is empty use localtime
Sep 8, 2018
2adc1e8
adding timeutil package
Sep 8, 2018
acc0262
make the use of time.Now in expression correct
Sep 8, 2018
709c32c
remoeve unecessay file
Sep 8, 2018
350d27d
adding test and debug print
Sep 9, 2018
c95e6c3
print tz in initLocalStr
Sep 9, 2018
21e9e22
move zone to timeutil
Sep 9, 2018
a84c028
remove prev changes
Sep 9, 2018
c1658d8
init localstr in bootstrap stage
Sep 11, 2018
a517a43
init localstr in bootstrap stage
Sep 11, 2018
b5e39b6
load system tz by select
Sep 12, 2018
84b6e8f
address comment
Sep 12, 2018
dae8a5a
correct test case
Sep 12, 2018
5c373bf
fix conflict
Sep 12, 2018
2d0aca2
fix ci
Sep 12, 2018
e624443
remove shadow err
Sep 12, 2018
f3ad3bc
remove err shadow
Sep 12, 2018
692d4d5
address comment
Sep 13, 2018
b32bdd2
remove extra print
Sep 13, 2018
49454d5
add more comment
Sep 13, 2018
318c12b
address comments
Sep 13, 2018
cb5fd7d
address comments
Sep 13, 2018
ec66759
fix build error
Sep 13, 2018
a3c3cc4
fix test error
Sep 13, 2018
3976eda
load system tz after bootstrap
Sep 13, 2018
d522982
address comments
Sep 13, 2018
dd2d0c9
move code around to avoid critical section
Sep 13, 2018
29679ab
remove callback
Sep 13, 2018
733331e
remove extra comment
Sep 13, 2018
e9bb73b
polish comment of fn
Sep 13, 2018
1d8ddfa
fix ci
Sep 13, 2018
bd24bee
make code cleanner
Sep 13, 2018
2f8018a
correct set time_zone behavior
Sep 13, 2018
7d6ae04
add test
Sep 13, 2018
d315b25
address comment
Sep 13, 2018
5dc988b
fix comment spelling issue
Sep 13, 2018
1f99ca1
use one hook
Sep 13, 2018
e4418cf
remove boot
Sep 13, 2018
44996c2
add extra space
Sep 13, 2018
bd1693e
address comment
Sep 14, 2018
fda4813
fix ci
Sep 14, 2018
9986492
Merge branch 'master' into get_tz_name_from_zoneinfo
Sep 14, 2018
1acd491
move code after checking errLoad
Sep 14, 2018
65051bb
Merge branch 'get_tz_name_from_zoneinfo' of github.com:zhexuany/tidb …
Sep 14, 2018
a37aeeb
add comment
Sep 14, 2018
e20dc07
remove reset chk
Sep 14, 2018
74d394a
rename local fn
Sep 14, 2018
64a5b2e
fix ci
Sep 14, 2018
e77ee43
fix ci
Sep 14, 2018
1b53dff
Merge branch 'master' into get_tz_name_from_zoneinfo
Sep 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 4 additions & 3 deletions executor/admin.go
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/ranger"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pingcap/tipb/go-tipb"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -125,7 +126,7 @@ func (e *CheckIndexRangeExec) Open(ctx context.Context) error {
func (e *CheckIndexRangeExec) buildDAGPB() (*tipb.DAGRequest, error) {
dagReq := &tipb.DAGRequest{}
dagReq.StartTs = e.ctx.Txn().StartTS()
dagReq.TimeZoneName, dagReq.TimeZoneOffset = zone(e.ctx)
dagReq.TimeZoneName, dagReq.TimeZoneOffset = timeutil.Zone(e.ctx.GetSessionVars().Location())
sc := e.ctx.GetSessionVars().StmtCtx
dagReq.Flags = statementContextToFlags(sc)
for i := range e.schema.Columns {
Expand Down Expand Up @@ -223,7 +224,7 @@ func (e *RecoverIndexExec) constructLimitPB(count uint64) *tipb.Executor {
func (e *RecoverIndexExec) buildDAGPB(txn kv.Transaction, limitCnt uint64) (*tipb.DAGRequest, error) {
dagReq := &tipb.DAGRequest{}
dagReq.StartTs = txn.StartTS()
dagReq.TimeZoneName, dagReq.TimeZoneOffset = zone(e.ctx)
dagReq.TimeZoneName, dagReq.TimeZoneOffset = timeutil.Zone(e.ctx.GetSessionVars().Location())
sc := e.ctx.GetSessionVars().StmtCtx
dagReq.Flags = statementContextToFlags(sc)
for i := range e.columns {
Expand Down Expand Up @@ -651,7 +652,7 @@ func (e *CleanupIndexExec) Open(ctx context.Context) error {
func (e *CleanupIndexExec) buildIdxDAGPB(txn kv.Transaction) (*tipb.DAGRequest, error) {
dagReq := &tipb.DAGRequest{}
dagReq.StartTs = txn.StartTS()
dagReq.TimeZoneName, dagReq.TimeZoneOffset = zone(e.ctx)
dagReq.TimeZoneName, dagReq.TimeZoneOffset = timeutil.Zone(e.ctx.GetSessionVars().Location())
sc := e.ctx.GetSessionVars().StmtCtx
dagReq.Flags = statementContextToFlags(sc)
for i := range e.idxCols {
Expand Down
7 changes: 4 additions & 3 deletions executor/builder.go
Expand Up @@ -43,6 +43,7 @@ import (
"github.com/pingcap/tidb/util/admin"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/ranger"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pingcap/tipb/go-tipb"
"github.com/pkg/errors"
"golang.org/x/net/context"
Expand Down Expand Up @@ -1320,7 +1321,7 @@ func (b *executorBuilder) buildDelete(v *plan.Delete) Executor {
}

func (b *executorBuilder) buildAnalyzeIndexPushdown(task plan.AnalyzeIndexTask, maxNumBuckets uint64) *AnalyzeIndexExec {
_, offset := zone(b.ctx)
_, offset := timeutil.Zone(b.ctx.GetSessionVars().Location())
e := &AnalyzeIndexExec{
ctx: b.ctx,
physicalTableID: task.PhysicalTableID,
Expand Down Expand Up @@ -1353,7 +1354,7 @@ func (b *executorBuilder) buildAnalyzeColumnsPushdown(task plan.AnalyzeColumnsTa
cols = append([]*model.ColumnInfo{task.PKInfo}, cols...)
}

_, offset := zone(b.ctx)
_, offset := timeutil.Zone(b.ctx.GetSessionVars().Location())
e := &AnalyzeColumnsExec{
ctx: b.ctx,
physicalTableID: task.PhysicalTableID,
Expand Down Expand Up @@ -1430,7 +1431,7 @@ func constructDistExec(sctx sessionctx.Context, plans []plan.PhysicalPlan) ([]*t
func (b *executorBuilder) constructDAGReq(plans []plan.PhysicalPlan) (dagReq *tipb.DAGRequest, streaming bool, err error) {
dagReq = &tipb.DAGRequest{}
dagReq.StartTs = b.getStartTS()
dagReq.TimeZoneName, dagReq.TimeZoneOffset = zone(b.ctx)
dagReq.TimeZoneName, dagReq.TimeZoneOffset = timeutil.Zone(b.ctx.GetSessionVars().Location())
sc := b.ctx.GetSessionVars().StmtCtx
dagReq.Flags = statementContextToFlags(sc)
dagReq.Executors, streaming, err = constructDistExec(b.ctx, plans)
Expand Down
17 changes: 0 additions & 17 deletions executor/distsql.go
Expand Up @@ -19,7 +19,6 @@ import (
"sort"
"sync"
"sync/atomic"
"time"
"unsafe"

"github.com/pingcap/tidb/distsql"
Expand Down Expand Up @@ -117,22 +116,6 @@ func closeAll(objs ...Closeable) error {
return errors.Trace(err)
}

// zone returns the current timezone name and timezone offset in seconds.
// In compatible with MySQL, we change `Local` to `System`.
// TODO: Golang team plan to return system timezone name intead of
// returning `Local` when `loc` is `time.Local`. We need keep an eye on this.
func zone(sctx sessionctx.Context) (string, int64) {
loc := sctx.GetSessionVars().Location()
_, offset := time.Now().In(loc).Zone()
var name string
name = loc.String()
if name == "Local" {
name = "System"
}

return name, int64(offset)
}

// statementContextToFlags converts StatementContext to tipb.SelectRequest.Flags.
func statementContextToFlags(sc *stmtctx.StatementContext) uint64 {
var flags uint64
Expand Down
29 changes: 29 additions & 0 deletions executor/executor_test.go
Expand Up @@ -26,6 +26,7 @@ import (
"time"

gofail "github.com/etcd-io/gofail/runtime"
"github.com/golang/protobuf/proto"
. "github.com/pingcap/check"
pb "github.com/pingcap/kvproto/pkg/kvrpcpb"
"github.com/pingcap/tidb/config"
Expand Down Expand Up @@ -58,6 +59,8 @@ import (
"github.com/pingcap/tidb/util/testkit"
"github.com/pingcap/tidb/util/testleak"
"github.com/pingcap/tidb/util/testutil"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pingcap/tipb/go-tipb"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
Expand Down Expand Up @@ -2357,6 +2360,32 @@ func (s *testContextOptionSuite) TestCoprocessorPriority(c *C) {
cli.mu.Unlock()
}

func (s *testSuite) TestTimezonePushDown(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("create table t (ts timestamp)")
defer tk.MustExec("drop table t")
tk.MustExec(`insert into t values ("2018-09-13 10:02:06")`)

systemTZ := timeutil.SystemLocation()
c.Assert(systemTZ.String(), Not(Equals), "System")
ctx := context.Background()
count := 0
ctx1 := context.WithValue(ctx, "CheckSelectRequestHook", func(req *kv.Request) {
count += 1
dagReq := new(tipb.DAGRequest)
err := proto.Unmarshal(req.Data, dagReq)
c.Assert(err, IsNil)
c.Assert(dagReq.GetTimeZoneName(), Equals, systemTZ.String())
})
tk.Se.Execute(ctx1, `select * from t where ts = "2018-09-13 10:02:06"`)
zhexuany marked this conversation as resolved.
Show resolved Hide resolved

tk.MustExec(`set time_zone="System"`)
tk.Se.Execute(ctx1, `select * from t where ts = "2018-09-13 10:02:06"`)
zhexuany marked this conversation as resolved.
Show resolved Hide resolved

c.Assert(count, Equals, 2) // Make sure the hook function is called.
}

func (s *testSuite) TestNotFillCacheFlag(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
3 changes: 2 additions & 1 deletion expression/builtin_time_test.go
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/pingcap/tidb/util/mock"
"github.com/pingcap/tidb/util/testleak"
"github.com/pingcap/tidb/util/testutil"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -997,7 +998,7 @@ func (s *testEvaluatorSuite) TestSysDate(c *C) {
fc := funcs[ast.Sysdate]

ctx := mock.NewContext()
ctx.GetSessionVars().StmtCtx.TimeZone = time.Local
ctx.GetSessionVars().StmtCtx.TimeZone = timeutil.SystemLocation()
timezones := []types.Datum{types.NewDatum(1234), types.NewDatum(0)}
for _, timezone := range timezones {
// sysdate() result is not affected by "timestamp" session variable.
Expand Down
24 changes: 23 additions & 1 deletion session/bootstrap.go
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/auth"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
Expand Down Expand Up @@ -233,7 +234,10 @@ const (
bootstrappedVarTrue = "True"
// The variable name in mysql.TiDB table.
// It is used for getting the version of the TiDB server which bootstrapped the store.
tidbServerVersionVar = "tidb_server_version" //
tidbServerVersionVar = "tidb_server_version"
zhexuany marked this conversation as resolved.
Show resolved Hide resolved
// The variable name in mysql.tidb table and it will be used when we want to know
// system timezone.
tidbSystemTZ = "system_tz"
// Const for TiDB server version 2.
version2 = 2
version3 = 3
Expand All @@ -257,6 +261,7 @@ const (
version21 = 21
version22 = 22
version23 = 23
version24 = 24
)

func checkBootstrapped(s Session) (bool, error) {
Expand Down Expand Up @@ -407,6 +412,10 @@ func upgrade(s Session) {
upgradeToVer23(s)
}

if ver < version24 {
upgradeToVer24(s)
}

updateBootstrapVer(s)
_, err = s.Execute(context.Background(), "COMMIT")

Expand Down Expand Up @@ -649,6 +658,18 @@ func upgradeToVer23(s Session) {
doReentrantDDL(s, "ALTER TABLE mysql.stats_histograms ADD COLUMN `flag` bigint(64) NOT NULL DEFAULT 0", infoschema.ErrColumnExists)
}

// writeSystemTZ writes system timezone info into mysql.tidb
func writeSystemTZ(s Session) {
sql := fmt.Sprintf(`INSERT HIGH_PRIORITY INTO %s.%s VALUES ("%s", "%s", "TiDB Global System Timezone.") ON DUPLICATE KEY UPDATE VARIABLE_VALUE="%s"`,
mysql.SystemDB, mysql.TiDBTable, tidbSystemTZ, timeutil.InferSystemTZ(), timeutil.InferSystemTZ())
mustExecute(s, sql)
}

// upgradeToVer24 initializes `System` timezone according to docs/design/2018-09-10-adding-tz-env.md
func upgradeToVer24(s Session) {
writeSystemTZ(s)
}

// updateBootstrapVer updates bootstrap version variable in mysql.TiDB table.
func updateBootstrapVer(s Session) {
// Update bootstrap version.
Expand Down Expand Up @@ -732,6 +753,7 @@ func doDMLWorks(s Session) {
mysql.SystemDB, mysql.TiDBTable, tidbServerVersionVar, currentBootstrapVersion)
mustExecute(s, sql)

writeSystemTZ(s)
_, err := s.Execute(context.Background(), "COMMIT")
if err != nil {
time.Sleep(1 * time.Second)
Expand Down
26 changes: 25 additions & 1 deletion session/session.go
Expand Up @@ -53,6 +53,7 @@ import (
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/kvcache"
"github.com/pingcap/tidb/util/timeutil"
binlog "github.com/pingcap/tipb/go-binlog"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -1068,6 +1069,20 @@ func CreateSession(store kv.Storage) (Session, error) {
return s, nil
}

// loadSystemTZ loads systemTZ from mysql.tidb
func loadSystemTZ(se *session) (string, error) {
sql := `select variable_value from mysql.tidb where variable_name = "system_tz"`
rss, errLoad := se.Execute(context.Background(), sql)
if errLoad != nil {
return "", errLoad
}
// the record of mysql.tidb under where condition: variable_name = "system_tz" should shall only be one.
defer rss[0].Close()
chk := rss[0].NewChunk()
rss[0].Next(context.Background(), chk)
return chk.GetRow(0).GetString(0), nil
}

// BootstrapSession runs the first time when the TiDB server start.
func BootstrapSession(store kv.Storage) (*domain.Domain, error) {
ver := getStoreBootstrapVersion(store)
Expand All @@ -1081,11 +1096,20 @@ func BootstrapSession(store kv.Storage) (*domain.Domain, error) {
if err != nil {
return nil, errors.Trace(err)
}
// get system tz from mysql.tidb
tz, err := loadSystemTZ(se)
if err != nil {
return nil, errors.Trace(err)
}

timeutil.SetSystemTZ(tz)

dom := domain.GetDomain(se)
err = dom.LoadPrivilegeLoop(se)
if err != nil {
return nil, errors.Trace(err)
}

se1, err := createSession(store)
if err != nil {
return nil, errors.Trace(err)
Expand Down Expand Up @@ -1180,7 +1204,7 @@ func createSessionWithDomain(store kv.Storage, dom *domain.Domain) (*session, er

const (
notBootstrapped = 0
currentBootstrapVersion = 23
currentBootstrapVersion = 24
)

func getStoreBootstrapVersion(store kv.Storage) int64 {
Expand Down
3 changes: 2 additions & 1 deletion sessionctx/variable/session.go
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/auth"
"github.com/pingcap/tidb/util/chunk"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -426,7 +427,7 @@ func (s *SessionVars) GetNextPreparedStmtID() uint32 {
func (s *SessionVars) Location() *time.Location {
loc := s.TimeZone
if loc == nil {
loc = time.Local
loc = timeutil.SystemLocation()
}
return loc
}
Expand Down
4 changes: 2 additions & 2 deletions sessionctx/variable/varsutil.go
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/pingcap/tidb/config"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/timeutil"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -350,8 +351,7 @@ func tidbOptInt64(opt string, defaultVal int64) int64 {

func parseTimeZone(s string) (*time.Location, error) {
if strings.EqualFold(s, "SYSTEM") {
// TODO: Support global time_zone variable, it should be set to global time_zone value.
return time.Local, nil
return timeutil.SystemLocation(), nil
}

loc, err := time.LoadLocation(s)
Expand Down