Deadlock vs Lockwait Timeout on MySQL [closed] - mysql

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 9 years ago.
Improve this question
Can anyone explain me on details the difference of Deadlock and Lockwait errors found on MySQL 5.1. Is it just the same? When does the deadlock error occur and when does the lockwait timeout occur?

A deadlock occurs whenever a circular dependency arises among the locks that transactions must acquire in order to proceed: for example, imagine that transaction 1 holds lock A but needs to acquire lock B to proceed; and transaction 2 holds lock B but needs to acquire lock A to proceed—the transactions are immediately deadlocked (no timeout required) and neither can proceed until one releases its locks. Thus the database picks a transaction to abort/rollback; application code should detect this eventuality and handle accordingly, usually by attempting the transaction again. A deadlock is analogous to a policeman solving gridlock (the situation at a road junction when no vehicle is able to move forward) by ordering a random participant to reverse.
A wait timeout occurs when the configured timeout period (e.g. innodb_lock_wait_timeout
in the case of InnoDB locks) elapses while a transaction awaits a lock, perhaps because a slow transaction is holding the lock and has not finished executing or perhaps because a number of transactions are queuing for the lock. It's possible (even, likely) that the lock would have become available and have been acquired if the transaction had waited longer, but the timeout exists to avoid applications waiting on the database indefinitely. A wait timeout is analogous to a driver giving up and turning back because of delays.

Deadlock is two threads infinitely waiting on the same thing. Lock wait timeout means one thread timed out while waiting to get a lock, thus preventing a deadlock.

Related

Default Concurrency Control Implementation in MySQL

What is the default implementation of concurrency control in MySQL? Is it optimistic locking (multi version concurrency control), or pessimistic locking (2 phase locking)? More specifically, how does InnoDb do it?
Internally, how does mysql (with innodb) decide on the start of a transaction whether to lock the row, or rollback after a conflict?
InnoDB uses optimistic locking.
There is no locking at the start of a transaction. How would it know which rows to lock until you execute a specific query? It doesn't even know which table(s) that you will eventually need to lock rows in.
There is no need for a rollback after a lock conflict. If you do a query in one transaction that has to wait because another session holds the lock, then your query waits up to a certain number of seconds (per the config option innodb_lock_wait_timeout, default 50 seconds).
If the other session commits before the timeout, then your session stops waiting, acquires the locks it needs, and proceeds with the query.
If your wait times out before the other session commits, your query returns an error. This still does NOT rollback your transaction; previous changes you made during your transaction are still able to be committed. You can even try the query that timed out again.
Exception: in cases of deadlock, InnoDB chooses one of the transactions involved in the deadlock, and forcibly does a rollback on one of them. It tries to choose the transaction that has modified fewer rows. If the transactions are tied, then the choice is arbitrary.

how to release a lock automatically in mysql

My question is similar to this questionMySQL rollback on transaction with lost/disconnected connection ,but it was 5 years ago.
If a client(like jdbc or something else) lock one row in table, execute some statements then network is down, so mysql would never receive commit or rollback command from client, does mysql support to rollback this transaction(unlock row) automatically?
I refer innodb_rollback_on_timeout it says If --innodb_rollback_on_timeout is specified, a transaction timeout causes InnoDB to abort and roll back the entire transaction, but how long is the transaction timeout and where to set it?
The accepted answer in similar question is to use wait_timeout, if wait_timeout is set to a small number like 10 seconds, so the idle connections in pool(if used) need to test connection every 10 seconds before they are disconnected by mysql sever, is the cost too high? or is there other ways(configuration will be best) to solve my question?
Actually there's no settings for transaction timeout, still wait_timeout or interactive_timeout applies. What --innodb_rollback_on_timeout affected is the behavior of rollback(whole transaction or statements in the transation).

Physical lock on DB rows obtained from a JPA PESSIMISTIC lock

According to the JPA 2.1 specification...
The lock modes PESSIMISTIC_READ, PESSIMISTIC_WRITE, and
PESSIMISTIC_FORCE_INCREMENT are used to immediately obtain long-term
database locks.
I assume a pessimistic lock will always trigger a SELECT ... FOR UPDATE SQL on the database, no matter what lock-mode is used. Now three questions on that:
Is the assumption correct or are there exceptions from this rule, if correct?
Given a SELECT ... FOR UPDATE locked the rows. Locked rows cannot be updated by any other transaction except the transaction which locked it?
The lock can be released by performing a commit or rollback on the transaction. What happens with the lock if the application (and the transaction which locked the rows) suddenly terminates without doing a commit or a rollback on the transaction?
For the question 1 and 2, your assumptions are correct:
Yes - pessimistic lock generally uses SELECT ... FOR UPDATE, as most databases and JPA implementations only support this type of lock. In this case there is no difference between READ and WRITE block, and JPA specification allows it as long as both behave as WRITE locks.
Yes - locked rows cannot be modified by any other transaction. In case of WRITE lock (and most time also for READ lock - se answer for 1), locked rows cannot be read also until the lock is released. Note that other unlocked rows in the same table are free to be read and modified.
To answer also question 3:
Yes - locks are release in case of commit or rollback. However, rollback also happens automatically when an error happens, or connection is dropped, or transaction takes too long. So, when the application dies, rollback is triggered immediately. If not, it is rolled back after some timeout (usually 5 minutes).

Mysql deadlock : what does 'try restarting transaction' mean and what exactly happens to the locked transactions [duplicate]

This question already has answers here:
Restarting transaction in MySQL after deadlock
(4 answers)
Closed 8 years ago.
I have a situation where 2 transactions create a mysql deadlock.
The following error is fired : Deadlock found when trying to get lock; try restarting transaction
If I'm correct, this error means that mysql deadlock timeout is expired, and mysql try to do something to removes this deadlock.
What isn't clear for me is what means try restarting transaction ? How a transaction can be "restarted" ?
What happens to the 2 locked transactions ? Are they both canceled (roll-backed) ? Or is it just one of them that is canceled so the lock can be released.
Thanks in advance
There is no deadlock timeout (though there are lock timeouts). If a deadlock is detected, no amount of time will resolve it, so MySQL reacts immediately.
MySQL will roll back one or more transactions until the deadlock is resolved.
From MySQL docs:
InnoDB tries to pick small transactions to roll back, where the size
of a transaction is determined by the number of rows inserted,
updated, or deleted.
It is up to your application that is making the SQL call to retry the transaction.
MySQL has some recommendations in its documentation How to Cope with Deadlocks.
If you wish to try to avoid the deadlock and are having trouble understanding the cause of the deadlock, I recommend starting another question, and posting the complete affected queries and schema, and ideally the deadlock report from SHOW ENGINE INNODB STATUS.

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. ;-)