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




пример 5.5 (11)

Перейти к процессам в mysql.

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

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

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

update some_table set some_column = some_value

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

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

Lock wait timeout exceeded; try restarting transaction

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


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

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

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

KILL 1234;

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


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

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


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


Исправлено. Убедитесь, что в запросе нет вставки несогласованного типа данных. У меня возникла проблема, когда я пытался «данные агента пользователя браузера» в «VARCHAR (255)» и проблема с этой блокировкой, однако, когда я изменил ее на «ТЕКСТ (255)», она исправила ее. Поэтому, скорее всего, это неправильное соответствие типа данных


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

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

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

Мое решение: я использовал бесплатный MySQL MySQL Query Browser (который ранее был установлен на моем компьютере) и запускал там запрос на удаление. Это сработало сразу, проблема решена. Затем я смог снова выполнить функцию, используя скрипт Access, используя соединение ODBC Access to MySQL.


Проверить статус InnoDB для блокировок

SHOW ENGINE InnoDB STATUS;

Проверить открытые таблицы MySQL

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.

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

@Transactional(propagation = Propagation.REQUIRES_NEW) 

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

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

Запустите это:

SET GLOBAL innodb_lock_wait_timeout = 5000; 

И тогда это:

SET innodb_lock_wait_timeout = 5000; 

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

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

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

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

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

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


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


Это довольно уродливый ответ, и я чувствую себя виноватым, говоря это. Тем не менее, это может помочь вам с вашей проблемой.

Один из способов определить процентную долю - подсчитать все строки и подсчитать количество строк, превышающее указанное вами число. Вы можете рассчитать больше или меньше и принять обратное значение по мере необходимости.

Создайте индекс по вашему номеру. итого = выбрать количество ( ); less_equal = select count ( ) где value> indexed_number;

Процент будет выглядеть примерно так: less_equal / total или (total - less_equal) / total

Убедитесь, что они оба используют индекс, который вы создали. Если они не, настройте их, пока они не будут. Запрос объяснения должен иметь «использующий индекс» в правом столбце. В случае счетчика выбора (*) следует использовать индекс для InnoDB и что-то вроде const для MyISAM. MyISAM будет знать это значение в любое время без необходимости его расчета.

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

Это помогает?

Иаков





mysql transactions