我们有一个定义如下的表:
CREATE TABLE ipsum (
id char(40) NOT NULL,
source char(40) NOT NULL,
ip_address varbinary(16) NOT NULL,
port smallint(5) unsigned NOT NULL,
percentage decimal(5,2) NOT NULL DEFAULT '0.00',
first_date datetime NOT NULL,
last_date datetime NOT NULL,
p0 tinyint(1) NOT NULL DEFAULT '0',
p1 tinyint(1) NOT NULL DEFAULT '0',
blocked tinyint(1) NOT NULL,
created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
country varchar(100) DEFAULT NULL,
continent varchar(100) DEFAULT NULL,
note varchar(100) DEFAULT NULL,
PRIMARY KEY (id),
KEY idx_first_seen_peer (first_date),
KEY idx_last_seen_peer (last_date),
KEY ipsum (source,ip_address,port)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 我们正在进行批量插入到此表中,每次多达15,000条记录。插入的结构如下:
INSERT INTO ipsum (id, source, ip_address, port, percentage, first_date, last_date, p0, p1, country, continent, note, blocked)
VALUES {{ 15000 legitimate values here sorted alphabetically by the id field }}
ON DUPLICATE KEY UPDATE
p0 = p0 OR VALUES(p0),
p1 = p1 OR VALUES(p1),
last_date = GREATEST(last_date, VALUES(last_date)),
first_date = LEAST(first_date, VALUES(first_date)),
percentage = GREATEST(percentage, VALUES(percentage));VALUES集中的记录是按id字母顺序排列的。
当我们在运行多个查询实例的情况下达到非常高的输入速率时,我们就会看到死锁:
错误: ER_LOCK_DEADLOCK:尝试锁定时发现死锁;尝试重新启动事务]
没有对表执行其他语句--只有上面描述的插入。
如何修改insert查询以防止死锁?
发布于 2017-07-04 20:36:19
在MySQL建议之后,我会考虑一些选项:
SHOW ENGINE INNODB STATUS以查看死锁在什么位置。INSERT ON DUPLICATE KEY UPDATE转换为SELECT,然后转换为INSERT或UPDATE。并发批中的ids之间的关系是什么?ids的范围是否重叠?
发布于 2017-03-03 19:58:46
尽管“显示处理列表”可能显示所有进程处于休眠状态并不一定意味着表没有被另一个进程锁定。
show open tables where name_locked=1;
select *
from performance_schema.table_lock_waits_summary_by_table
where object_schema=@db
and object_name=@tab
\Ghttps://dba.stackexchange.com/questions/164772
复制相似问题