可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I\'m running the following MySQL UPDATE
statement:
mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
I\'m not using a transaction, so why would I be getting this error? I even tried restarting my MySQL server and it didn\'t help.
The table has 406,733 rows.
回答1:
You are using a transaction; autocommit does not disable transactions, it just makes them automatically commit at the end of the statement.
What is happening is, some other thread is holding a record lock on some record (you\'re updating every record in the table!) for too long, and your thread is being timed out.
You can see more details of the event by issuing a
SHOW ENGINE INNODB STATUS
after the event (in sql
editor). Ideally do this on a quiet test-machine.
回答2:
HOW TO FORCE UNLOCK for locked tables in MySQL:
Breaking locks like this may cause atomicity in the database to not be enforced on the sql statements that caused the lock.
This is hackish, and the proper solution is to fix your application that caused the locks. However, when dollars are on the line, a swift kick will get things moving again.
1) Enter MySQL
mysql -u your_user -p
2) Let\'s see the list of locked tables
mysql> show open tables where in_use>0;
3) Let\'s see the list of the current processes, one of them is locking your table(s)
mysql> show processlist;
4) Kill one of these processes
mysql> kill <put_process_id_here>;
回答3:
mysql> set innodb_lock_wait_timeout=100
Query OK, 0 rows affected (0.02 sec)
mysql> show variables like \'innodb_lock_wait_timeout\';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100 |
+--------------------------+-------+
Now trigger the lock again. You have 100 seconds time to issue a SHOW ENGINE INNODB STATUS\\G
to the database and see which other transaction is locking yours.
回答4:
Take a look on if your database is fine tuned. Especially the transactions isolation. Isn\'t good idea to increase the innodb_lock_wait_timeout variable.
Check your database transaction isolation level in the mysql cli:
mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation;
+-----------------------+-----------------+------------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation |
+-----------------------+-----------------+------------------------+
| REPEATABLE-READ | REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+------------------------+
1 row in set (0.00 sec)
You could get improvements changing de isolation level, use the oracle like READ COMMITTED instead REPEATABLE READ (InnoDB Defaults)
mysql> SET tx_isolation = \'READ-COMMITTED\';
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL tx_isolation = \'READ-COMMITTED\';
Query OK, 0 rows affected (0.00 sec)
mysql>
Also try use SELECT FOR UPDATE only in if necesary.
回答5:
100% with what MarkR said. autocommit makes each statement a one statement transaction.
SHOW ENGINE INNODB STATUS
should give you some clues as to the deadlock reason. Have a good look at your slow query log too to see what else is querying the table and try to remove anything that\'s doing a full tablescan. Row level locking works well but not when you\'re trying to lock all of the rows!
回答6:
None of the suggested solutions worked for me but this did.
Something is blocking the execution of the query. Most likely another query updating, inserting or deleting from one of the tables in your query. You have to find out what that is:
SHOW PROCESSLIST;
Once you locate the blocking process, find it\'s id
and run :
KILL {id};
Re-run your initial query.
回答7:
Can you update any other record within this table, or is this table heavily used? What I am thinking is that while it is attempting to acquire a lock that it needs to update this record the timeout that was set has timed out. You may be able to increase the time which may help.
回答8:
The number of rows is not huge... Create an index on account_import_id if its not the primary key.
CREATE INDEX idx_customer_account_import_id ON customer (account_import_id);
回答9:
Make sure the database tables are using InnoDB storage engine and READ-COMMITTED transaction isolation level.
You can check it by SELECT @@GLOBAL.tx_isolation, @@tx_isolation; on mysql console.
If it is not set to be READ-COMMITTED then you must set it. Make sure before setting it that you have SUPER privileges in mysql.
You can take help from http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html.
By setting this I think your problem will be get solved.
You might also want to check you aren\'t attempting to update this in two processes at once. Users ( @tala ) have encountered similar error messages in this context, maybe double-check that...
回答10:
Late to the party (as usual) however my issue was the fact that I wrote some bad SQL (being a novice) and several processes had a lock on the record(s) <-- not sure the appropriate verbiage. I ended up having to just: SHOW PROCESSLIST
and then kill the IDs using KILL <id>
回答11:
This kind of thing happened to me when I was using php
language construct exit; in middle of transaction. Then this
transaction \"hangs\" and you need to kill mysql process (described above with processlist;)
回答12:
In my instance, I was running an abnormal query to fix data. If you lock the tables in your query, then you won\'t have to deal with the Lock timeout:
LOCK TABLES `customer` WRITE;
update customer set account_import_id = 1;
UNLOCK TABLES;
This is probably not a good idea for normal use.
For more info see: MySQL 8.0 Reference Manual
回答13:
Had this same error, even though I was only updating one table with one entry, but after restarting mysql, it was resolved.
回答14:
If you have nothing else running and its your own instance, I find it would be more efficient to just restart mysql