简体   繁体   中英

`InnoDB` placing a lock on a table that has no `insert` or `update` operations pending

I'm currently have a long process that inserts rows into table A sourced from a complex join query between A and B . Since this process started, all insert operations into table B have timed out. This is what shows when I do SHOW ENGINE INNODB STATUS :

---TRANSACTION 3597993, ACTIVE 108 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 173507, OS thread handle 140455303333632, query id 1051475 10.0.0.6 root update
INSERT INTO `B` (`id`, `time`, `elem_1`, `elem_2`) VALUES (251322486, '2018-04-27 19:29:59', 'PTY', 'USD')
------- TRX HAS BEEN WAITING 108 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6 page no 5859 n bits 96 index PRIMARY of table `default`.`B` trx id 3597993 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

My understanding of the InnoDB rules is that there shouldn't be a lock happening on B , since the only running process is reading from it, and not updating or inserting.

The ongoing insert operation has this structure:

insert into `default`.A
select * from (select i1.id, min(IFNULL(i2.id,-1)) as next_id, i1.item_1, i1.item_2 from
(select idx.id, idx.item_2, idx.item_2
 from `default`.B idx left join `default`.A map on
idx.id = map.id and idx.item_1 = map.item_1 where map.id is null or map.next_id = -1) i1 left join
`default`.B i2 on i1.id < i2.id and i1.item_1 = i2.item_1 and i1.item_2 = i2.item_2
group by i1.id, i1.item_1, i1.item_2) new_entries
on duplicate key update next_id = new_entries.next_id

This is the version of the db I'm using:

mysql> SHOW VARIABLES LIKE "%version%";
+-------------------------+--------------------------------------+
| Variable_name           | Value                                |
+-------------------------+--------------------------------------+
| innodb_version          | 5.7.21                               |
| protocol_version        | 10                                   |
| slave_type_conversions  |                                      |
| version                 | 10.2.13-MariaDB-10.2.13+maria~jessie |
| version_comment         | mariadb.org binary distribution      |
| version_compile_machine | x86_64                               |
| version_compile_os      | debian-linux-gnu                     |
| version_malloc_library  | system                               |
| version_ssl_library     | OpenSSL 1.0.1t  3 May 2016           |
| wsrep_patch_version     | wsrep_25.21                          |
+-------------------------+--------------------------------------+

UPDATE

I stopped the long-standing operation and restarted it, and the inserts now proceed seemingly unimpeded, so I'm leaning toward considering this some transient bug

InnoDB does create shared locks on rows in the table you SELECT from if you are using the result of the SELECT in some way that saves data into a table or a variable.

INSERT INTO T1 SELECT ... FROM T2 ...;

CREATE TABLE T1 AS SELECT ... FROM T2 ...;

SET @my_variable = (SELECT ... FROM T2 ...);

SELECT ... INTO @my_variable, ... FROM T2 ...;

In all the cases above, rows in T2 get shared locks. Shared means multiple concurrent statements can have shared locks on the same rows, but no concurrent statement can get an exclusive lock on a set of rows while any shared locks exist on those rows.

See https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM