I have a distributed application that registers millions of records in MySQL. Sometimes it's a million per day or week, depending on the user.
I recently rewrote a “cleanup” system that automatically deletes obsolete entries. It works every 12 hours and cleans up the data in accordance with the rules set by the user. Since a database can often contain more than 50 million records on average, I designed a query to use primary key allocation .
Each delete request only checks a limited number of rows with its primary key. In my opinion, this reduces the number of locks needed to “keep” another when conditions are present. The next delete request is completed in a few seconds.
However, many of our users still see “wait wait locks,” and they always indicate cleanup requests.
DELETE FROM prism_data WHERE prism_data.id >= 7564001 AND prism_data.id < 7568001 AND prism_data.epoch <= '1388566847'
Here is part of the engine status report:
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1248, 1 row lock(s)
MySQL thread id 458, OS thread handle 0x7efed0c62700, query id 779832 localhost 127.0.0.1 prism updating
DELETE FROM prism_data WHERE prism_data.id >= 7564001 AND prism_data.id < 7568001 AND prism_data.epoch <= '1388566847'
RECORD LOCKS space id 0 page no 606 n bits 1272 index `epoch` of table `prism`.`prism_data` trx id 208A7E lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 52d7d976; asc R v;;
1: len 4; hex 00000001; asc ;;
Just for you to have it, here is the table layout:
CREATE TABLE IF NOT EXISTS `prism_data` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`epoch` int(10) unsigned NOT NULL,
`action_id` int(10) unsigned NOT NULL,
`player_id` int(10) unsigned NOT NULL,
`world_id` int(10) unsigned NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`z` int(11) NOT NULL,
`block_id` mediumint(5) DEFAULT NULL,
`block_subid` mediumint(5) DEFAULT NULL,
`old_block_id` mediumint(5) DEFAULT NULL,
`old_block_subid` mediumint(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `epoch` (`epoch`),
KEY `location` (`world_id`,`x`,`z`,`y`,`action_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
, , , , , . mysql. -, , , , - ?
:
:
[13:43:47 INFO]: [Prism]: Database connection error: Lock wait timeout exceeded; try restarting transaction
[13:43:47 WARN]: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
[13:43:47 WARN]: at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073)
[13:43:47 WARN]: at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593)
[13:43:47 WARN]: at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525)
[13:43:47 WARN]: at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986)
[13:43:47 WARN]: at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)
[13:43:47 WARN]: at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620)
[13:43:47 WARN]: at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1662)
[13:43:47 WARN]: at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1581)
[13:43:47 WARN]: at me.botsko.prism.actionlibs.ActionsQuery.delete(ActionsQuery.java:346)
[13:43:47 WARN]: at me.botsko.prism.purge.PurgeTask.run(PurgeTask.java:84)
SHOW FULL PROCESSLIST, :
http://i.imgur.com/DxL4Rk1.png
,