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

flaky deadlock with go1.23 #55478

Closed
Tracked by #55480
hawkingrei opened this issue Aug 16, 2024 · 0 comments · Fixed by #55479
Closed
Tracked by #55480

flaky deadlock with go1.23 #55478

hawkingrei opened this issue Aug 16, 2024 · 0 comments · Fixed by #55479
Labels
affects-6.5 This bug affects the 6.5.x(LTS) versions. affects-7.1 This bug affects the 7.1.x(LTS) versions. affects-7.5 This bug affects the 7.5.x(LTS) versions. affects-8.1 This bug affects the 8.1.x(LTS) versions. component/test severity/moderate type/bug The issue is confirmed as a bug.

Comments

@hawkingrei
Copy link
Member

hawkingrei commented Aug 16, 2024

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

run any test in the tidb with testkit

2. What did you expect to see? (Required)

no deadlock report

3. What did you see instead (Required)

POTENTIAL DEADLOCK: Inconsistent locking. saw this ordering in one goroutine:
happened before
../../session/txn.go:346 session.(*LazyTxn).changeToInvalid { txn.mu.Lock() } <<<<<
../../session/txn.go:345 session.(*LazyTxn).changeToInvalid {  }
../../session/session.go:497 session.(*session).doCommit.func1 { s.txn.changeToInvalid() }
../../session/session.go:502 session.(*session).doCommit { if s.txn.IsReadOnly() { }
../../session/session.go:790 session.(*session).doCommitWithRetry { err = s.doCommit(ctx) }
../../session/session.go:919 session.(*session).CommitTxn { ctx = context.WithValue(ctx, tikvutil.CommitDetailCtxKey, &commitDetail) }
../../session/tidb.go:287 session.autoCommitAfterStmt { if !sessVars.InTxn() { }
../../session/tidb.go:249 session.finishStmt { } }
../../session/session.go:2314 session.runStmt {  }
../../session/session.go:2154 session.(*session).ExecuteStmt {  }
../../session/session.go:1517 session.(*session).ExecuteInternal {  }
../../session/bootstrap.go:3350 session.mustExecute { ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBootstrap) }
../../session/bootstrap.go:3148 session.doDDLWorks { // Create stats_meta table. }
../../session/bootstrap.go:742 session.bootstrap { doDDLWorks(s) }
../../session/session.go:3688 session.runInBootstrapSession { bootstrap(s) }
../../session/session.go:3438 session.bootstrapSessionImpl { if ver == notBootstrapped { }
../../session/session.go:3388 session.BootstrapSession { func BootstrapSession(store kv.Storage) (*domain.Domain, error) { }
../../testkit/mockstore.go:253 testkit.bootstrap { domain.DisableDumpHistoricalStats4Test() }
../../testkit/mockstore.go:224 testkit.CreateMockStoreAndDomain { require.NoError(t, err) }
../../testkit/mockstore.go:70 testkit.CreateMockStore { store, _ := CreateMockStoreAndDomain(t, opts...) }
ranger_test.go:2204 ranger_test.TestPrefixIndexRange { store := testkit.CreateMockStore(t) }

happened after
../../session/txn.go:377 session.(*LazyTxn).onStmtEnd { txn.mu.Lock() } <<<<<
../../session/txn.go:376 session.(*LazyTxn).onStmtEnd { func (txn *LazyTxn) onStmtEnd() { }
../../session/session.go:2163 session.(*session).ExecuteStmt { } }
../../session/session.go:1517 session.(*session).ExecuteInternal {  }
../../ddl/session/session.go:84 session.(*Session).Execute { } }
../../ddl/job_scheduler.go:373 ddl.(*jobScheduler).loadAndDeliverJobs { rows, err := se.Execute(context.Background(), sql, "load_ddl_jobs") }
../../ddl/job_scheduler.go:316 ddl.(*jobScheduler).schedule { failpoint.InjectCall("beforeLoadAndDeliverJobs") }
../../ddl/job_scheduler.go:251 ddl.(*jobScheduler).scheduleLoop { for { }
../wait_group_wrapper.go:171 util.(*WaitGroupWrapper).RunWithLog.func1 { exec() }

in another goroutine: happened before
../../session/txn.go:314 session.(*LazyTxn).changePendingToValid { txn.mu.Lock() } <<<<<
../../session/txn.go:313 session.(*LazyTxn).changePendingToValid { // The txnInfo may already recorded the first statement (usually "begin") when it's pending, so keep them. }
../../session/txn.go:614 session.(*LazyTxn).Wait { // If Txn() is called later, wait for the future to get a valid txn. }
../../sessiontxn/isolation/base.go:289 isolation.(*baseTxnContextProvider).ActivateTxn { txn, err := txnFuture.Wait(p.ctx, p.sctx) }
../../sessiontxn/isolation/base.go:184 isolation.(*baseTxnContextProvider).GetStmtReadTS { func (p *baseTxnContextProvider) GetStmtReadTS() (uint64, error) { }
../../sessiontxn/isolation/optimistic.go:99 isolation.(*OptimisticTxnContextProvider).GetStmtReadTS { } }
../../session/txnmanager.go:97 session.(*txnManager).GetStmtReadTS { } }
../../executor/builder.go:2066 executor.(*executorBuilder).getSnapshotTS { } }
../../executor/builder.go:3476 executor.buildNoRangeTableReader { startTS, err := b.getSnapshotTS() }
../../executor/builder.go:3623 executor.(*executorBuilder).buildTableReader { ret, err := buildNoRangeTableReader(b, v) }
../../executor/builder.go:288 executor.(*executorBuilder).build { case *plannercore.PhysicalTableReader: }
../../executor/builder.go:2014 executor.(*executorBuilder).buildProjection { func (b *executorBuilder) buildProjection(v *plannercore.PhysicalProjection) exec.Executor { }
../../executor/builder.go:276 executor.(*executorBuilder).build { case *plannercore.PhysicalProjection: }
../../executor/adapter.go:1212 executor.(*ExecStmt).buildExecutor { b := newExecutorBuilder(ctx, a.InfoSchema) }
../../executor/adapter.go:555 executor.(*ExecStmt).Exec {  }
../../session/session.go:2283 session.runStmt {  }
../../session/session.go:2154 session.(*session).ExecuteStmt {  }
../../session/session.go:1517 session.(*session).ExecuteInternal {  }
../../ddl/session/session.go:84 session.(*Session).Execute { } }
../../ddl/job_scheduler.go:373 ddl.(*jobScheduler).loadAndDeliverJobs { rows, err := se.Execute(context.Background(), sql, "load_ddl_jobs") }
../../ddl/job_scheduler.go:316 ddl.(*jobScheduler).schedule { failpoint.InjectCall("beforeLoadAndDeliverJobs") }
../../ddl/job_scheduler.go:251 ddl.(*jobScheduler).scheduleLoop { for { }
../wait_group_wrapper.go:171 util.(*WaitGroupWrapper).RunWithLog.func1 { exec() }

happened after
../../session/txn.go:160 session.(*LazyTxn).cleanupStmtBuf { txn.mu.Lock() } <<<<<
../../session/txn.go:159 session.(*LazyTxn).cleanupStmtBuf {  }
../../session/txn.go:578 session.(*LazyTxn).cleanup { txn.cleanupStmtBuf() }
../../session/txn.go:742 session.(*session).StmtCommit.func1 { s.txn.cleanup() }
../../session/txn.go:758 session.(*session).StmtCommit { } }
../../session/tidb.go:249 session.finishStmt { } }
../../session/session.go:2314 session.runStmt {  }
../../session/session.go:2154 session.(*session).ExecuteStmt {  }
../../session/session.go:1517 session.(*session).ExecuteInternal {  }
../../session/bootstrap.go:3350 session.mustExecute { ctx = kv.WithInternalSourceType(ctx, kv.InternalTxnBootstrap) }
../../session/bootstrap.go:3159 session.doDDLWorks { // NOTE: Feedback is deprecated, but we still need to create this table for compatibility. }
../../session/bootstrap.go:742 session.bootstrap { doDDLWorks(s) }
../../session/session.go:3688 session.runInBootstrapSession { bootstrap(s) }
../../session/session.go:3438 session.bootstrapSessionImpl { if ver == notBootstrapped { }
../../session/session.go:3388 session.BootstrapSession { func BootstrapSession(store kv.Storage) (*domain.Domain, error) { }
../../testkit/mockstore.go:253 testkit.bootstrap { domain.DisableDumpHistoricalStats4Test() }
../../testkit/mockstore.go:224 testkit.CreateMockStoreAndDomain { require.NoError(t, err) }
../../testkit/mockstore.go:70 testkit.CreateMockStore { store, _ := CreateMockStoreAndDomain(t, opts...) }
ranger_test.go:2204 ranger_test.TestPrefixIndexRange { store := testkit.CreateMockStore(t) }

Other goroutines holding locks:
goroutine 2 lock 0xc0059982f8
../../session/txn.go:314 session.(*LazyTxn).changePendingToValid { txn.mu.Lock() } <<<<<
../../session/txn.go:313 session.(*LazyTxn).changePendingToValid { // The txnInfo may already recorded the first statement (usually "begin") when it's pending, so keep them. }
../../session/txn.go:614 session.(*LazyTxn).Wait { // If Txn() is called later, wait for the future to get a valid txn. }
../../sessiontxn/isolation/base.go:289 isolation.(*baseTxnContextProvider).ActivateTxn { txn, err := txnFuture.Wait(p.ctx, p.sctx) }
../../sessiontxn/isolation/base.go:184 isolation.(*baseTxnContextProvider).GetStmtReadTS { func (p *baseTxnContextProvider) GetStmtReadTS() (uint64, error) { }
../../sessiontxn/isolation/optimistic.go:99 isolation.(*OptimisticTxnContextProvider).GetStmtReadTS { } }
../../session/txnmanager.go:97 session.(*txnManager).GetStmtReadTS { } }
../../executor/builder.go:2066 executor.(*executorBuilder).getSnapshotTS { } }
../../executor/builder.go:3476 executor.buildNoRangeTableReader { startTS, err := b.getSnapshotTS() }
../../executor/builder.go:3623 executor.(*executorBuilder).buildTableReader { ret, err := buildNoRangeTableReader(b, v) }
../../executor/builder.go:288 executor.(*executorBuilder).build { case *plannercore.PhysicalTableReader: }
../../executor/builder.go:2014 executor.(*executorBuilder).buildProjection { func (b *executorBuilder) buildProjection(v *plannercore.PhysicalProjection) exec.Executor { }
../../executor/builder.go:276 executor.(*executorBuilder).build { case *plannercore.PhysicalProjection: }
../../executor/adapter.go:1212 executor.(*ExecStmt).buildExecutor { b := newExecutorBuilder(ctx, a.InfoSchema) }
../../executor/adapter.go:555 executor.(*ExecStmt).Exec {  }
../../session/session.go:2283 session.runStmt {  }
../../session/session.go:2154 session.(*session).ExecuteStmt {  }
../../session/session.go:1517 session.(*session).ExecuteInternal {  }
../../ddl/session/session.go:84 session.(*Session).Execute { } }
../../ddl/job_scheduler.go:373 ddl.(*jobScheduler).loadAndDeliverJobs { rows, err := se.Execute(context.Background(), sql, "load_ddl_jobs") }
../../ddl/job_scheduler.go:316 ddl.(*jobScheduler).schedule { failpoint.InjectCall("beforeLoadAndDeliverJobs") }
../../ddl/job_scheduler.go:251 ddl.(*jobScheduler).scheduleLoop { for { }
../wait_group_wrapper.go:171 util.(*WaitGroupWrapper).RunWithLog.func1 { exec() }

4. What is your TiDB version? (Required)

@hawkingrei hawkingrei added the type/bug The issue is confirmed as a bug. label Aug 16, 2024
@hawkingrei hawkingrei mentioned this issue Aug 16, 2024
1 task
@ti-chi-bot ti-chi-bot bot closed this as completed in 6d403d4 Aug 16, 2024
@ti-chi-bot ti-chi-bot added affects-8.1 This bug affects the 8.1.x(LTS) versions. affects-6.5 This bug affects the 6.5.x(LTS) versions. affects-7.5 This bug affects the 7.5.x(LTS) versions. affects-7.1 This bug affects the 7.1.x(LTS) versions. labels Aug 21, 2024
ti-chi-bot bot pushed a commit that referenced this issue Aug 21, 2024
ti-chi-bot bot pushed a commit that referenced this issue Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects-6.5 This bug affects the 6.5.x(LTS) versions. affects-7.1 This bug affects the 7.1.x(LTS) versions. affects-7.5 This bug affects the 7.5.x(LTS) versions. affects-8.1 This bug affects the 8.1.x(LTS) versions. component/test severity/moderate type/bug The issue is confirmed as a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants