Find out what is locking a MySQL InnoDB table-row - mysql

I use a database with an InnoDB-table. When I try to update a row, I get the "ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction" message, which I don't get on any other row (that I've tried).
How can I debug that?
SHOW PROCESSLIST;
is only yielding sleeping processes and because it's an InnoDB table, SHOW TABLE STATUS is basically useless (seems to work only for MyISAM tables).
SHOW ENGINE INNODB STATUS
also does not contain anything useful; the LATEST DETECTED DEADLOCK section contains two transactions from 3 days ago that no longer exist (thread IDs no longer appear in SHOW PROCESSLIST) and no longer seem relevant.
Is there any way to get to know what query caused the problem?
Also I would love to see the current locks on InnoDB tables, what is locking what right now - and not three days ago.

Have you checked the error log file of mysql? Maybe there is more detail to which transaction it is that failed.
To show all tables that are in use, simply execute this syntax
SHOW OPEN TABLES WHERE IN_Use=1

Related

ER_LOCK_DEADLOCK called when there is no lock

Logs showing that from time to time this error is raised.
I'm reading the docs and it's very confusing because we're not locking any tables to do inserts and we have no transactions beyond individual SQL calls.
So - might this be happening because we're running out of the mySQL connection pool in Node? (We've set it to something like 250 simultaneous connections).
I'm trying to figure out how to replicate this but having no luck.
Every query not run within an explicit transaction runs in an implicit transaction that immediately commits when the query finishes or rolls back if an error occurs... so, yes, you're using transactions.
Deadlocks occur when at least two queries are in the process of acquiring locks, and each of them holds row-level locks that they happened to acquire in such an order that they each now need another lock that the other one holds -- so, they're "deadlocked." An infinite wait condition exists between the running queries. The server notices this.
The error is not so much a fault as it is the server saying, "I see what you did, there... and, you're welcome, I cleaned it up for you because otherwise, you would have waited forever."
What you aren't seeing is that there are two guilty parties -- two different queries that caused the problem -- but only one of them is punished. The query that has accomplished the least amount of work (admittedly, this concept is nebulous) will be killed with the deadlock error, and the other query happily proceeds along its path, having no idea that it was the lucky survivor.
This is why the deadlock error message ends with "try restarting transaction" -- which, if you aren't explicitly using transacrions, just means "run your query again."
See https://dev.mysql.com/doc/refman/5.6/en/innodb-deadlocks.html and examine the output of SHOW ENGINE INNODB STATUS;, which will show you the other query -- the one that helped cause the deadlock but that was not killed -- as well as the one that was.

ERROR 1205 (HY000): Lock wait timeout exceeded on update mysql

I am running following update -
update table_x set name= 'xyz' where id = 121;
and getting -
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
I googled it number of times and adding extra time to innodb_lock_wait_timeout not helping me out.
Please let me know the root cause of this issue and how I can solve it.
I am using mysql 5.6(master-master replication) on dedicated server.
Also table_x(Innodb table) heavily used in database. Autocommit is on.
Find out what other statement is running at the same time as this UPDATE. It sounds as if it is running a long time and hanging onto the rows that this UPDATE needs. Meanwhile this statement is waiting.
One way to see it is to do SHOW FULL PROCESSLIST; while the UPDATE is hung.
(In my opinion, the default of 50 seconds for innodb_lock_wait_timeout is much to high. Raising the value only aggravates the situation.)
If you give up on fixing the 'root cause' of the conflict, then you might tackle the issue a different way.
Lower innodb_lock_wait_timeout to, say, 5.
Programmatically catch the error when it times out and restart the UPDATE.
Do likewise for all other transactions. Other queries may also be piling up; restarting some may "uncork" the problem.
SHOW VARIABLES LIKE 'tx_isolation'; -- There may be a better setting for it, especially if a long-running SELECT is the villain.
Looks like there is some lock on any of your other transaction. You can check the status of INNODB by using this:
SHOW ENGINE INNODB STATUS\G
Check if there is any lock on the tables like this:
show open tables where in_use>0;
And then kill that processes which are locked.
I have solved the problem. I tried different values for innodb_lock_wait_timeout, also tried to change queries but got the same error. I did some research and asked my colleagues about hibernate.
They were doing numbers of transaction which include updating main table and committing in the end. So, I suggested them to use commit on each transaction. Finally I am not getting any lock wait time out errors.

How do I avoid MySql deadlocks?

