Roc*_*joe 10 mysql innodb locking
我正在运行MySql 5.0.22并且有一个非常笨重的表,包含大约500万行.
某些但不是所有行都由另一个表的外键引用.
到目前为止,所有剔除未引用行的尝试都失败了,每次都会导致锁定超时.
将我想要的行复制到备用表也会因锁定超时而失败.
可疑的是,即使是一个应该像下面那样立即完成的声明也会因"锁定超时"而失败:
DELETE FROM mytable WHERE uid_pk = 1 LIMIT 1;
Run Code Online (Sandbox Code Playgroud)
......就在这时,我已经没有想法了.
编辑:为了它的价值,我一直在我的开发系统上完成这个工作,所以现在只有我实际上在使用数据库所以不应该在我正在运行的SQL之外进行任何锁定.
任何MySql专家都有关于如何驯服这个流氓表的建议?
编辑#2:根据要求,表格结构:
CREATE TABLE `tunknowncustomer` (
`UID_PK` int(11) NOT NULL auto_increment,
`UNKNOWNCUSTOMERGUID` varchar(36) NOT NULL,
`CREATIONDATE` datetime NOT NULL,
`EMAIL` varchar(100) default NULL,
`CUSTOMERUID` int(11) default NULL,
PRIMARY KEY (`UID_PK`),
KEY `IUNKNOWCUST_CUID` (`CUSTOMERUID`),
KEY `IUNKNOWCUST_UCGUID` (`UNKNOWNCUSTOMERGUID`),
CONSTRAINT `tunknowncustomer_ibfk_1` FOREIGN KEY (`CUSTOMERUID`) REFERENCES `tcustomer` (`UID_PK`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
Run Code Online (Sandbox Code Playgroud)
注意,试图放弃FK也会超时.
好吧,我终于找到了一种方法,可以从我的大型 InnoDB 表中删除不需要的行!我是这样做的:
整个工作看起来有点像这样:
ALTER TABLE `ep411`.`tunknowncustomer` RENAME TO `ep411`.`tunknowncustomer2`;
Run Code Online (Sandbox Code Playgroud)
...奇怪的是,重命名表是唯一会立即完成的 ALTER TABLE 命令。
delimiter $$
CREATE TABLE `tunknowncustomer` (
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$
Run Code Online (Sandbox Code Playgroud)
...然后重新启动,以防我之前失败的尝试可能会阻止完成任何新工作...
SET AUTOCOMMIT = 0;
delete from tunknowncustomer2 where customeruid is null limit 1000;
delete from tunknowncustomer2 where customeruid is null limit 100000;
commit;
delete from tunknowncustomer2 where customeruid is null limit 1000000;
delete from tunknowncustomer2 where customeruid is null limit 1000000;
commit;
Run Code Online (Sandbox Code Playgroud)
...一旦我一次删除 100k,InnoDB 的执行时间就会随着每个成功的命令而下降。我假设 InnoDB 开始对大型扫描进行预读。进行提交会重置预读数据,因此我将 COMMIT 间隔为每 200 万行,直到作业完成。
我通过将剩余的行复制到“空”克隆表中,然后删除旧的(重命名的)表来完成任务。
这不是一个优雅的解决方案,它没有解决为什么从大表中删除一行会失败的任何原因,但至少我得到了我正在寻找的结果!