4

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)

現在、同じデータベースへの 2 つの 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 エラーをスローします。ロック待機タイムアウトが超過しました。トランザクションを再開してみてください。

スレッドAがその行に「X」ロックを設定したため、スレッドAがロックを解放するまでスレッドBは「X」ロックを取得できないため、これは理にかなっています。

さて、私の質問は次のとおりです。スレッド B の観点から、MySQL がエラー 1205 を返したときに、どのスレッド/接続が私の要求をブロックするか (テーブル 'SeqNum' の 'UPDATE' 権限を取得するため) をどのように知ることができますか? X ロックを取得した後、threadA が何もしていない場合、スレッド B で「show processlist」を実行すると、「Sleep」ステータスの複数のスレッド (データベースに 2 つ以上のスレッドが接続されていると仮定します) しかありません。リクエストをブロックしたスレッドを特定できませんか?

うまくいけば、私は質問を明確に説明しました。ありがとう!

4

4 に答える 4

7

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 プラグインをインストールする必要があるのはあなただけです。

于 2011-07-18T12:08:34.830 に答える
4

新しい(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)という列が必要です。これがSHOWPROCESSLISTのIDです。

(innodb_locksの名前が間違っていることに注意してください。これは、ロックではなく、ロック待機に対してのみ入力されます)。

于 2010-10-27T19:40:51.630 に答える
2

この段階では、クエリ「SHOW ENGINE INNODB STATUS\G」で問題を解決できると思います。MySQL マニュアルからの情報は次のとおりです。 http://dev.mysql.com/doc/refman/5.0/en/innodb-monitors.html#innodb-standard-monitor

このクエリをスレッド B で実行すると、「トランザクション」セクションでリクエストをブロックしたスレッドが取得されます

于 2010-11-26T19:13:58.837 に答える
0

両方のセッションでトランザクションを行っていますか、つまり、入力しましたか

START TRANSACTION

通常、動作は希望どおりです。つまりFOR UPDATE、ロックが使用可能になるまでブロックします (最初のトランザクションによるCOMMITROLLBACK、最初のトランザクションから)。

于 2010-10-21T19:56:55.543 に答える