Удаление одной строки из большой таблицы MySql приводит к «тайм-ауту блокировки» - PullRequest
9 голосов
/ 05 мая 2011

Я использую MySql 5.0.22 и у меня действительно громоздкая таблица, содержащая приблизительно 5 миллионов строк.

Некоторые, но не все строки ссылаются внешним ключом на другую таблицу.

До сих пор все попытки отбраковки строк, на которые нет ссылок, приводили к истечению времени ожидания блокировки каждый раз.

Копирование строк, которые я хочу, в альтернативную таблицу также не удавалось с временем ожидания блокировки.даже утверждение, которое должно завершиться мгновенно, как показано ниже, также потерпит неудачу с «тайм-аутом блокировки»:

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$$

Примечание,пытаясь дроp FK также истекает.

Ответы [ 2 ]

3 голосов
/ 20 июля 2011

У меня была такая же проблема с таблицей innodb. оптимизировать таблицу, исправить это.

1 голос
/ 12 мая 2011

Хорошо, я наконец нашел подход, который работал, чтобы обрезать ненужные строки из моей большой таблицы InnoDB!Вот как я это сделал:

  1. Остановлен с помощью MySQL Workbench (у них жестко задан тайм-аут выполнения 30 секунд)
  2. Открыта командная строка
  3. Переименован«полная» таблица с использованием ALTER TABLE
  4. Создана пустая таблица с использованием исходного имени и структуры таблицы
  5. Перезагрузка MySQL
  6. Отключено «Автокоммит» с SET AUTOCOMMIT = 0
  7. Удаление ограниченного числа строк за раз, увеличивая мой лимит после каждого успеха
  8. Сделал COMMIT;между операциями удаления, так как отключение автоматической фиксации действительно оставило меня внутри одной большой транзакции

Все усилия выглядели примерно так:

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

... как ни странно, переименованиеtable была единственной командой 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;

... Как только я начал удалять 100 Кбайт, время выполнения InnoDB уменьшалось с каждой успешной командой.Я предполагаю, что InnoDB начинает делать упреждающие чтения при больших сканированиях.Выполнение коммитов сбрасывает данные упреждающего чтения, поэтому я распределил коммиты каждые 2 миллиона строк, пока работа не будет завершена.

Я завернул задачу, скопировав оставшиеся строки в мой «пустой» клонtable, затем удаляя старую (переименованную) таблицу.

Не изящное решение, и оно не устраняет никаких причин, по которым удаление хотя бы одной строки из большой таблицы может завершиться неудачей, но по крайней мере я получил результатЯ искал!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...