views:

44

answers:

2

Hi All:

I have a question about MySQL InnoDB. For example: I have the following table created:

   mysql>CREATE TABLE IF NOT EXISTS `SeqNum`
   (
     `id` varchar(10) NOT NULL,
     `seq_num` BIGINT(30) default 0,
      PRIMARY KEY(`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  Query OK, 0 rows affected (0.00 sec)

  mysql>INSERT IGNORE INTO `SeqNum` VALUES('current',0);
  Query OK, 1 rows affected (0.00 sec)

Now, I have two mysql connections to the same database, I name them as Thread A and B. In thread A, I have the following SQL statement:

    mysql> begin;
    Query OK, 0 rows affected (0.00 sec)

    mysql> select `seq_num` from SeqNum where `id`='current' FOR UPDATE;
       +---------+
       | seq_num |
       +---------+
       |       0 | 
       +---------+
       1 row in set (0.01 sec)

and then, I just leave the thread A as it is.

In thread B, I would like to do the same query:

   mysql> begin;
   Query OK, 0 rows affected (0.00 sec)

   mysql>SELECT `current_seq_num` FROM SeqNum WHERE `id` = 'current' FOR UPDATE;

thread B will throw an MySQL 1205 Error after the lock waiting time out: Lock wait timeout exceeded; try restarting transaction.

It makes sense, because threadA put a 'X' lock on that row, so that thread B can NOT get the 'X' lock until thread A release the lock.

Now, my question is: from the perspective of thread B, how could I know which thread/connection block my request (to obtain the 'UPDATE' privilege for the table 'SeqNum') when MySQL return Error 1205 to me? If threadA is doing nothing after it obtains the X lock, and I run 'show processlist' in thread B, all I have are: several threads with 'Sleep' Status (I assume there are more than two threads connected to the datbase), I can NOT identify which thread blocked my request?

Hopefully, I explained the question clearly. Thanks!

A: 

Are you in a transaction on both sessions, i.e. have you typed

START TRANSACTION

Normally the behaviour would be as you desire, i.e. a FOR UPDATE would just block until the lock were available (due to COMMIT or ROLLBACK from the first transaction)

Adrian Smith
yes, both sessions are in a transaction. I just added the transaction statement in my question. My question is not why the 1st session blocked the 2nd session. But, from 2nd session point of view, how to know which session blocked its request? Of course, I assume there are more than two sessions.
WilliamLou
and I misread your question, I thought you were getting the timeout immediately, I'm sorry!
Adrian Smith
A: 

You can only easily tell if you use a newer (InnoDB Plugin) release. There are some tables in information_schema which you can query:

  • SELECT * FROM information_schema.innodb_trx;
  • SELECT * FROM information_schema.innodb_locks;

In the innodb_trx table there should be a column called 'trx_mysql_thread_id' (or similar - it is trx_mysql_thread_id in MySQL 5.5). That is the id in SHOW PROCESSLIST.

(Note that innodb_locks is misnamed. It will only be populated for lock-waits, not locks).

Morgan Tocker