繁体   English   中英

MySQL InnoDB锁定问题

[英]MySQL InnoDB lock question

我有一个关于MySQL InnoDB的问题。 例如:我创建了下表:

   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)

现在,我有两个mysql连接到同一个数据库,我将它们命名为线程A和B.在线程A中,我有以下SQL语句:

    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)

然后,我只是按原样离开线程A.

在线程B中,我想做同样的查询:

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

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

锁定等待超时后,线程B将抛出一个MySQL 1205错误:超过锁定等待超时; 尝试重新启动事务。

这是有道理的,因为threadA在该行上放置了一个'X'锁,因此线程B无法获得'X'锁,直到线程A释放锁。

现在,我的问题是:从线程B的角度来看,当MySQL向我返回错误1205时,我怎么能知道哪个线程/连接阻塞了我的请求(获取表'SeqNum'的'UPDATE'特权)? 如果threadA在获得X锁之后什么都不做,并且我在线程B中运行'show processlist',那么我只有:几个具有'Sleep'状态的线程(我假设有两个以上的线程连接到数据库),我无法确定哪个线程阻止了我的请求?

希望我能清楚地解释这个问题。 谢谢!

InnoDB插件将为您提供锁定和锁定查询的清晰图片。

例如

SELECT r.trx_id waiting_trx_id,  r.trx_mysql_thread_id waiting_thread,
      r.trx_query waiting_query,
      b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread,
      b.trx_query blocking_query
FROM       information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b  ON  b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r  ON  r.trx_id = w.requesting_trx_id;

会给你一个锁定和阻止交易。 只有你必须安装innodb插件。

您只能轻松判断是否使用了较新的(InnoDB插件)版本。 information_schema中有一些表可以查询:

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

在innodb_trx表中应该有一个名为'trx_mysql_thread_id'的列(或类似的 - 它在MySQL 5.5中是trx_mysql_thread_id)。 这是SHOW PROCESSLIST中的id。

(请注意,innodb_locks名称错误。它只会填充锁定等待,而不是锁定)。

我认为在这个阶段,查询“SHOW ENGINE INNODB STATUS \\ G”可以解决我的问题。 以下是MySQL手册中的信息: http//dev.mysql.com/doc/refman/5.0/en/innodb-monitors.html#innodb-standard-monitor

在线程B中运行此查询,您将获得在“事务”部分中阻止您的请求的线程

您是否在两个会话中进行交易,即您是否已键入

START TRANSACTION

通常情况下,行为将如您所愿,即FOR UPDATE将阻塞直到锁可用(由于第一个事务的COMMITROLLBACK

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM