【发布时间】:2017-09-15 14:38:17
【问题描述】:
我有一个mysql(实际上是MariaDB 5.5.52)数据库,大致描述如下:
CREATE TABLE table1 (
id INT NOT NULL AUTOINCREMENT,
col1 INT,
col2 VARCHAR(32),
col3 VARCAHR(128),
PRIMARY KEY (ID),
UNIQUE KEY index1 (col1, col2, col3)
);
列比较多,但都在UNIQUE键里面,表中没有其他键。
我运行插入此数据库的 python 脚本的多个线程。每个线程使用 mysql.connector 的 executemany 进行大约 100-1000 次插入,例如
ins_string = "INSERT IGNORE INTO table1 ({0}) VALUES ({1});"
cursor.executemany(ins_string.format(fields, string_symbols), values)
我遇到了一致的死锁问题。我认为这些问题是由于每个线程根据我的python列表values的生成顺序以某种半随机顺序锁定table1的行之间造成的。这在一定程度上通过测试得到了验证;当我使用 24 个线程从头开始构建一个新数据库时,每个 executemany() 语句的死锁率 > 80%,但是当数据库中有超过一百万行时,死锁率接近于零。
我曾考虑过死锁是线程竞争 AUTOINCREMENT 的结果,但在默认的 InnoDB 'consecutive' 锁定模式下,这似乎不应该发生。每个线程都应该得到一个table level lock,直到插入结束。但是,AUTOINCREMENT 和 INSERT 锁的交互方式让我感到困惑,所以如果我有这个错误,请告诉我。
因此,如果问题是由唯一键的随机排序引起的,我需要某种方式在 python 中对插入语句进行排序,然后再将它们传递给 MySql。索引由 MySql 以某种方式散列,然后排序。如何在 python 中复制散列/排序?
我在这里询问我对问题的诊断的解决方案,但如果您发现我的诊断有误,请再次告诉我。
【问题讨论】:
标签: python mysql mariadb innodb