Исправление "превышен тайм-аут ожидания блокировки; попробуйте перезапустить транзакцию" для "застрявшей" таблицы Mysql?



из скрипта я отправил такой запрос тысячи раз в мою локальную базу данных:



update some_table set some_column = some_value


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



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



Lock wait timeout exceeded; try restarting transaction


это таблица innodb, поэтому застрявшая транзакция, вероятно, неявна. Как я могу исправить эту таблицу и удалить застрявшую транзакцию из нее?

2000   12  

12 ответов:

у меня была аналогичная проблема, и я решил ее, проверив потоки, которые работают. Чтобы увидеть запущенные потоки, используйте следующую команду в интерфейсе командной строки mysql:

SHOW PROCESSLIST;

Он также может быть отправлен из phpMyAdmin, если у вас нет доступа к интерфейсу командной строки mysql.
Это отобразит список потоков с соответствующими идентификаторами и временем выполнения, так что вы можете убить потоки, которые занимают слишком много времени для выполнения. В phpMyAdmin у вас будет кнопка для остановка потоков с помощью KILL, если вы используете интерфейс командной строки, просто используйте команду KILL, за которой следует идентификатор потока, как в следующем примере:

KILL 115;

это приведет к прекращению соединения для соответствующего потока.

вы можете проверить текущие транзакции с

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`

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

KILL 1234;

если вы не уверены, какая транзакция ваша, повторите первый запрос очень часто и посмотрите, какие транзакции сохраняются.

Это начало происходить со мной, когда мой размер базы данных вырос и я делал много операций на нем.

правда, есть, вероятно, какой-то способ оптимизировать либо ваши запросы, либо вашу БД, но попробуйте эти 2 запроса для работы вокруг исправления.

выполнить это:

SET GLOBAL innodb_lock_wait_timeout = 5000; 

а потом этот:

SET innodb_lock_wait_timeout = 5000; 

проверьте состояние InnoDB для замков

SHOW ENGINE InnoDB STATUS;

Проверьте MySQL open tables

SHOW OPEN TABLES WHERE In_use > 0;

Проверьте отложенные транзакции InnoDB

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`; 

проверить зависимость блокировки - что блокирует что

SELECT * FROM `information_schema`.`innodb_locks`;

после изучения результатов выше, вы должны быть в состоянии увидеть, что блокирует то, что.

основная причина проблемы может быть в вашем коде тоже-пожалуйста, проверьте связанные функции, особенно для аннотаций, если вы используете JPA, как Hibernate.

например, как описано здесь, неправильное использование следующей аннотации может привести к блокировкам в базе данных:

@Transactional(propagation = Propagation.REQUIRES_NEW) 

перезагрузите MySQL, он отлично работает.

но будьте осторожны, что если такой запрос застрял, есть проблема где-то:

  • в вашем запросе (неуместный символ, декартово произведение, ...)
  • очень много записей для редактирования
  • сложные соединения или тесты (MD5, подстроки,LIKE %...% и т. д.)
  • проблема структуры данных
  • модель внешнего ключа (блокировка цепи/петли)
  • misindexed данные

как сказал @ syedrakib, это работает, но это не долговечное решение для производства.

осторожно: выполнение перезапуска может повлиять на ваши данные с несогласованным состоянием.

кроме того, вы можете проверить, как MySQL обрабатывает ваш запрос с ключевым словом EXPLAIN и посмотреть, возможно ли что-то ускорить запрос (индексы, сложные тесты,...).

когда вы устанавливаете соединение для транзакции, вы получаете блокировку перед выполнением транзакции. Если не удается приобрести замок, то вы пытаетесь на некоторое время. Если блокировка по-прежнему недоступна, то ошибка ожидания блокировки превышена. Почему вы не сможете получить блокировку, так это то, что вы не закрываете соединение. Таким образом, когда вы пытаетесь получить блокировку во второй раз, вы не сможете получить блокировку, поскольку ваше предыдущее соединение все еще открыто и удерживает блокировку.

решение: закройте соединение или setAutoCommit (true) [в соответствии с вашим дизайном], чтобы освободить блокировку.

Goto процессы в mysql.

Так что можете видеть, что задача все еще работает.

убейте конкретный процесс или дождитесь завершения процесса.

У меня была эта проблема при попытке удалить определенную группу записей (используя MS Access 2007 с подключением ODBC к MySQL на веб-сервере). Обычно я удаляю определенные записи из MySQL, а затем заменяю их обновленными записями (каскадное удаление нескольких связанных записей, это упрощает удаление всех связанных записей для удаления одной записи).

Я попытался выполнить операции, доступные в phpMyAdmin для таблицы (оптимизация, флеш и т. д.), Но у меня возникла необходимость разрешение на перезагрузку ошибка, когда я пытался сбросить. Поскольку моя база данных находится на веб-сервере, я не смог перезапустить базу данных. Восстановление из резервной копии не было.

Я попытался запустить запрос на удаление для этой группы записей в cPanel mySQL access в интернете. Получил такое же сообщение об ошибке.

мое решение: я использовал бесплатный браузер запросов MySQL Sun (Oracle) (который я ранее установил на своем компьютере) и запустил там запрос на удаление. Это сработало сразу, проблема решена. Я затем удалось еще раз выполнить функцию с помощью скрипта доступа, используя соединение ODBC Access to MySQL.

Я столкнулся с той же проблемой с "обновлением"-заявление. Мое решение было просто запустить через операции, доступные в phpmyadmin в таблице. Я оптимизировал, смыл и дефрагментировал таблицу (не в том порядке). Не нужно сбрасывать таблицу и восстанавливать ее из резервной копии для меня. :)

У меня была та же проблема. Я думаю, что это была тупиковая проблема с SQL. Вы можете просто принудительно закрыть процесс SQL из Диспетчера задач. Если это не исправить, просто перезагрузите компьютер. Вам не нужно удалять таблицу и перезагружать данные.

исправил, Убедитесь, что в запросе нет несоответствующего типа данных insert. У меня была проблема, когда я пытался "данные агента браузера пользователя" в "VARCHAR(255)" и имел проблему с этой блокировкой, однако, когда я изменил ее на "TEXT(255)", он исправил ее. Так что скорее всего это неправильное совпадение типа данных

Я решил проблему, сбросив таблицу и восстановив ее из резервной копии.

Comments

    Ничего не найдено.