Hi Kyle, Thank you for the simplified example. It is showing a different problem than the one that I initially had in mind. I converted it to the following .test file and invoked ./mtr --rr on the test for more convenient debugging with rr replay: --source include/have_innodb.inc CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB; INSERT INTO t1 VALUES (1,1),(2,2),(3,3); BEGIN; SELECT * FROM t1 WHERE a=2; --connect t3,localhost,root UPDATE t1 SET b=12 WHERE a=2; --disconnect t3 --connection default SELECT * FROM t1 WHERE a=2; UPDATE t1 SET b=-1 WHERE a=2; SELECT * FROM t1 WHERE a=2; COMMIT; DROP TABLE t1; During the last UPDATE, I set a breakpoint on row_search_mvcc and then watch -l prebuilt->trx.lock.n_rec_locks to catch where the record lock is created. Here is a MariaDB Server 10.6 stack trace: #0 lock_rec_set_nth_bit (lock=0x7f4e583e5c80, i=3) at /mariadb/10.6/storage/innobase/include/lock0priv.inl:101 #1 0x0000564e48969508 in lock_rec_create_low (c_lock=0x0, type_mode=1027, page_id=..., page=0x7f4e53cd0000 "", heap_no=3, index=0x7f4e2c115a18, trx=0x7f4e583e5b80, holds_trx_mutex=false) at /mariadb/10.6/storage/innobase/lock/lock0lock.cc:1270 #2 0x0000564e4896b704 in lock_rec_lock (impl=false, mode=1027, block=0x7f4e5380f490, heap_no=3, index=0x7f4e2c115a18, thr=0x7f4e2c203118) at /mariadb/10.6/storage/innobase/lock/lock0lock.cc:1692 #3 0x0000564e4897d320 in lock_clust_rec_read_check_and_lock (flags=0, block=0x7f4e5380f490, rec=0x7f4e53cd0097 "\200", index=0x7f4e2c115a18, offsets=0x7f4e5814bb40, mode=LOCK_X, gap_mode=1024, thr=0x7f4e2c203118) at /mariadb/10.6/storage/innobase/lock/lock0lock.cc:5927 #4 0x0000564e48ac85b7 in sel_set_rec_lock (pcur=0x7f4e2c202978, rec=0x7f4e53cd0097 "\200", index=0x7f4e2c115a18, offsets=0x7f4e5814bb40, mode=3, type=1024, thr=0x7f4e2c203118, mtr=0x7f4e5814bf20) at /mariadb/10.6/storage/innobase/row/row0sel.cc:1349 #5 0x0000564e48ad3dfe in row_search_mvcc (buf=0x7f4e2c2012f8 "\377", mode=PAGE_CUR_GE, prebuilt=0x7f4e2c2027a8, match_mode=1, direction=0) at /mariadb/10.6/storage/innobase/row/row0sel.cc:5234 I tried a quick and dirty patch (attached) to fix this particular case. Note: it only works with a fixed-length PRIMARY KEY, and I did not run the regression test suite, only this particular test. We would also need something similar for secondary indexes. But it is a start: mysqltest: At line 9: query 'UPDATE t1 SET b=12 WHERE a=2' failed: ER_LOCK_DEADLOCK (1213): Deadlock found when trying to get lock; try restarting transaction Would you be interested to help fix all this? It would be an iterative process: you provide tests and we would update a branch accordingly. You could even download precompiled packages from our CI system if that is more convenient. Once we have it sorted out in some way (such as "faking" deadlock errors), then it would be time to polish it, to introduce new error messages or a new transaction isolation level, to avoid risk of breaking any applications that would expect the current buggy behaviour. First we would have to get the logic right. Best regards, Marko