I'm talking to a MySql database using the jOOQ database abstraction layer.
I keep getting the following error:
SQL [null]; Deadlock found when trying to get lock; try restarting transaction
This is during a bulk insert of about 500 rows into a table. It is likely that more than one of these bulk inserts will be attempted at a time from different threads.
What is causing the deadlock, and how can I avoid it?
A traditional deadlock is when a transaction is trying to lock A and then B where another is trying to lock B and then A, leading to a situation where neither can complete. MySQL produces another sort of deadlock when there are too many pending locks on a particular resource.
You should check SHOW PROCESSLIST to see how many "waiting for lock" processes you have. It could be that the ones that fail are simply out of luck because there's too many in line.

When does InnoDB time out instead of reporting deadlock?

I have a "Lock wait timeout exceeded" error from MySQL that I can't reproduce or diagnose. I'm sure it's deadlock (as opposed to a transaction grabbing a lock then twiddling its thumbs), because my logs show that another process started at the same time, also hung, then continued when the first timed out. But normally, InnoDB detects deadlocks without timing out. So I am trying to understand why this deadlock was not detected.
Both transactions are using isolation level serializable. (I have a fair understanding of InnoDB locking in this isolation level.) There is one non-InnoDB (MyISAM) table used in the transaction, which I insert into and update. However, I don't understand how it could be involved in the deadlock, because I believe MyISAM just takes a table lock during the inserts and updates (then immediately releases it since MyISAM is not transactional), so no other lock is taken while this table lock is held.
So I'm convinced that the deadlock involves only InnoDB tables, which brings me back to the question of why it was not detected. The MySQL documentation (http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlock-detection.html) implies that deadlock detection pretty much always works. The problem cases I found while searching involve things like explicit "lock table", "alter table", and "insert delayed". I'm not doing any of these things, just inserts, updates, and selects (some of my selects are "for update").
I tried to reproduce by creating one MyISAM table and a couple InnoDB tables and doing various sequences of insert and update into MyISAM, and "select for update"s in InnoDB. But every time I produced a deadlock, InnoDB reported it immediately. I could not reproduce a timeout.
Any other tips for diagnosing this? I am using mysql 5.1.49.
One tip is that you can use SHOW INNODB STATUS to, you guessed it, show the status of the InnoDB engine.
The information it returns (a big hunk of text) includes info on current table locks, and the last detected deadlock (under the heading "LATEST DETECTED DEADLOCK"), so this trick isn't that useful well after the fact, but it can help you track down a hung query while it's happening.
mysqladmin debug can also print useful lock-debugging information.
A third trick is to create a magically-named table called innodb_lock_monitor as described at http://dev.mysql.com/doc/refman/5.1/en/innodb-monitors.html which gives more detailed lock debugging.
HTH!
UPDATE:
It may not be detecting a deadlock becuase it isn't actually a deadlock, but more likely that one process is waiting for a row lock on a row that is locked by another process. From the manual for the innodb_lock_wait_timeout variable:
The timeout in seconds an InnoDB
transaction may wait for a row lock
before giving up. The default value is
50 seconds. A transaction that tries
to access a row that is locked by
another InnoDB transaction will hang
for at most this many seconds before
issuing the following error:
ERROR 1205 (HY000): Lock wait timeout
exceeded; try restarting transaction
When a lock wait timeout occurs, the
current statement is not executed. The
current transaction is not rolled
back. (Until MySQL 5.0.13 InnoDB
rolled back the entire transaction if
a lock wait timeout happened.
A deadlock occurs, for example, when two processes each need to lock rows that are locked by the other process, and no amount of waiting will resolve the conflict.
I managed to reproduce and diagnose the problem. It is a deadlock involving MyISAM and InnoDB. It appears to be an interaction between transactional InnoDB row locking and non-transactional MyISAM table locking. I've filed a bug: http://bugs.mysql.com/bug.php?id=57118. At any rate, I believe the answer to my original question is, InnoDB should always detect deadlocks, unless there is a bug in MySQL. ;-)

Innodb Lock out causing whole database down

I have searched many threads and stackoverflow but I couldn't found any solution. I am trying to insert records into few innodb tables randomly rather one condition matches which cause whole database down. I am getting this error "Lock wait timeout exceeded; try restarting transaction"
One the question (#1103248) has been answered here
In InnoDB, an insert on an
auto-increment column results in a
table lock. Selecting a row FOR UPDATE
results in a row level lock.
All tables are just used for inserts none of them table performs updated at all. My question is how do I avoid these locks? Is there any solution available?
Here is the solution I found.
I installed the mysql 5.1
I have put following variable in my.cnf innodb_autoinc_lock_mode = 2
Restart mysql all should be set!
Thanks every one for your help.