SELECT ... FOR SHARE with tidb_enable_noop_functions=1 is accepted but TiDB acquires no shared lock
- Dominant language
- Go
- Stars
- 40.5k
- Forks
- 6.2k
- PR merge metrics
- PR metrics pending
Description
## Bug Report
Please answer these questions before submitting your issue. Thanks!
### 1. Minimal reproduce step (Required)
```sql
-- Session A:
SET SESSION tidb_enable_noop_functions=1;
BEGIN;
SELECT v FROM t WHERE id=1 FOR SHARE;
SELECT SLEEP(5);
COMMIT;
-- Session B, about one second later:
SET SESSION tidb_enable_noop_functions=1;
BEGIN;
SET SESSION innodb_lock_wait_timeout=1;
SELECT v FROM t WHERE id=1 FOR UPDATE;
ROLLBACK;
```
Probe output:
```text
MYSQL_B_RC=1
MYSQL_B_OUT=''
MYSQL_B_ERR=ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
MYSQL_B_DURATION=1.02
MYSQL_FOR_SHARE_LOCK_ENFORCED
TIDB_FOR_SHARE_RC=0
TIDB_FOR_SHARE_OUT='10'
TIDB_FOR_SHARE_ACCEPTED
TIDB_B_RC=0
TIDB_B_OUT='10'
TIDB_B_DURATION=0.01
TIDB_FOR_SHARE_LOCK_IGNORED
```
MySQL blocks the concurrent writer; TiDB returns the row immediately because `FOR SHARE` acquired no lock.
### 2. What did you expect to see? (Required)
When `FOR SHARE` is accepted, session A must hold a shared lock and session B's `FOR UPDATE` must block until `innodb_lock_wait_timeout`, matching MySQL. If shared locks are unsupported, `FOR SHARE` must be rejected instead of silently taking no lock.
### 3. What did you see instead (Required)
MySQL: session A FOR SHARE blocks session B FOR UPDATE with ERROR 1205 after 1.02s. TiDB a514: same sequence with the noop switch returns 10 in 0.01s.
### 4. What is your TiDB version? (Required)
```text
Release Version: v8.4.0-this-is-a-placeholder
Edition: Community
Git Commit Hash: None
Git Branch: None
UTC Build Time: None
GoVersion: go1.25.12
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
```
Built from source commit `a514a92784c9654502686e6ee6efc9e0aeda8afa` (pingcap/tidb master, 2026-09-07).
### 5. Root cause (optional)
- pkg/planner/core/preprocess.go:1344-1350 sets ForShareLockEnabledByNoop when tidb_enable_noop_functions=1
- pkg/sessionctx/variable/session.go:3955-3958 returns false from PessimisticLockEligible when that flag is set
- pkg/planner/core/operator/logicalop/logical_lock.go:145-153 lists FOR SHARE as a supported lock type, but the noop flag skips acquisition
Contributor guide
Research direction
Start by reproducing the two-session SQL sequence and then read the referenced logic in pkg/planner/core/preprocess.go, pkg/sessionctx/variable/session.go, and pkg/planner/core/operator/logicalop/logical_lock.go. Trace how the noop flag affects FOR SHARE eligibility and lock acquisition. Done means an accepted FOR SHARE blocks the concurrent FOR UPDATE as shown, or the statement is rejected when shared locks are unsupported.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100