Skip to content

Commit

Permalink
stats: fix converting duration to timestamp (#8174) (#8182)
Browse files Browse the repository at this point in the history
  • Loading branch information
alivxxx authored and zz-jason committed Nov 5, 2018
1 parent e5ce3e5 commit 89140e2
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 9 deletions.
3 changes: 1 addition & 2 deletions statistics/gc.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/cznic/mathutil"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/store/tikv/oracle"
"github.com/pingcap/tidb/util/sqlexec"
"github.com/pkg/errors"
"golang.org/x/net/context"
Expand All @@ -31,7 +30,7 @@ func (h *Handle) GCStats(is infoschema.InfoSchema, ddlLease time.Duration) error
// To make sure that all the deleted tables' schema and stats info have been acknowledged to all tidb,
// we only garbage collect version before 10 lease.
lease := mathutil.MaxInt64(int64(h.Lease), int64(ddlLease))
offset := oracle.ComposeTS(10*lease, 0)
offset := DurationToTS(10 * time.Duration(lease))
if h.LastUpdateVersion() < offset {
return nil
}
Expand Down
7 changes: 6 additions & 1 deletion statistics/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ func (h *Handle) GetQueryFeedback() []*QueryFeedback {
return h.feedback
}

// DurationToTS converts duration to timestamp.
func DurationToTS(d time.Duration) uint64 {
return oracle.ComposeTS(d.Nanoseconds()/int64(time.Millisecond), 0)
}

// Update reads stats meta from store and updates the stats map.
func (h *Handle) Update(is infoschema.InfoSchema) error {
lastVersion := h.LastUpdateVersion()
Expand All @@ -117,7 +122,7 @@ func (h *Handle) Update(is infoschema.InfoSchema) error {
// and A0 < B0 < B1 < A1. We will first read the stats of B, and update the lastVersion to B0, but we cannot read
// the table stats of A0 if we read stats that greater than lastVersion which is B0.
// We can read the stats if the diff between commit time and version is less than three lease.
offset := oracle.ComposeTS(3*int64(h.Lease), 0)
offset := DurationToTS(3 * h.Lease)
if lastVersion >= offset {
lastVersion = lastVersion - offset
} else {
Expand Down
21 changes: 15 additions & 6 deletions statistics/handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,14 @@ func (s *testStatsCacheSuite) TestAvgColLen(c *C) {
c.Assert(statsTbl.Columns[tableInfo.Columns[3].ID].AvgColSize(statsTbl.Count), Equals, 16.0)
}

func (s *testStatsCacheSuite) TestDurationToTS(c *C) {
tests := []time.Duration{time.Millisecond, time.Second, time.Minute, time.Hour}
for _, t := range tests {
ts := statistics.DurationToTS(t)
c.Assert(oracle.ExtractPhysical(ts)*int64(time.Millisecond), Equals, int64(t))
}
}

func (s *testStatsCacheSuite) TestVersion(c *C) {
defer cleanEnv(c, s.store, s.do)
testKit := testkit.NewTestKit(c, s.store)
Expand All @@ -249,11 +257,12 @@ func (s *testStatsCacheSuite) TestVersion(c *C) {
tbl1, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1"))
c.Assert(err, IsNil)
tableInfo1 := tbl1.Meta()
h := statistics.NewHandle(testKit.Se, 1)
testKit.MustExec("update mysql.stats_meta set version = 2 where table_id = ?", tableInfo1.ID)
h := statistics.NewHandle(testKit.Se, time.Millisecond)
unit := oracle.ComposeTS(1, 0)
testKit.MustExec("update mysql.stats_meta set version = ? where table_id = ?", 2*unit, tableInfo1.ID)

h.Update(is)
c.Assert(h.LastUpdateVersion(), Equals, uint64(2))
c.Assert(h.LastUpdateVersion(), Equals, 2*unit)
statsTbl1 := h.GetTableStats(tableInfo1)
c.Assert(statsTbl1.Pseudo, IsFalse)

Expand All @@ -264,15 +273,15 @@ func (s *testStatsCacheSuite) TestVersion(c *C) {
c.Assert(err, IsNil)
tableInfo2 := tbl2.Meta()
// A smaller version write, and we can still read it.
testKit.MustExec("update mysql.stats_meta set version = 1 where table_id = ?", tableInfo2.ID)
testKit.MustExec("update mysql.stats_meta set version = ? where table_id = ?", unit, tableInfo2.ID)
h.Update(is)
c.Assert(h.LastUpdateVersion(), Equals, uint64(2))
c.Assert(h.LastUpdateVersion(), Equals, 2*unit)
statsTbl2 := h.GetTableStats(tableInfo2)
c.Assert(statsTbl2.Pseudo, IsFalse)

testKit.MustExec("insert t1 values(1,2)")
testKit.MustExec("analyze table t1")
offset := oracle.ComposeTS(3*int64(h.Lease), 0)
offset := 3 * unit
testKit.MustExec("update mysql.stats_meta set version = ? where table_id = ?", offset+4, tableInfo1.ID)
h.Update(is)
c.Assert(h.LastUpdateVersion(), Equals, offset+uint64(4))
Expand Down

0 comments on commit 89140e2

Please sign in to comment.