Я запускаю следующую UPDATE
инструкцию MySQL :
mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Я не использую транзакцию, так почему я получаю эту ошибку? Я даже попытался перезапустить свой сервер MySQL, и это не помогло.
В таблице 406 733 строки.
mysql
sql
timeout
lock-timeout
Джейсон Светт
источник
источник
process
будут работать. Если это так, вы можете получить эту ошибку. Я прав?connection.commit()
коммитINSERT
илиUPDATE
вы только что пробежались.Как принудительно разблокировать заблокированные таблицы в MySQL:
Взлом подобных блокировок может привести к тому, что атомарность в базе данных не будет применена к операторам sql, вызвавшим блокировку.
Это хакерское решение, и правильное решение - исправить приложение, которое вызвало блокировки. Однако, когда доллары на линии, быстрый удар заставит вещи двигаться снова.
1) Войдите в MySQL
2) Давайте посмотрим список заблокированных таблиц
3) Давайте посмотрим список текущих процессов, один из них блокирует ваши таблицы
4) Убей один из этих процессов
источник
Теперь снова активируйте замок. У вас есть 100 секунд, чтобы выдать
SHOW ENGINE INNODB STATUS\G
базу данных и посмотреть, какая другая транзакция блокирует вашу.источник
lock_wait_timeout
значениеПосмотрите, хорошо ли настроена ваша база данных. Особенно изоляция транзакций. Не стоит увеличивать переменную innodb_lock_wait_timeout.
Проверьте уровень изоляции транзакции базы данных в mysql cli:
Вы можете получить улучшения, изменяя уровень изоляции, используя оракул, такой как READ COMMITTED, вместо REPEATABLE READ (InnoDB Defaults)
Также попробуйте использовать SELECT FOR UPDATE только в случае необходимости.
источник
tx_isolation
переменную вtransaction_isolation
.Ни одно из предложенных решений не сработало для меня, но это сработало.
Что-то блокирует выполнение запроса. Скорее всего, другой запрос обновляется, вставляется или удаляется из одной из таблиц вашего запроса. Вы должны выяснить, что это такое:
Как только вы обнаружите процесс блокировки, найдите его
id
и запустите:Повторите ваш начальный запрос.
источник
100% с тем, что сказал MarkR. autocommit делает каждый оператор транзакцией одного оператора.
SHOW ENGINE INNODB STATUS
должен дать вам некоторые подсказки относительно причины тупика. Внимательно посмотрите на свой медленный журнал запросов, чтобы увидеть, что еще запрашивает таблицу, и попытайтесь удалить все, что делает полный просмотр таблицы. Блокировка на уровне строк работает хорошо, но не тогда, когда вы пытаетесь заблокировать все строки!источник
Можете ли вы обновить любую другую запись в этой таблице, или эта таблица интенсивно используется? Я думаю о том, что, пока он пытается получить блокировку, ему нужно обновить эту запись, истек тайм-аут, который был установлен. Вы можете увеличить время, которое может помочь.
источник
innodb_lock_wait_timeout
вmy.cnf
Количество строк невелико ... Создайте индекс для account_import_id, если это не первичный ключ.
источник
Если вы только что убили большой запрос, это займет время
rollback
. Если вы выполните другой запрос до того, как завершенный откат будет завершен, вы можете получить ошибку тайм-аута блокировки. Вот что случилось со мной. Решение было просто немного подождать.Подробности:
Я выполнил запрос DELETE, чтобы удалить около 900 000 из примерно 1 миллиона строк.
Я запустил это по ошибке (удаляет только 10% строк):
DELETE FROM table WHERE MOD(id,10) = 0
Вместо этого (удаляет 90% строк):
DELETE FROM table WHERE MOD(id,10) != 0
Я хотел удалить 90% строк, а не 10%. Поэтому я убил процесс в командной строке MySQL, зная, что он откатит все строки, которые он удалил до сих пор.
Затем я сразу же выполнил правильную команду и
lock timeout exceeded
вскоре получил ошибку. Я понял, что на самом деле блокировка может бытьrollback
из-за убитого запроса, все еще происходящего в фоновом режиме. Поэтому я подождал несколько секунд и снова запустил запрос.источник
Убедитесь, что таблицы базы данных используют механизм хранения InnoDB и уровень изоляции транзакций READ-COMMITTED.
Вы можете проверить это SELECT @@ GLOBAL.tx_isolation, @@ tx_isolation; на консоли MySQL.
Если он не установлен как READ-COMMITTED, вы должны установить его. Перед установкой убедитесь, что у вас есть привилегии SUPER в mysql.
Вы можете воспользоваться помощью http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html .
Установив это, я думаю, что ваша проблема будет решена.
Вы также можете проверить, не пытаетесь ли вы обновить это сразу в двух процессах. Пользователи (@tala) сталкивались с подобными сообщениями об ошибках в этом контексте, возможно, еще раз проверьте, что ...
источник
Я пришел из Google, и я просто хотел добавить решение, которое работало для меня. Моя проблема заключалась в том, что я пытался удалить записи огромной таблицы, в которой было много FK в каскаде, поэтому я получил ту же ошибку, что и OP.
Я отключил,
autocommit
а затем он работал, просто добавляяCOMMIT
в конце предложения SQL. Насколько я понял, это освобождает буфер по битам вместо ожидания в конце команды.Чтобы соответствовать примеру OP, это должно сработать:
mysql> set autocommit=0;
mysql> update customer set account_import_id = 1; commit;
Не забудьте снова активировать,
autocommit
если вы хотите оставить конфигурацию MySQL, как и раньше.mysql> set autocommit=1;
источник
Поздно к вечеринке (как обычно), однако, моя проблема заключалась в том, что я написал какой-то плохой SQL (будучи новичком), и у нескольких процессов была блокировка записи (записей) <- не уверен в правильном словесном выражении. Мне пришлось просто:
SHOW PROCESSLIST
а затем убить идентификаторы с помощьюKILL <id>
источник
Подобные вещи случались со мной, когда я использовал выход из PHP-конструкции; в середине транзакции. Затем эта транзакция «зависает», и вам нужно убить процесс mysql (описанный выше с помощью processlist;)
источник
В моем случае я выполнял ненормальный запрос для исправления данных. Если вы заблокируете таблицы в своем запросе, вам не придется иметь дело с таймаутом блокировки:
Это, вероятно, не очень хорошая идея для нормального использования.
Для получения дополнительной информации см .: Справочное руководство по MySQL 8.0
источник
Я столкнулся с этим, имея 2 соединения Doctrine DBAL, одно из которых как нетранзакционные (для важных журналов), они предназначены для параллельной работы независимо друг от друга.
Мои тесты интеграции были свернуты в транзакции для отката данных после самого теста.
Мое решение состояло в том, чтобы отключить транзакцию обертывания в этих тестах и сбросить данные БД другим способом.
источник
Была такая же ошибка, хотя я обновлял только одну таблицу с одной записью, но после перезапуска mysql она была исправлена.
источник