2

InnoDB の更新は行ロックであり、MyISAM の更新はテーブルロックであることは誰もが知っていますが、これをどのように説明しますか? 問題が発生している最中の SHOW FULL PROCESSLIST の結果を次に示します。

╔═════════╦════════╦═════════╦════════════════════════════════╗
║ Command ║ Time   ║ State   ║ Info                           ║
╠═════════╬════════╬═════════╬════════════════════════════════╣
║ Query   ║ 0      ║ NULL    ║ SHOW FULL PROCESSLIST          ║
║ Query   ║ 121    ║ end     ║ UPDATE [InnoDB table]          ║
║ Query   ║ 121    ║ update  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 121    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 120    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
║ Query   ║ 120    ║ Locked  ║ INSERT INTO [MyISAM table]     ║
╚═════════╩════════╩═════════╩════════════════════════════════╝

スペースを節約するために、いくつかの列を省略しました。上記はすべて 1 つのデータベースで発生し、単一の InnoDB テーブルと単一の MyISAM テーブルを参照します。この下には、下の 3 つと同様の行が他にもたくさんありましたが、ここでも除外しました。

問題は、MyISAM テーブルをロックしているように見える InnoDB テーブルの UPDATE によって開始されます。毎秒何百もの SELECT クエリが発生し、スタックしていないため、データベース全体はロックされていません。最初の INSERT の状態は「更新」であることに注意してください。これはおそらく、その後の挿入がロックされる原因となっていると思われます。自動インクリメント?テーブルのインデックス? おそらく。しかし、なぜそのような更新が別のテーブルの UPDATE によってブロックされるのでしょうか? 状態の意味の詳細については、こちらを参照してください。

http://dev.mysql.com/doc/refman/5.1/en/general-thread-states.html

これが私がこれまでに理解したものです:

  • クエリに問題はありません。UPDATE は適切にインデックス化されており、INSERT クエリと UPDATE クエリの実行には通常 100 ミリ秒未満かかりますが、ご覧のとおり、これは 2 分以上かかっています。
  • データベースで実行されるほとんどすべてのクエリは SELECT と INSERT です。UPDATE は例外です。
  • 問題を引き起こすのは間違いなくUPDATEであり、半複製可能です-同様のクエリを実行すると、問題が再現される場合があり、通常どおり迅速に実行される場合があります。
  • データベース内の他の InnoDB テーブルが問題なく更新されるという点で、問題があると思われるのはこの特定の InnoDB テーブルだけですが、それは最大であり、〜 100 万行を含み、サイズは〜 40 MB です。
  • UPDATE は複数のサーバーに複製されますが、長い実行時間は負荷が大きいサーバーでのみ発生するようです。
  • 問題が発生している間、サーバーの CPU 負荷と空き RAM を確認しましたが、どちらも問題ありません。

サーバー仕様:

  • Debian スクイーズ
  • MySQL 5.1
  • 8コア
  • 32GBのRAM

質問する前に、[mysqld] 構成設定の一部を次に示します。

skip-external-locking
innodb_file_per_table
innodb_flush_method     = O_DIRECT
innodb_buffer_pool_size = 512M
key_buffer              = 1500M
read_rnd_buffer_size    = 512k
table_open_cache        = 4096
tmp_table_size          = 256M
max_heap_table_size     = 256M
concurrent_insert       = 2
max_allowed_packet      = 16M
thread_stack            = 192K
thread_cache_size       = 8
max_connections         = 2000
open_files_limit        = 60000
query_cache_limit       = 1M
query_cache_size        = 512M

大規模なグーグル検索の後、私はまだ途方に暮れているので、どんな助けも感謝して受け取ります!

追加した

InnoDB テーブルの構文を作成します。

CREATE TABLE `tablename` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `column1` bigint(20) unsigned NOT NULL,
  `column2` int(10) unsigned NOT NULL,
  `column3` int(10) unsigned NOT NULL,
  `column4` int(10) unsigned NOT NULL,
  `column5` int(10) unsigned DEFAULT NULL,
  `column6` enum('yes','no') NOT NULL DEFAULT 'no',
  PRIMARY KEY (`id`),
  UNIQUE KEY (`column1`),
  KEY (`column2`),
  KEY (`column5`)
) ENGINE=InnoDB AUTO_INCREMENT=993266 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
4

1 に答える 1

0

あなたのステータスは「終了」状態にあるためです。こういったことが起こりえます

ドキュメントによると、最終状態では、次の操作が行われている可能性があります。

◾ テーブル内のデータが変更された後のクエリ キャッシュ エントリの削除

◾ バイナリログへのイベントの書き込み

◾ ブロブを含むメモリ バッファの解放

クエリ キャッシュを無効にするか、サイズを小さく設定することをお勧めします。これで、バッファー プール全体と同じ大きさになります。

于 2013-11-06T15:59:42.773 に答える