-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
workloadrepo: try to recover etcd snapID from table #59628
base: master
Are you sure you want to change the base?
Changes from all commits
a1905aa
a33f0a2
aaa969f
c47c469
cbcc317
2d97398
b387176
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -59,21 +59,7 @@ func setupWorkerForTest(ctx context.Context, etcdCli *clientv3.Client, dom *doma | |||||||||||
return wrk | ||||||||||||
} | ||||||||||||
|
||||||||||||
func setupDomainAndContext(t *testing.T) (context.Context, kv.Storage, *domain.Domain, string) { | ||||||||||||
ctx := context.Background() | ||||||||||||
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnOthers) | ||||||||||||
var cancel context.CancelFunc = nil | ||||||||||||
if ddl, ok := t.Deadline(); ok { | ||||||||||||
ctx, cancel = context.WithDeadline(ctx, ddl) | ||||||||||||
} | ||||||||||||
t.Cleanup(func() { | ||||||||||||
if cancel != nil { | ||||||||||||
cancel() | ||||||||||||
} | ||||||||||||
}) | ||||||||||||
|
||||||||||||
store, dom := testkit.CreateMockStoreAndDomain(t) | ||||||||||||
|
||||||||||||
func setupEtcd(t *testing.T) string { | ||||||||||||
cfg := embed.NewConfig() | ||||||||||||
cfg.Dir = t.TempDir() | ||||||||||||
|
||||||||||||
|
@@ -97,7 +83,25 @@ func setupDomainAndContext(t *testing.T) (context.Context, kv.Storage, *domain.D | |||||||||||
require.False(t, true, "server took too long to start") | ||||||||||||
} | ||||||||||||
|
||||||||||||
return ctx, store, dom, embedEtcd.Clients[0].Addr().String() | ||||||||||||
return embedEtcd.Clients[0].Addr().String() | ||||||||||||
} | ||||||||||||
|
||||||||||||
func setupDomainAndContext(t *testing.T) (context.Context, kv.Storage, *domain.Domain, string) { | ||||||||||||
ctx := context.Background() | ||||||||||||
ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnOthers) | ||||||||||||
var cancel context.CancelFunc = nil | ||||||||||||
if ddl, ok := t.Deadline(); ok { | ||||||||||||
ctx, cancel = context.WithDeadline(ctx, ddl) | ||||||||||||
} | ||||||||||||
t.Cleanup(func() { | ||||||||||||
if cancel != nil { | ||||||||||||
cancel() | ||||||||||||
} | ||||||||||||
}) | ||||||||||||
|
||||||||||||
store, dom := testkit.CreateMockStoreAndDomain(t) | ||||||||||||
etcdAddr := setupEtcd(t) | ||||||||||||
return ctx, store, dom, etcdAddr | ||||||||||||
} | ||||||||||||
|
||||||||||||
func setupWorker(ctx context.Context, t *testing.T, addr string, dom *domain.Domain, id string, testWorker bool) *worker { | ||||||||||||
|
@@ -857,3 +861,44 @@ func TestCalcNextTick(t *testing.T) { | |||||||||||
require.True(t, calcNextTick(time.Date(2024, 12, 7, 2, 0, 0, 1, loc)) == time.Hour*24-time.Nanosecond) | ||||||||||||
require.True(t, calcNextTick(time.Date(2024, 12, 7, 1, 59, 59, 999999999, loc)) == time.Nanosecond) | ||||||||||||
} | ||||||||||||
|
||||||||||||
func TestRecoverSnapID(t *testing.T) { | ||||||||||||
ctx, store, dom, addr := setupDomainAndContext(t) | ||||||||||||
worker := setupWorker(ctx, t, addr, dom, "worker1", true) | ||||||||||||
require.NoError(t, worker.setRepositoryDest(ctx, "table")) | ||||||||||||
now := time.Now() | ||||||||||||
|
||||||||||||
require.Eventually(t, func() bool { | ||||||||||||
return worker.checkTablesExists(ctx, now) | ||||||||||||
}, time.Minute, time.Second) | ||||||||||||
tk := testkit.NewTestKit(t, store) | ||||||||||||
prevSnapID := uint64(0) | ||||||||||||
require.Eventually(t, func() bool { | ||||||||||||
res := tk.MustQuery("select max(snap_id) from workload_schema.hist_snapshots").Rows() | ||||||||||||
if len(res) == 0 || len(res[0]) == 0 { | ||||||||||||
return false | ||||||||||||
} | ||||||||||||
snapID, err := strconv.ParseUint(res[0][0].(string), 10, 64) | ||||||||||||
prevSnapID = snapID | ||||||||||||
return err == nil && snapID > 0 | ||||||||||||
}, time.Minute, time.Second) | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe time.Second should be time.Millisecond*100? |
||||||||||||
worker.stop() | ||||||||||||
|
||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably wait for the worker to stop.
Suggested change
|
||||||||||||
etcd2 := setupEtcd(t) | ||||||||||||
worker2 := setupWorker(ctx, t, etcd2, dom, "worker2", true) | ||||||||||||
snapIDStr, err := worker2.etcdGet(ctx, snapIDKey) | ||||||||||||
require.Nil(t, err) | ||||||||||||
require.Equal(t, "", snapIDStr) | ||||||||||||
|
||||||||||||
_, err = worker2.getSnapID(ctx) | ||||||||||||
require.EqualError(t, errKeyNotFound, err.Error()) | ||||||||||||
newSnapID, err := queryMaxSnapID(ctx, worker2.getSessionWithRetry().(sessionctx.Context)) | ||||||||||||
require.Nil(t, err) | ||||||||||||
require.Equal(t, prevSnapID, newSnapID) | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code assumes that prevSnapID has to match the last run. This based on timing. It might be better to just run a SQL query to validate that this value is one greater than max(snap_id). |
||||||||||||
|
||||||||||||
require.NoError(t, worker2.setRepositoryDest(ctx, "table")) | ||||||||||||
require.Eventually(t, func() bool { | ||||||||||||
newSnapID, err = worker2.getSnapID(ctx) | ||||||||||||
return err == nil && newSnapID >= prevSnapID | ||||||||||||
}, time.Minute, time.Second) | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would retry every 100 milliseconds instead. |
||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add some comments on when this may happen.