Skip to content

Commit 032afaf

Browse files
committed
pkg: support the TSO format for asof expression
Signed-off-by: BornChanger <[email protected]>
1 parent 9d07f83 commit 032afaf

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

pkg/executor/recover_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,67 @@ func TestFlashbackWithSafeTs(t *testing.T) {
451451
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/ddl/changeFlashbackGetMinSafeTimeTimeout"))
452452
}
453453

454+
func TestFlashbackTSOWithSafeTs(t *testing.T) {
455+
store := testkit.CreateMockStore(t)
456+
tk := testkit.NewTestKit(t, store)
457+
458+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/ddl/mockFlashbackTest", `return(true)`))
459+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/ddl/changeFlashbackGetMinSafeTimeTimeout", `return(0)`))
460+
461+
timeBeforeDrop, _, safePointSQL, resetGC := MockGC(tk)
462+
defer resetGC()
463+
464+
// Set GC safe point.
465+
tk.MustExec(fmt.Sprintf(safePointSQL, timeBeforeDrop))
466+
467+
time.Sleep(time.Second)
468+
ts, _ := tk.Session().GetStore().GetOracle().GetTimestamp(context.Background(), &oracle.Option{})
469+
flashbackTs := oracle.GetTimeFromTS(ts)
470+
testcases := []struct {
471+
name string
472+
sql string
473+
injectSafeTS uint64
474+
// compareWithSafeTS will be 0 if FlashbackTS==SafeTS, -1 if FlashbackTS < SafeTS, and +1 if FlashbackTS > SafeTS.
475+
compareWithSafeTS int
476+
}{
477+
{
478+
name: "5 seconds ago to now, safeTS 5 secs ago",
479+
sql: fmt.Sprintf("flashback cluster to timestamp '%d'", ts),
480+
injectSafeTS: oracle.GoTimeToTS(flashbackTs),
481+
compareWithSafeTS: 0,
482+
},
483+
{
484+
name: "10 seconds ago to now, safeTS 5 secs ago",
485+
sql: fmt.Sprintf("flashback cluster to timestamp '%d'", ts),
486+
injectSafeTS: oracle.GoTimeToTS(flashbackTs.Add(10 * time.Second)),
487+
compareWithSafeTS: -1,
488+
},
489+
{
490+
name: "5 seconds ago to now, safeTS 10 secs ago",
491+
sql: fmt.Sprintf("flashback cluster to timestamp '%d'", ts),
492+
injectSafeTS: oracle.GoTimeToTS(flashbackTs.Add(-10 * time.Second)),
493+
compareWithSafeTS: 1,
494+
},
495+
}
496+
for _, testcase := range testcases {
497+
t.Log(testcase.name)
498+
require.NoError(t, failpoint.Enable("github.com/pingcap/tidb/pkg/ddl/injectSafeTS",
499+
fmt.Sprintf("return(%v)", testcase.injectSafeTS)))
500+
if testcase.compareWithSafeTS == 1 {
501+
start := time.Now()
502+
tk.MustContainErrMsg(testcase.sql,
503+
"cannot set flashback timestamp after min-resolved-ts")
504+
// When set `flashbackGetMinSafeTimeTimeout` = 0, no retry for `getStoreGlobalMinSafeTS`.
505+
require.Less(t, time.Since(start), time.Second)
506+
} else {
507+
tk.MustExec(testcase.sql)
508+
}
509+
}
510+
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/ddl/injectSafeTS"))
511+
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/ddl/mockFlashbackTest"))
512+
require.NoError(t, failpoint.Disable("github.com/pingcap/tidb/pkg/ddl/changeFlashbackGetMinSafeTimeTimeout"))
513+
}
514+
454515
func TestFlashbackRetryGetMinSafeTime(t *testing.T) {
455516
store := testkit.CreateMockStore(t)
456517
tk := testkit.NewTestKit(t, store)

pkg/sessiontxn/staleread/util.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package staleread
1616

1717
import (
1818
"context"
19+
"strconv"
1920
"time"
2021

2122
"github.com/pingcap/failpoint"
@@ -30,6 +31,7 @@ import (
3031
)
3132

3233
// CalculateAsOfTsExpr calculates the TsExpr of AsOfClause to get a StartTS.
34+
// tsExpr could be an expression of TSO or a timestamp
3335
func CalculateAsOfTsExpr(ctx context.Context, sctx sessionctx.Context, tsExpr ast.ExprNode) (uint64, error) {
3436
sctx.GetSessionVars().StmtCtx.SetStaleTSOProvider(func() (uint64, error) {
3537
failpoint.Inject("mockStaleReadTSO", func(val failpoint.Value) (uint64, error) {
@@ -49,6 +51,11 @@ func CalculateAsOfTsExpr(ctx context.Context, sctx sessionctx.Context, tsExpr as
4951
return 0, errAsOf.FastGenWithCause("as of timestamp cannot be NULL")
5052
}
5153

54+
// if tsVal is TSO already, return it directly.
55+
if tso, err := strconv.ParseUint(tsVal.GetString(), 10, 64); err == nil {
56+
return tso, nil
57+
}
58+
5259
toTypeTimestamp := types.NewFieldType(mysql.TypeTimestamp)
5360
// We need at least the millionsecond here, so set fsp to 3.
5461
toTypeTimestamp.SetDecimal(3)

0 commit comments

Comments
 (0)