Why do I get a MySQL database deadlock in this situation? - mysql

I find a similar question asked here Deadlock using SELECT ... FOR UPDATE in MySQL. But the answer didn't really explain why this happens.
The situation is quite easy to reproduce # Mysql 5.7.17 (or other versions in 5.5 or 5.6):
CREATE TABLE `test` (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`val` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `search` (`val`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
insert into test set val='pre-lock';
==session1==
start transaction;
select * from test where val='pre-lock' for update;
==session2==
start transaction;
select * from test where val='pre-lock' for update;
==session1==
insert into test set val='/a/b/c'; //note that if the set val='pre-lock111', there will be no deadlock at session 2
==session2==
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
The result of show engine innodb status:
LATEST DETECTED DEADLOCK
------------------------
2017-04-06 23:54:03 0x7000057db000
*** (1) TRANSACTION:
TRANSACTION 1333, ACTIVE 18 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 5, OS thread handle 123145394155520, query id 62 localhost root Sending data
select * from test where val='pre-lock' for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 4 n bits 72 index search of table `test_tnx`.`test` trx id 1333 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 7072652d6c6f636b; asc pre-lock;;
1: len 8; hex 8000000000000001; asc ;;
*** (2) TRANSACTION:
TRANSACTION 1332, ACTIVE 29 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1136, 4 row lock(s), undo log entries 1
MySQL thread id 62, OS thread handle 123145394434048, query id 63 localhost root update
insert into test set val='/a/b/c'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 24 page no 4 n bits 72 index search of table `test_tnx`.`test` trx id 1332 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 7072652d6c6f636b; asc pre-lock;;
1: len 8; hex 8000000000000001; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 24 page no 4 n bits 72 index search of table `test_tnx`.`test` trx id 1332 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 7072652d6c6f636b; asc pre-lock;;
1: len 8; hex 8000000000000001; asc ;;
*** WE ROLL BACK TRANSACTION (1)
My perception is that the insert clause in session 1 acquires a gap lock which is somehow overlapping with the gap lock by the select for update. And therefore, this create a deadlock. However, I couldn't find any document supporting my idea. Please help to explain.
Updated 1 on 7th. Apr. 2017:
My full use case is like follows. Each session starts a transaction. It first locks the "pre-lock" row for uniqueness, after which performs a set of insertions. Then, it commits all insertions and release the lock. To my understand, if I remove the "pre-lock", two transactions may result in deadlock, and both fail (mysql kills one and let the other go as pointed out by #Michael - sqlbot). Meanwhile, it is allowed for some other sessions to read the content of the table already been committed beforeļ¼Œ and therefore, exclusively locking the table is not the cue.
Updated 2 on 7th. Apr. 2017:
It it quite a long story to to fully explain my objective. In short, I want to use mysql as a locking service for an external system. These insertions I mentioned is a set of external locks. It can not be made unique since I have read/write locks, and want to support kind of wildcard. Before these insertions, I actually need to do a conflict analysis with a set of selections. Setting up a global pre-lock sounds a good solution for me to accomplish this task.

Related

Does WHERE clause affect how MySQL locks a table?

We are encountering deadlocks that at first glance doesn't make sense.
We have the following table:
liveMember (id, memberID, liveID, dateUpdated, dateLeft)
And we have a keep-alive endpoint in our application that constantly updates the dateUpdated column every 10 seconds.
Here is our UPDATE statement:
UPDATE
`liveMember`
SET
`liveMember`.`dateUpdated` = NOW()
WHERE 1
AND `liveMember`.`liveID` = 139959
AND `liveMember`.`memberID` = 3761423
AND `liveMember`.`dateLeft` IS NULL
And this is a deadlock:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2020-07-28 19:09:21 2b598948a700
*** (1) TRANSACTION:
TRANSACTION 4555766560, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
LOCK WAIT 4 lock struct(s), heap size 1184, 3 row lock(s)
MySQL thread id 116431423, OS thread handle 0x2b5b67943700, query id 1402103525 ---- et updating
UPDATE
`liveMember`
SET
`liveMember`.`dateUpdated` = NOW()
WHERE 1
AND `liveMember`.`liveID` = 139959
AND `liveMember`.`memberID` = 3761423
AND `liveMember`.`dateLeft` IS NULL
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 170197 page no 1244 n bits 1160 index `liveID` of table `et_inevent`.`liveMember` trx id 4555766560 lock_mode X waiting
Record lock, heap no 227 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 800222b7; asc " ;;
1: len 4; hex 80028bba; asc ;;
*** (2) TRANSACTION:
TRANSACTION 4555766561, ACTIVE 0 sec starting index read
mysql tables in use 3, locked 3
5 lock struct(s), heap size 1184, 4 row lock(s)
MySQL thread id 116431422, OS thread handle 0x2b598948a700, query id 1402103526 ------ et updating
UPDATE
`liveMember`
SET
`liveMember`.`dateUpdated` = NOW()
WHERE 1
AND `liveMember`.`liveID` = 139959
AND `liveMember`.`memberID` = 3761474
AND `liveMember`.`dateLeft` IS NULL
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 170197 page no 1244 n bits 1160 index `liveID` of table `et_inevent`.`liveMember` trx id 4555766561 lock_mode X
Record lock, heap no 227 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 800222b7; asc " ;;
1: len 4; hex 80028bba; asc ;;
Both updates belong to the same liveID, however, they should never update the same row since they use two different memberID values.
Would changing the order of our WHERE clause help our database detect that the lock should only be done on rows with that given memberID?
Am I missing something here?
Index table:
Result of EXPLAIN:
Thanks.

Why did this deadlock happen in MySQL?

I use JMeter to test my program, somehow the total response number is stopping increasing, then I find out there is a deadlock in MySQL. I don't understand what's meaning of below log. Seems that transaction(2) owned a S lock and trying to own a X lock of the same table. Does this cause the deadlock? If so, why will this happen?
ATEST DETECTED DEADLOCK
------------------------
2019-01-02 14:38:27 0x70000f30a000
*** (1) TRANSACTION:
TRANSACTION 24004, ACTIVE 0 sec inserting
mysql tables in use 2, locked 2
LOCK WAIT 5 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11953, OS thread handle 123145549275136, query id 418447 localhost 127.0.0.1 username executing
INSERT INTO MRBS_SCHEDULE (ID,START_TIME,END_TIME,ROOM_ID,CREATE_BY,PRESIDE,REPEAT_ID,DESCRIPTION,NUM,TITLE,PRESIDE_EMAIL,PROJECTOR,CONFERENCE_CALL,CREATE_ID,BOOK_TIME,END_TYPE,EXPECTED_END_TIME) select null,'2019-01-03 19:53:00','2019-01-03 19:53:00',10113558,'d','d',12245755,'fdsfds',10,null,'d#sh.ff.com',0,0,10227622,'2019-01-02 14:38:27.358',0,'2019-01-03 19:53:00' from dual WHERE NOT EXISTS (SELECT * FROM MRBS_SCHEDULE ms where ms.START_TIME<'2019-01-03 19:53:00' and ms.END_TIME>'2019-01-03 19:53:00' and ms.ROOM_ID=10113558)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24004 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;;
*** (2) TRANSACTION:
TRANSACTION 24005, ACTIVE 0 sec inserting
mysql tables in use 2, locked 2
5 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11940, OS thread handle 123145557155840, query id 418448 localhost 127.0.0.1 username executing
INSERT INTO MRBS_SCHEDULE (ID,START_TIME,END_TIME,ROOM_ID,CREATE_BY,PRESIDE,REPEAT_ID,DESCRIPTION,NUM,TITLE,PRESIDE_EMAIL,PROJECTOR,CONFERENCE_CALL,CREATE_ID,BOOK_TIME,END_TYPE,EXPECTED_END_TIME) select null,'2019-01-03 19:54:00','2019-01-03 19:54:00',10113685,'z','z',12245756,'fdsfds',10,null,'z#sz.ff.com',0,0,10227544,'2019-01-02 14:38:27.397',0,'2019-01-03 19:54:00' from dual WHERE NOT EXISTS (SELECT * FROM MRBS_SCHEDULE ms where ms.START_TIME<'2019-01-03 19:54:00' and ms.END_TIME>'2019-01-03 19:54:00' and ms.ROOM_ID=10113685)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24005 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24005 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;;
*** WE ROLL BACK TRANSACTION (2)
Edit: Table MRBS_SCHEDULE primary key use Auto_increment
Deadlock can occur anytime and it is normal behavior. It happens when transaction 1 tries to update Table B using Table A but at the same time Transaction 2 tries to update Table A using Table B.
basicly Transactions holds theirselves and since nobody wants to give up, deadlock occurs.
you can set deadlock threshold for your db using innodb_lock_wait_timeout
From the documentation,
When deadlock detection is enabled (the default), InnoDB automatically detects transaction deadlocks and rolls back a transaction or transactions to break the deadlock. InnoDB tries to pick small transactions to roll back, where the size of a transaction is determined by the number of rows inserted, updated, or deleted.
InnoDB is aware of table locks if innodb_table_locks = 1 (the default) and autocommit = 0, and the MySQL layer above it knows about row-level locks. Otherwise, InnoDB cannot detect deadlocks where a table lock set by a MySQL LOCK TABLES statement or a lock set by a storage engine other than InnoDB is involved. Resolve these situations by setting the value of the innodb_lock_wait_timeout system variable.
Reference: https://dev.mysql.com/doc/refman/8.0/en/innodb-deadlock-detection.html

Why do two concurrent delete + insert statements deadlock on an empty table?

I'm curious to know why two concurrent DELETE followed by INSERT statements that use primary keys causes a deadlock in MySQL when the primary keys don't exist. The example is contrived to illustrate the issue in it's simplest form.
Here is the setup.
> SELECT ##GLOBAL.tx_isolation, ##tx_isolation;
+-------------------------+------------------+
| ##GLOBAL.tx_isolation | ##tx_isolation |
|-------------------------+------------------|
| REPEATABLE-READ | REPEATABLE-READ |
+-------------------------+------------------+
1 row in set
Time: 0.002s
> select version();
+-------------+
| version() |
|-------------|
| 5.7.12 |
+-------------+
1 row in set
Time: 0.002s
create table lock_test ( id int(11) not null, primary key (`id`) );
Below, 1> represents one mysql terminal and 2> represents another.
1> begin;
1> delete from lock_test where id = 1;
2> begin;
2> delete from lock_test where id = 2;
1> insert into lock_test values (1); -- hangs
2> insert into lock_test values (2);
*** deadlock ***
Here's the show engine innodb status output:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-06-06 16:15:18 0x70000ba52000
*** (1) TRANSACTION:
TRANSACTION 807765, ACTIVE 46 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 620, OS thread handle 123145496289280, query id 43097 localhost ::1 root update
insert into lock_test values (1)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6819 page no 3 n bits 72 index PRIMARY of table `content_graph`.`lock_test` trx id 807765 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;;
*** (2) TRANSACTION:
TRANSACTION 807766, ACTIVE 37 sec inserting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 617, OS thread handle 123145497681920, query id 43099 localhost ::1 root update
insert into lock_test values (2)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 6819 page no 3 n bits 72 index PRIMARY of table `content_graph`.`lock_test` trx id 807766 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 6819 page no 3 n bits 72 index PRIMARY of table `content_graph`.`lock_test` trx id 807766 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;;
*** WE ROLL BACK TRANSACTION (2)
Note that if you first insert records with ids 1, and 2 then repeat the sequence above there is no deadlock.
My sense is that because the key is not in the index (both are appending) the delete has to lock more of the index (more of the page the primary would land in) but I want to make sure I have my understanding correct.
The "gap" is locked in anticipation that someone may try to insert the row I am trying to delete.
Or, to look at it another way... It would be too slow to perfectly handle every odd case. So, InnoDB chooses to handle most cases efficiently and punt on the rare oddball case.
Bottom line: Live with it. You will get deadlocks. You won't necessarily be able to understand them. But your code needs to recover -- by simply rolling back and going back to the BEGIN.

Deadlock using SELECT ... FOR UPDATE in MySQL

Let's say I have the table:
CREATE TABLE t (id INTEGER AUTOINCREMENT NOT NULL, desc TEXT NOT NULL)
I populate the table with 1 element:
INSERT INTO TABLE t VALUES (1, 'Hello')
And I run two transactions in MySQL. In t1 I run:
START TRANSACTION;
SELECT * FROM t WHERE id = 1 FOR UPDATE;
In t2 I run:
START TRANSACTION;
SELECT * FROM t WHERE id = 1 FOR UPDATE;
At this point I expect t1 to hold an e(X)clusive lock on the row, and t2 to wait until it can get an X lock (and t2 gets indeed blocked, so far so good). I then run an update in t1 (without any WHERE clause!):
UPDATE t SET desc = 'Hello from t1';
At this point in t2 I get immediately (no need to COMMIT the transaction) the error:
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Why am I getting this error? I guess there is a lock that t2 is obtaining that the full UPDATE needs to proceed, making a deadlock, but I don't understand how can t2 obtain a lock given that it should be waiting for t1 to finish.
What works and what does not
A way to make both transactions run through without a deadlock is to change the isolation level to READ COMMITED (or READ UNCOMMITED) in both connections:
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
(before start transaction).
Likely it would be enough to set it in t2, but just to be sure for the example, set it in both.
Changing the isolation level of transactions does introduce some side-effects, which one should inform about in the manual before changing this in a production environment.
Status information concerning deadlock
------------------------
LATEST DETECTED DEADLOCK
------------------------
140424 8:45:46
*** (1) TRANSACTION:
TRANSACTION B6F18A3, ACTIVE 5 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s)
MySQL thread id 13885, OS thread handle 0x7f8b1dbd2700, query id 901012
localhost root statistics
SELECT * FROM t WHERE id = 1 FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A3 lock_mode X locks rec but not gap waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** (2) TRANSACTION:
TRANSACTION B6F18A2, ACTIVE 10 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 376, 2 row lock(s)
MySQL thread id 13888, OS thread handle 0x7f8b1f64d700, query id 901068
localhost root Updating
UPDATE t SET `descc` = 'Hello from t1'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A2 lock_mode X locks rec but not gap
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 22921 n bits 72 index `PRIMARY` of table
`test`.`t` trx id B6F18A2 lock_mode X waiting
Record lock, heap no 4 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
0: len 4; hex 80000001; asc ;;
1: len 6; hex 00000b6f1883; asc o ;;
2: len 7; hex 06000059a211ea; asc Y ;;
3: len 5; hex 48656c6c6f; asc Hello;;
*** WE ROLL BACK TRANSACTION (1)
Explanation
As a_horse_with_no_name mentioned, this seems like a bug in MySQL. Transaction (2) wants to obtain a gap lock on the same row it already holds an X lock. Transaction (1) waits for a non-gap X lock on this row. It is not clear to me why this requests should conflict. Setting the isolation level to READ COMMITTED disables gap locking. Since the example works then, this is a hint that gap locking is indeed the problem here.

Why is this a deadlock (MySQL using InnoDB)

SHOW INNODB ENGINE STATUS shows me this and calls it deadlock:
LATEST DETECTED DEADLOCK
100923 22:29:21
* (1) TRANSACTION:
TRANSACTION 0 5335752, ACTIVE 0 sec, OS thread id 7992 inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1024, 4 row lock(s), undo log entries 3
MySQL thread id 26, query id 14422 localhost 127.0.0.1 root update
insert into history_messagearguments (history_id, messageArguments_ORDER, messageArguments) values (69, 1, '1')
* (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs of table zvs_rkl_01_test.history_messagearguments trx id 0 5335752 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 198 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 8000000000000048; asc H;; 1: len 6; hex 0000006fe7c5; asc o ;;
* (2) TRANSACTION:
TRANSACTION 0 5335748, ACTIVE 0 sec, OS thread id 6988 inserting, thread declared inside InnoDB 500
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1024, 3 row lock(s), undo log entries 2
MySQL thread id 25, query id 14424 localhost 127.0.0.1 root update
insert into history_messagearguments (history_id, messageArguments_ORDER, messageArguments) values (71, 0, '0')
* (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs of table zvs_rkl_01_test.history_messagearguments trx id 0 5335748 lock_mode X locks gap before rec
Record lock, heap no 198 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 8000000000000048; asc H;; 1: len 6; hex 0000006fe7c5; asc o ;;
* (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs of table zvs_rkl_01_test.history_messagearguments trx id 0 5335748 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 198 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 8; hex 8000000000000048; asc H;; 1: len 6; hex 0000006fe7c5; asc o ;;
* WE ROLL BACK TRANSACTION (2)
I cannot see why this is a deadlock. There is no line "WAITING FOR THIS LOCK TO BE GRANTED:" for transaction 1. If transaction 1 does not hold any locks, it cannot block anyone, so it cannot be part of a deadlock.
More theoretically, I cannot see condition 4 being satisfied as written here:
http://en.wikipedia.org/wiki/Deadlock#Necessary_conditions
The way I see it, MySQL should let transaction 2 continue. After it completes, transaction 1 can then go on.
Here (http://stackoverflow.com/questions/1851528/mysql-deadlock-explanation-needed) BrainCore wrote:
Transaction 2 gets "stuck" behind Transaction 1's request, a la FIFO queue.
Can anyone point me to MySQL documentation to confirm this? I find it hard to believe that transactions are strictly executed in the order they arrive.
Before all the questions about the table layout, isolation level etc. show up: I do not ask for help right now about resolving the deadlock. I ask how to read the SHOW ENGINE STATUS OUTPUT.
Read transactions 1 and 2:
Read from end to begining:
what type and why: lock_mode X locks gap before rec insert intention waiting
what is blocked:RECORD LOCKS space id 0 page no 179145 n bits 304 index fk_history_msgargs of table zvs_rkl_01_test.history_messagearguments trx id 0 5335748
WAITING FOR THIS LOCK TO BE GRANTED
InnoDB has problem with concurrent writes, especially if You insert data in the end of innodb table.