We have a (currently InnoDB) table which contains roughly 500,000 rows. This represents a queue of tasks to run. It is stored in a MySQL database.
An a continual basis, at least once per second but sometimes more frequently, we select data from it and subsequently update some rows. Once per day, we prune old rows from the table.
We started getting deadlocks on the table and this brought our task processing to a standstill. These deadlocks were caused during the nightly prune run. The combination of DELETE, SELECT, and UPDATE meant that essentially nothing productive could happen. I unfortunately do not have the output of a SHOW ENGINE INNODB STATUS.
I'd like to know the best option for dealing with this. Note that our code detects deadlocks and reissues the query. Also, we long ago discovered that deleting all matching rows at once was too taxing on a database table that saw a lot of activity, so we LIMIT our deletes to 10,000 rows at a time and keep on reissuing the query until all necessary rows have been pruned.
I see the following options, and would like opinions on which are the best, or suggestions for other options:
When performing DML
operations, InnoDB
locks all rows scanned, not matched.
Consider this table layout:
DROP TABLE t_tran;
CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;
DROP TABLE t_tran;
CREATE TABLE t_tran (id INT NOT NULL PRIMARY KEY, data INT NOT NULL, KEY ix_tran_data (data)) Engine=InnoDB;
INSERT
INTO t_tran
VALUES
(1, 1),
(2, 2),
(3, 3),
(4, 4),
(5, 5),
(6, 6),
(7, 7),
(8, 8);
START TRANSACTION;
DELETE
FROM t_tran
WHERE data = 2
AND id <= 5;
In this case, MySQL
selects RANGE
access path on id
, which it considers cheaper than REF
on data
.
In a concurrent transaction, you will be able to delete or update rows 6
, 7
, 8
but not rows 1
to 5
since they are locked (despite the fact that only row 2
was affected).
If you remove id <= 5
from the condition above, you will be able to delete any row but row 3
.
Unfortunately, you cannot control MySQL
access paths in DML
operations.
Best you can do is to index your conditions properly and hope that MySQL
will pick these indexes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With