2011-05-05 75 views
9

我正在運行MySql 5.0.22,並且有一個真正不方便的表,其中包含大約500萬行。從大的MySql表中刪除單行導致「鎖定超時」

有些但不是所有的行都被外鍵引用到另一個表中。

迄今爲止所有嘗試剔除未引用的行都失敗了,每次都會導致鎖定超時。

將我想要的備份表的行復制到鎖定超時也失敗。

可疑,甚至應該立即完成像一個聲明下面也將失敗,並「鎖定超時」:

DELETE FROM mytable WHERE uid_pk = 1 LIMIT 1; 

...它是在這一點上,我已經江郎才盡。

編輯:爲什麼它的價值,我一直在通過我的開發系統上的工作,所以只有我實際上在這個時候使用數據庫,所以不應該有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$$ 

注意,嘗試刪除該FK也超時。

+0

您正在使用數據庫引擎? InnoDB,MyISAM,另一個? – 2011-05-05 19:48:30

+0

織補細節!我正在使用InnoDB。 – Rocjoe 2011-05-06 20:21:26

+0

可以在哪裏有一個開放的事務嗎?嘗試重新啓動MySQL。 – Galz 2011-05-07 00:46:59

回答

1

好吧,我終於找到了一種方法來修剪我的大型InnoDB表中不需要的行!以下是我做的:

  1. 使用MySQL工作臺(他們有30秒的硬編碼的執行超時)
  2. 打開一個命令提示符
  3. 使用ALTER TABLE
  4. 改名爲「滿」錶停
  5. 創建使用原始表的名稱和結構
  6. 重啓的MySQL
  7. 一個空表車削OFF '自動提交' 用SET AUTOCOMMIT = 0
  8. 刪除d一次有限數量的行,在每次成功後增加我的限制
  9. 做了一個COMMIT;在DELETE語句之間,因爲關閉自動提交真的給我留下了一個大交易的內部

全部努力,有些看上去像這樣:

ALTER TABLE `ep411`.`tunknowncustomer` RENAME TO `ep411`.`tunknowncustomer2`; 

...自嘆不如,重命名錶中是唯一的ALTER TABLE命令即可完成。

delimiter $$ 

CREATE TABLE `tunknowncustomer` (
    ... 
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$ 

...然後重啓,以防萬一我以前失敗的嘗試可能會阻止做過任何新的工作......

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; 

......一旦我進入一次InnoDB的執行刪除100K隨着每一個成功的命令都會下降我認爲InnoDB開始在大型掃描中進行預讀。做提交會重置預讀數據,所以我將COMMIT分隔到每200萬行,直到作業完成。

我通過將其餘行復制到我的「空」克隆表中,然後刪除舊的(重命名的)表來包裝任務。

不是一個優雅的解決方案,它沒有解決任何爲什麼從大表中刪除單行應該失敗的原因,但至少我得到了我期待的結果!

3

我對innodb表有同樣的問題。優化表糾正它。