テーブルレベルのロックエラーの原因は何ですか?


8

データベースはすでに2回停止していて、原因を探そうとしました。

show processlist
Waiting for global read lock | INSERT INTO {myisam_table} ...

ここではディスク領域がいっぱいだったので、それをもう少し与えると問題は終わったと思いましたが、翌日の正午に再びハングしました。

show processlist
Waiting for table level lock | UPDATE {myisam_table} ... 

何が原因ですか?

Mysqlデフォルトエンジン:InnoDB。

データベースには、MyISAMエンジンとInnoDBエンジンの両方を備えたテーブルが混在しています。

ここに投稿されたログ:

http://arturito.net/2013/08/28/mysql-waiting-for-table-level-lock-errors/


一度にディスク領域の問題が発生したと言ったり、これらは2種類のロックであるため、2つのイベントは関係がない可能性があります。両方の原因となった可能性の1つは、を使用したバックアップmysqldumpです。その時にバックアップを実行していましたか?
マイケル-sqlbot 2013

すべてのバックアップは午前7時に終了し、勤務時間中に実行されることはありません。昼食時にデータベースが動かなくなった。
ArturKędzior2013

MyISAMテーブルが1つのDBセッションでロックされている場合、それをロックした別のDBセッションが必要です。次回これが発生したときに、完全なプロセスリストを表示してください。
RolandoMySQLDBA 2013


@Arturito SHOW FULL PROCESSLISTでは、SHOW PROCESSLIST各スレッドのクエリ全体を表示できるようにするためではなく、おそらく必要です...しかし、現状ではMyISAM、関係するテーブルがある場合SELECT、42686で長時間実行されているクエリが43506でUPDATEクエリをブロックしているようですは、その後にSELECT続くすべてのクエリをブロックします。
マイケル-sqlbot 2013

回答:


8

最初の観測

  • プロセスID 42686は、SELECTクエリを実行する準備をしています
  • いくつかのスリープ接続があります
  • 他のすべてのプロセスはテーブルロックを取得できません
  • ロックを実行するには、UPDATE、DELETE、またはINSERTが必要でした。問題のテーブルの所有権を主張することはありません。
  • プロセスID 42686での完全なクエリを参照してください、私はそれが必要と疑うことができないJOINGROUP BYまたはORDER BY

作業理論

あなたが私に与えたプロセスリストでディスクスペースが足りなくなった場合、MyISAMストレージエンジンのせいにすることができます。どうして?

特定のケースでは、それはテーブルの1つではありません。場合JOINGROUP BYまたはORDER BY(ディスクの一時テーブルにMyISAMストレージエンジンを使用して)実行されたと一時テーブルがディスクに書き込まれたMySQLは単にスペースの場合アウトフリーズ。どうやってそれを知るのですか?

MySQL 5.0認定調査ガイドによると

ここに画像の説明を入力してください ページ408,409セクション29.2 Bulletpoint 11によると、

MyISAMテーブルに行を追加しているときにディスク領域が不足しても、エラーは発生しません。サーバーは、スペースが使用可能になるまで操作を中断し、操作を完了します。

私は以前この状況について話しました

あなたはこれら2つの状況の1つを持っていると何かが教えてくれます

  • SELECTのディスクベースの一時テーブルと、通常のデータとのスペースの競合
  • 一時テーブルが/tmpルートパーティションに配置されている場合、スペースが不足しています

提案

提案#1:tmpdirを別のディスクにマップする

[mysqld]
tmpdir = /another/disk/besides/root/partition

提案#2:RAMディスクを作成する

このコードを実行して、Linuxの再起動時に使用できるRAMディスクをインストールします。

RAMDISK_SIZE=32g
service mysql stop
mkdir /var/tmpfs
echo "none   /var/tmpfs  tmpfs  defaults,size=${RAMDISK_SIZE} 1 2" >> /etc/fstab
mount -t tmpfs -o size=${RAMDISK_SIZE} none /var/tmpfs
cp -R /var/lib/mysql/* /var/tmpfs
mv /var/lib/mysql /var/lib/mysql_old
ln -s /var/tmpfs /var/lib/mysql
chown -R mysql:mysql /var/tmpfs
chown -R mysql:mysql /var/lib/mysql
service mysql start

次に、tmpdir/var/tmpfs

試してみる !!!


RAMディスクに関するすばらしいアドバイス-速度が大幅に向上し、そのためには多くのメモリが必要です-SSDを作成するようなものです。
Up_One 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.