diff --git a/pkg/executor/test/recovertest/BUILD.bazel b/pkg/executor/test/recovertest/BUILD.bazel index 0a1640b2b130d..f2b5c4dd8e62a 100644 --- a/pkg/executor/test/recovertest/BUILD.bazel +++ b/pkg/executor/test/recovertest/BUILD.bazel @@ -12,6 +12,7 @@ go_test( deps = [ "//pkg/config", "//pkg/config/kerneltype", + "//pkg/domain", "//pkg/ddl/util", "//pkg/errno", "//pkg/infoschema", @@ -19,6 +20,9 @@ go_test( "//pkg/meta/autoid", "//pkg/meta/model", "//pkg/parser/auth", + "//pkg/resourcemanager", + "//pkg/session", + "//pkg/sessionctx/vardef", "//pkg/sessionctx/variable", "//pkg/store/mockstore", "//pkg/testkit", @@ -28,9 +32,11 @@ go_test( "//pkg/util/dbterror", "//pkg/util/gcutil", "@com_github_pingcap_failpoint//:failpoint", + "@com_github_pingcap_kvproto//pkg/kvrpcpb", "@com_github_stretchr_testify//require", "@com_github_tikv_client_go_v2//oracle", "@com_github_tikv_client_go_v2//tikv", + "@com_github_tikv_client_go_v2//tikvrpc", "@com_github_tikv_client_go_v2//util", "@io_opencensus_go//stats/view", "@org_uber_go_goleak//:goleak", diff --git a/pkg/executor/test/recovertest/recover_test.go b/pkg/executor/test/recovertest/recover_test.go index 5324c29eb8a43..bcc378176dcd0 100644 --- a/pkg/executor/test/recovertest/recover_test.go +++ b/pkg/executor/test/recovertest/recover_test.go @@ -19,17 +19,23 @@ import ( "fmt" "strconv" "sync" + "sync/atomic" "testing" "time" "github.com/pingcap/failpoint" + "github.com/pingcap/kvproto/pkg/kvrpcpb" "github.com/pingcap/tidb/pkg/config/kerneltype" ddlutil "github.com/pingcap/tidb/pkg/ddl/util" + "github.com/pingcap/tidb/pkg/domain" "github.com/pingcap/tidb/pkg/errno" "github.com/pingcap/tidb/pkg/infoschema" "github.com/pingcap/tidb/pkg/kv" "github.com/pingcap/tidb/pkg/meta/model" "github.com/pingcap/tidb/pkg/parser/auth" + "github.com/pingcap/tidb/pkg/resourcemanager" + "github.com/pingcap/tidb/pkg/session" + "github.com/pingcap/tidb/pkg/sessionctx/vardef" "github.com/pingcap/tidb/pkg/sessionctx/variable" "github.com/pingcap/tidb/pkg/store/mockstore" "github.com/pingcap/tidb/pkg/testkit" @@ -40,7 +46,10 @@ import ( "github.com/pingcap/tidb/pkg/util/gcutil" "github.com/stretchr/testify/require" "github.com/tikv/client-go/v2/oracle" + "github.com/tikv/client-go/v2/tikv" + "github.com/tikv/client-go/v2/tikvrpc" tikvutil "github.com/tikv/client-go/v2/util" + "go.opencensus.io/stats/view" ) func TestRecoverTable(t *testing.T) { @@ -721,8 +730,79 @@ func mockGC(tk *testkit.TestKit) (string, string, string, func()) { return timeBeforeDrop, timeAfterDrop, safePointSQL, resetGC } +type flashbackClusterTestClient struct { + tikv.Client +} + +func (c *flashbackClusterTestClient) SendRequest(ctx context.Context, addr string, req *tikvrpc.Request, timeout time.Duration) (*tikvrpc.Response, error) { + switch req.Type { + case tikvrpc.CmdPrepareFlashbackToVersion: + return &tikvrpc.Response{Resp: &kvrpcpb.PrepareFlashbackToVersionResponse{}}, nil + case tikvrpc.CmdFlashbackToVersion: + return &tikvrpc.Response{Resp: &kvrpcpb.FlashbackToVersionResponse{}}, nil + default: + return c.Client.SendRequest(ctx, addr, req, timeout) + } +} + +type flashbackClusterTestStorage interface { + kv.Storage + tikv.Storage + kv.StorageWithPD +} + +type flashbackClusterTestStore struct { + flashbackClusterTestStorage + minSafeTS *atomic.Uint64 +} + +var _ kv.StorageWithPD = (*flashbackClusterTestStore)(nil) + +func newFlashbackClusterTestStore(t *testing.T, minSafeTS *atomic.Uint64) kv.Storage { + t.Helper() + + store, err := mockstore.NewMockStore( + mockstore.WithStoreType(mockstore.MockTiKV), + mockstore.WithClientHijacker(func(client tikv.Client) tikv.Client { + return &flashbackClusterTestClient{Client: client} + }), + ) + require.NoError(t, err) + testStore, ok := store.(flashbackClusterTestStorage) + require.True(t, ok) + wrappedStore := &flashbackClusterTestStore{ + flashbackClusterTestStorage: testStore, + minSafeTS: minSafeTS, + } + + vardef.SetSchemaLease(500 * time.Millisecond) + session.DisableStats4Test() + domain.DisablePlanReplayerBackgroundJob4Test() + domain.DisableDumpHistoricalStats4Test() + dom, err := session.BootstrapSession(wrappedStore) + require.NoError(t, err) + dom.SetStatsUpdating(true) + t.Cleanup(func() { + dom.Close() + view.Stop() + require.NoError(t, wrappedStore.Close()) + resourcemanager.InstanceResourceManager.Reset() + }) + + return wrappedStore +} + +func (*flashbackClusterTestStore) Name() string { + return "TiKV" +} + +func (s *flashbackClusterTestStore) GetMinSafeTS(string) uint64 { + return s.minSafeTS.Load() +} + func TestFlashbackClusterWithManyDBs(t *testing.T) { - store := testkit.CreateMockStore(t) + var minSafeTS atomic.Uint64 + store := newFlashbackClusterTestStore(t, &minSafeTS) tk := testkit.NewTestKit(t, store) timeBeforeDrop, _, safePointSQL, resetGC := mockGC(tk) @@ -758,11 +838,7 @@ func TestFlashbackClusterWithManyDBs(t *testing.T) { ts, _ := store.CurrentVersion(oracle.GlobalTxnScope) flashbackTs := oracle.GetTimeFromTS(ts.Ver) - - injectSafeTS := oracle.GoTimeToTS(flashbackTs.Add(10 * time.Second)) - testfailpoint.Enable(t, "github.com/pingcap/tidb/pkg/ddl/mockFlashbackTest", `return(true)`) - testfailpoint.Enable(t, "github.com/pingcap/tidb/pkg/ddl/injectSafeTS", - fmt.Sprintf("return(%v)", injectSafeTS)) + minSafeTS.Store(oracle.GoTimeToTS(flashbackTs.Add(10 * time.Second))) // this test will fail before the fix, because the DDL job KV entry is too large. tk.MustExec(fmt.Sprintf("flashback cluster to timestamp '%s'", flashbackTs))