Xaprb

Stay curious!

How I patched InnoDB to show locks held

with 5 comments

I’ve written before about how to figure out which connection is holding the InnoDB locks for which other connections are waiting. In other words, how to figure out who’s blocking you from getting work done when you get InnoDB lock timeouts or other InnoDB lock contention. The short and sweet: turn on the InnoDB lock monitor and use innotop to look at the locks held and waited-for.

The InnoDB lock monitor has a few major disadvantages, though:

  • It spews InnoDB status dumps into your log files
  • It prints tons of lock information you don’t want to see (it prints three lines of text for every row that’s locked, each of them in several formats just in case you need it!)
  • It can be so verbose that it crowds out the rest of the InnoDB status output, or even causes you not to see anything but a single lock

Basically, it’s written for the InnoDB developers, not for a MySQL DBA.

Fixing this requires changing the server and/or storage engine; there’s no configuration you can change. The easiest solution, in my view, is to a) turn off the verbose output b) print the locks held by default. Sure there are better ways, such as using INFORMATION_SCHEMA tables, but this is by far the lowest-hanging fruit.

By the way, I think the InnoDB developers are working on exporting some status to pluggable INFORMATION_SCHEMA tables in future releases.

Since MySQL is Free Software, I was able to patch InnoDB and MySQL the way I want them. The patch is attached to my feature request for fixing InnoDB lock output. It’s unlikely to be included in the MySQL server itself, but perhaps it’ll help someone else too.

With this patch, you get two new server variables, which you can set in either your my.cnf file, or dynamically via SET GLOBAL. By default, they are as follows:

mysql> show variables like 'innodb_show%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| innodb_show_locks_held    | 10    | 
| innodb_show_verbose_locks | 0     | 
+---------------------------+-------+

The first is the number of locks to print for each transaction. The second is whether to print the verbose record dumps for each lock. (My advice is to leave the second variable at 0).

Now when you run SHOW INNODB STATUS, you’ll see something like the following in the TRANSACTIONS section:

---TRANSACTION 0 268216580, ACTIVE 27 sec, process no 16382, OS thread id 2424191888
2 lock struct(s), heap size 320
MySQL thread id 8, query id 949 localhost 192.168.0.5 xaprb
TABLE LOCK table `test/t1` trx id 0 268216580 lock mode IX
RECORD LOCKS space id 0 page no 2670602 n bits 72 index `PRIMARY` of table `test/t1` trx id 0 268216580 lock_mode X locks rec but not gap

I caused that output by doing a SELECT FOR UPDATE query on an InnoDB table in a transaction.

If this were all I did, it would still be a big help in figuring out who’s blocking whom. But I also made innotop smarter to take advantage of the new output. Now it aggregates locks held and waited-for in L mode, so you can see very quickly “something is waiting for a lock on this table, and something else has a lock on the same table.” This works fine even when you haven’t applied my patch, but my patch lets you debug lock waits much more cleanly.

And as a bonus, it’ll prevent your SHOW INNODB STATUS from being completely overwritten when you have a big deadlock.

All in all, it’s been a huge relief to have this applied to the servers I manage. Sometimes InnoDB’s status output used to drive me nuts. I stopped complaining and did something about it!

Written by Baron Schwartz

December 21st, 2007 at 5:45 pm

Posted in Uncategorized

Tagged with , , , ,

5 Responses to 'How I patched InnoDB to show locks held'

Subscribe to comments with RSS

  1. This comment/request does not belong in this section but i couln’t trace your contacts so …..
    first off…thanks for the great set of tools they make MySQL more bearable!!!!
    My request – a tool that allows general and/or specific query logging on a per database and/or table basis
    That would definately help troubleshoot source of corrupted data in a table, etc

    Ben

    25 Dec 07 at 8:28 am

  2. ps. Merry Christmas and a prosperous new year!!!!

    Ben

    25 Dec 07 at 8:30 am

  3. Hi Ben,

    Thanks, and a merry Christmas to you as well!

    Xaprb

    25 Dec 07 at 10:19 am

  4. Just showing the process list and looking for the longest running process on a table can also give information as to what connection is holding the lock.

    Other then the cool show status variable that allows for easy graphing, what other information does this show? I’d like to get information as to why the table lock is established, and why it’s taking so long.

    Some suggestions that may answer these questions:

    What about showing the number of rows the lock needs to hold as an indicator to why the lock is across the entire table?

    A page to row conversion, to see which processes are trying to operate on the same page/row, which could be an indicator as to why a lock across the table is needed.

    This is some great work with a bunch of expandable information.

    Dathan Pattishall

    28 Dec 07 at 4:13 pm

  5. Dathan,

    Sometimes, yes, but row locks are held until the transaction commits, so of course even short-running statements can block things. In most of the cases I’ve needed to track down, it’s usually something like “update table1 join client… set table1.clientname=client.nickname” and then the client table’s rows are locked until the transaction commits. Take a poorly-behaved program that doesn’t commit for a while, add 99 other things running at the same time, and it’s basically impossible to figure out who really has the lock you need to kill and un-freeze the works.

    I’ve been spending some time in the InnoDB source trying to figure out if there’s a way to just see which transaction holds the lock, but I don’t know the code that well. (The locking code is pretty complicated). That would be my preferred solution.

    Xaprb

    29 Dec 07 at 7:28 pm

Leave a Reply