If you're using Innodb and transactions with JDBC and your MySQL application, you should know about a couple of debugging features that made their way into MySQL Connector/J 5.1.15.
First, by adding "includeThreadNamesAsStatementComment=true" to your JDBC URL, you will get the current Java thread's name that is executing SQL on a given connection as a statement comment, visible in SHOW FULL PROCESSLIST output:
mysql> show full processlist; +------+------+-----------------+------+---------+------+----------+------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +------+------+-----------------+------+---------+------+----------+------------------------------------------------------+ ... | | 2939 | test | localhost:59339 | test | Query | 5 | Updating | /* java thread: main */ UPDATE t1 SET x=2 WHERE id=0 | .... +------+------+-----------------+------+---------+------+----------+------------------------------------------------------+
This is handy as it will also show up in the output of SHOW INNODB STATUS in the transaction list:
===================================== 110405 12:25:03 INNODB MONITOR OUTPUT ===================================== ... ------------ TRANSACTIONS ------------ Trx id counter D20A9 Purge done for trx's n:o < D20A3 undo n:o < 0 History list length 200 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 0, not started, OS thread id 4830089216 MySQL thread id 2940, query id 61108 localhost root show engine innodb status ---TRANSACTION D20A8, ACTIVE 20 sec, OS thread id 4829814784 fetching rows mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 376, 1 row lock(s) MySQL thread id 2939, query id 61106 localhost 127.0.0.1 root Updating /* java thread: main */ UPDATE t1 SET x=2 WHERE id=0 ^^^ Note the thread name here! ------- TRX HAS BEEN WAITING 20 SEC FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13798 page no 3 n bits 72 index `GEN_CLUST_INDEX` of table `test`.`t1` trx id D20A8 lock_mode X locks rec but not gap waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 5; compact format; info bits 0 0: len 6; hex 000000030a37; asc 7;; 1: len 6; hex 0000000d20a6; asc ;; 2: len 7; hex b9000002040084; asc ;; 3: len 4; hex 80000000; asc ;; 4: len 4; hex 80000000; asc ;; ------------------ ---TRANSACTION D20A7, ACTIVE 49 sec, OS thread id 4829147136 2 lock struct(s), heap size 376, 1 row lock(s) MySQL thread id 2938, query id 61103 localhost 127.0.0.1 root .... ---------------------------- END OF INNODB MONITOR OUTPUT ============================
In combination with a thread dump (sending "kill -QUIT" to your JVM process) this can really help debug those situations where you've built a app-thread-level deadlock into your application that isn't entirely visible in the database space.
If you're able to grant the PROCESS privilege to your JDBC user, you can also have Connector/J add the INNODB status output like above to your exception messages automatically by adding "includeInnodbStatusInDeadlockExceptions=true" to your JDBC URL.
To complete the loop, Connector/J 5.1.15 can also automatically dump the thread stack and state when the above is enabled by adding "includeThreadDumpInDeadlockExceptions=true" to your URL.
To get on your way to easier deadlock debugging with MySQL and JDBC, grab your own copy of MySQL Connector/J 5.1.15 at http://dev.mysql.com/downloads/connector/j/!