2011年 6月 6日 はてなブックマーク -
タグ: #MySQL #InnoDB

データ圧縮の手順

データ圧縮はテーブル単位に指定します。CREATE TABLEまたはALTER TABLE文で以下のように定義します。

CREATE TABLE `text` (
  `old_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `old_text` mediumblob NOT NULL,
  `old_flags` tinyblob NOT NULL,
  PRIMARY KEY (`old_id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8

ROW_FORMATにCOMPRESSEDを指定することで、Barracudaフォーマットの圧縮形式になります。InnoDB Pluginにおいて、ROW_FORMATは現在以下の四種類が指定できます。

  • REDUNDANT:MySQL 4.1までのフォーマットです。
  • COMPACT:MySQL 5.0以降のフォーマットです。UTF-8文字列の最適化などによって、REDUNDANTよりもデータサイズが小さくなっています。
  • DYNAMIC:InnoDB PluginのBarracudaフォーマットを用いますが、データ圧縮は行わない形式です。
  • COMPRESSED:InnoDB PluginのBarracudaフォーマットを用い、データ圧縮を行う形式です。

次のKEY_BLOCK_SIZEは、圧縮後におけるInnoDBのページサイズを指定するものです。デフォルトは8KBで、1、2、4、8、16KBから選ぶことができます。InnoDBはもともとページサイズが16KB固定になっていてこのページ単位にディスクI/Oなどのデータ管理を行っているのですが、Barracudaフォーマットの圧縮形式ではページサイズがテーブルごとに可変になっています。

MySQL InnoDB Pluginのデータ圧縮機能 - SH2の日記

入るデータサイズが小さいならKEY_BLOCK_SIZEをデフォルトの8KBから2KBにする事で、さらに圧縮効率が高まります。


11ヶ月前 | | 2011年 6月 6日 | このエントリーを含むはてなブックマーク
2011年 5月 24日 はてなブックマーク -
タグ: #Mysql #innodb

今回は、MySQL-5.0.45のInnoDBで連番を管理するテーブルのパフォーマンス測定をしていたのですが、その際に少し変わったデッドロック問題に遭遇しましたので、そのあたりをネタとして書いてみたいと思います。

まずは、今回使用したデータベースのスキーマは下記のようなものです。

CREATE TABLE num (
    id bigint unsigned NOT NULL default '0'
) Engine=InnoDB;

AUTO_INCREMENTは使用していません。
そこに1レコードだけ登録します。

INSERT INTO num (id) values (1);

そして実際連番を取得する際には、

UPDATE num SET id = LAST_INSERT_ID(id+1);

といったクエリを発行しインクリメントしていき、最新のidはSELECTするのではなくUPDATE時のMySQL応答パケットに含まれるmysql_insertidを参照します。

上記のような内容をベンチマークテストのために同時接続を増やしながらテストしていると、350を超えたあたりで

ERROR 1213 (40001): Deadlock found when trying to get lock

というエラーが発生するという事態に遭遇しました(350という具体的な数値はハードウェアの性能などで変動すると思います)。ちなみに試験環境のOSやMySQLのバージョンは簡単ですが下記のような感じです。

  • MySQL-5.0.45
  • Linux-2.6.22

まずはWebで検索してみる

筆者の英語力不足という説もありますが、なかなか「コレ!」というものが見つけられませんでした。

パラメータやSQL文等を色々試してみる

  • 1カラムしかないのが逆に良くないのかと思い、主キーカラムを追加しWhere句で指定 → 変化なし
  • autocommitなのが良くないのかと思い、start transaction(またはbegin)とcommitを発行する → 変化なし
  • トランザクション分離レベルをserializableに変えてみる → 変化なし
  • innodb_table_locksパラメータを0にしてみる → 変化なし

他にもいくつか試しました。また、それらを組み合わせてみたりもしましたが解決しません。なので、ソースを読んでみることにします。

mixi Engineers’ Blog » MySQLのInnoDBでのデッドロック

結論からいいますと、サーバーのハードのスペックにもよりますが、今回の検証用環境では多少の増加は出来ましたが、さらに負荷を上昇させていくとロック待ち時間が増加し、その結果innodb_lock_wait_timeoutに引っかかり始めました。じゃあinnodb_lock_wait_timeoutも増加させればいいじゃないか、と考えもしましたが、ただ実際にはそれによりパフォーマンスが向上するわけではなく、「90秒や120秒待てばデッドロック扱いもタイムアウト扱いもせずSQLが完了します」というのは、MySQL的にはエラーでなくとも実際のシステム的にはエラーも同然ですのであまり意味がないのではないかと判断しました。というわけで、現在mysqldを動作させる一般的なハードウェア上では200という数字はそれなりに適切な値なのではないかと思いました。

ちなみにMyISAMではこのような問題は起こらず、パフォーマンスも良好な結果でした。システムの要件にもよりますが、MyISAMに変更しても問題ない場合はそちらも検討されるのも良いかと思います。

デッドロックになるはずのないSQL文でデッドロックだとエラーメッセージが返却された場合にこのような例もあったなということを思い出していただけると幸いです。
————-

MySQL5.1や5.5を使えばこの問題は起きないという噂です


1年前 | | 2011年 5月 24日 | このエントリーを含むはてなブックマーク
2011年 1月 4日 はてなブックマーク -
タグ: #MySQL #InnoDB #MyISAM
copy to tmp table

まず、カラム追加時に最初に行なわれる一時テーブルへのコピーについて。これは、「ALTER TABLE」を実行すると確実に行なわれる動作のようです。また、実行中対象テーブルは読み取り可、書き込み不可の状態になります。

ALTER TABLE の処理では、元のテーブルの一時的なコピーが作成されます。 変更はこのコピーに対して実行されます。その後元のテーブルが削除され、新しいテーブルの名前が変更されます。この変更処理は、すべての更新が、エラーに なることなく、確実に新しいテーブルに自動でリダイレクトされるように実行されます。ALTER TABLE の実行中、元のテーブルは他のクライアントによって読み取り可能です。このテーブルの更新とテーブルへの書き込みは、新しいテーブルの準備が整うまで停止 されます。


repair with keycache

この動作は、「LOAD DATA INFILE」とかで大量のデータをinsert する処理を高速に行いたい場合に使われる手法と同じです。insert 毎にインデックスの更新を行なうと効率が悪いので、「ALTER TABLE … DISABLE KEYS」でインデックスの更新を行わないようにし、データを挿入。その後、「ALTER TABLE … ENABLE KEYS」でインデックスを再構築します。

ALTER TABLE を実行する場合はこの動作が自動で行なわれ、インデックス構築の処理を高速化するとあります。

MyISAM テーブルに対して ALTER TABLE を使用すると、非ユニークなインデックスのすべてが別のバッチに作成される(REPAIR の場合と同様)。 インデックスが数多くある場合は、これによって ALTER TABLE の処理がはるかに迅速化される。


ただ、この「repair with keycache」には問題があるようです。


repair with keycache ではなく、repair by sorting を使うようにする

インデックスの再構築処理には「repair with keycache」を使う方法と、「repair by sorting」を使う方法があるようです。

ALTER TABLE … ENABLE KEYSステートメントをMyISAMテーブルに対して実行する場合やインデックスの修復を行う際、MyISAMは以下の2通りのうちいずれかの方法によりインデックスの修復を試みる。

  • Repair by sorting
  • Repair with keycache

名前からすると後者の方が速そうだが、実は前者の方が遙かに速い。


Repair with keycache 修復コードが、キーキャッシュにより、キーを1つずつ作成している。これは、Repair by sorting よりも大幅に時間がかかる。


インデックスの再構築を行なっている時に、「repair with keycache」が使われるのはよくないようです。高速な「repair by filesort」を使うようにするには、パラメータの設定が必要。適切なパラメータが設定されていないと、MySQL の判断によって「repair with keycache」が使われるようです。

名前からすると後者(Repair with keycache )の方が速そうだが、実は前者(Repair by sorting)の方が遙かに速い。ただしこの手法を用いるにはソート用のバッファが確保されている必要があるのだが、これが実にやっかいである。バッ ファのサイズがとてつもなく大きいのだ。バッファはmyisam_max_sort_file_sizeにて指定するが、必要な分だけ確保するようになっ ているので100Gぐらいにしておいて差し支えないだろう。ファイルシステムがいっぱいになったり、ここに指定した値を超えてバッファが必要な場合には、 Repair with keycacheに自動的に切り替わる。

myisam_max_sort_file_sizeだけでなく、myisam_sort_buffer_sizeを増やしておくとメモリ上 でバッファリングが行われるので、Repair by sortingがさらに高速になる。REPAIR TABLEやLOAD DATAで非常に大きなテーブルを扱う場合、myisam_sort_buffer_sizeを増やしておくと良いだろう。


100G くらい割りあてるといいと書いてあるけど、パーティションとかの関係で/tmp にそんなに容量を割りあてていない場合結局「repair with keycache」が使われるので、「tmpdir」の値も変更してあげる必要があります。例えば、「/home」の容量に余裕があれば以下のような感 じ。

$ mkdir /home/luke/tmp

$ sudo /etc/init.d/mysql restart —myisam_max_sort_file_size=100G —tmpdir=/home/luke/tmp


これで、カラムやインデックスの追加を高速に行なうことができるようになります。

なお、「myisam_max_sort_file_size」や「myisam_sort_buffer_size」は今回のようなインデックスの作成時にしか使用されないバッファなので、通常は大きく割りあてておく必要はなさそうです。

大きめのテーブルにカラムやインデックスを追加する際の注意 - Slow Dance

mysqldumpしたデータが重たいのならば、そのsqlファイルの冒頭に
「SET GLOBAL xxxxx=100G; 」のような指定を行っても良いですね。


1年前 | | 2011年 1月 4日 | このエントリーを含むはてなブックマーク
2011年 1月 4日 はてなブックマーク -
タグ: #MySQL #InnoDB #MyISAM

先日大きめ(といっても500万行くらい)のテーブルにインデックス付きのカラムを追加しようとして痛い目にあったので調査。


大きめのテーブルにカラムやインデックスを追加するとどうなるか

今回は単純に、「ALTER TABLE 〜 」で追加しようとしました。追加するカラムは3つで、

  • varchar(255)
    • インデックスなし
  • varchar(255)
    • ↓のdate 型カラムとマルチカラムインデックスの形式のユニークインデックスあり
  • date
    • インデックスあり

SQL を実行し、状況を「SHOW PROCESSLIST」で監視していたら、1つ目のカラム追加で次のような状態に…

  • 最初にState が「copy to tmp table」状態になり、次の状態に遷移するまで1時間かかる
  • 次にState が「Repair with keycache」状態になり、完了までに1時間かかる
  • 次のカラム追加に対する「copy to tmp table」が開始される

もう超絶的に遅いです。まぁ、1時間とかは序の口のようで、7時間かかっても終わらないこともあるらしい

たかだか700万行、 mysqldump して 150MB 弱のデータ量しかないテーブルに一つユニークインデックスを貼るだけで7時間半かかってまだ終わらないってどういうことよ。この大きさになるともう ALTER TABLE では無理だってことか・・・。


ただ、今回の場合監視していて不思議だったのが、top でmysql の状態を見ると全然仕事をしていなかったことです。CPU 使用率も2%とかで、おい!って感じ。


解決策

結論から言うと、「key_buffer_size」の不足でした…。「repair with keycache」を実行する際にも、MyISAM のインデックスのキャッシュ機構が使われるわけで、このサイズが足りなかったわけです。

インデックスブロックには、key cache (あるいはkey buffer)という特別な構造が保持されています。その構造には最も頻繁に使用されるインデックスがおかれた多数のブロックバッファが含まれます。

キーキャッシュのサイズを制限するには、key_buffer_sizeシステム変数を使用します。


実際に追加している最中に確認したら驚きの少なさ!

mysql> show variables LIKE '%key_buffer%';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| key_buffer_size | 8384512   |
+-----------------+-----------+

なんとデフォルトのサイズ。MyISAM 使っていて、「key_buffer_size」の値を確認していないとはどこの小学生だよって感じです…( ゚Д゚)

というわけで、直ぐに変更。マシンのメモリが1G だったので1/4 の256M に設定。クエリ実行中だったのでSET 構文使う。

SET GLOBAL key_buffer_size=268435456; 	

これを設定したら、mysqld が仕事し始めました。CPU も7~9割使っているし、メモリも割りあてた分をフルに使っている模様。さっきまでは使用できるメモリが小さすぎてディスクを使っていたのでIO 待ちが長くCPU を有効に使えていなかったのだと思います。


結果、最初のカラム追加に2時間かかったのに対し、15分ほどで追加できるようになりました。これで、無事カラム追加を完了させることができました。


最後に、SET 構文で設定した値はmysqld を再起動すると無効になってしまうので設定ファイルで値を変更して完了。

大きめのテーブルにカラムやインデックスを追加する際の注意 - Slow Dance

1年前 | | 2011年 1月 4日 | このエントリーを含むはてなブックマーク
2011年 1月 4日 はてなブックマーク -
タグ: #MySQL #InnoDB #MyISAM

大量データのinsert

もう、mysql_dumpの中見てもらえれば良いと思うけど、

-- 以下みたいに書くより
insert into x ( ... );
insert into x ( ... );
insert into x ( ... );
insert into x ( ... );

-- この方が良いよ
insert into x values( ... ),( ... ),( ... ),( ... );
indexの再構築が遅い

一度に大量に突っ込むとindexの再構築が遅いです。

そんな一度に大量のデータ突っ込んだりとかするようなジャンクな使い方する場合には、MyISAM使ってると思うので*1、MyISAMの場合にはこうしましょう。

alter table x disable keys;
insert into x values( ... ),( ... ),( ... ),( ... );
insert into x values( ... ),( ... ),( ... ),( ... );
insert into x values( ... ),( ... ),( ... ),( ... );
-- ( 以下ry 多分100万回ループな感じで)
alter table x enable keys;

で、enable keys したタイミングで3日待たされたとかになっちゃう可能性が有ります。

id:ichii386 (いちい君) がここで言及してますが

http://d.hatena.ne.jp/ichii386/20070924/1190610994 

myisam_max_sort_file_size と言う項目を広げてやるとソートにかかるコストが減るので速くなります。

更新してなかった間にしてたこと | 404 motivation not found

以下2つを1Gとかにすると「alter table x enable keys;」の実行結果が半日かかってこないような状況でも、その半分以下で終わったりするようになります。
myisam_max_sort_file_size
myisam_sort_buffer_size


1年前 | | 2011年 1月 4日 | このエントリーを含むはてなブックマーク
2010年 10月 16日 はてなブックマーク -
タグ: #MySQL #InnoDB
InnoDBにはOPTIMIZE TABLEに相当する機能は実装されておらず、代わりにALTER TABLEが実行される。OPTIMIZE TABLE t1は次のコマンドを実行するのと同じなのである。
  1. mysql> ALTER TABLE t1 ENGINE INNODB;  
mysql> ALTER TABLE t1 ENGINE INNODB;
このコマンドを実行すると、テーブルのデータが詰め直される。データの挿入は主キーの順番で行われるため、OPTIMIZE TABLEすると
  • フラグメンテーションが解消する。
  • テーブルスキャンが高速になる。
という効果が期待できることになる。残念ながら、セカンダリインデックスをセカンダリインデックスの順番で詰め直す方法はない。そのため、セカンダリインデックスの空間効率はあまりよくない場合があるので注意が必要である。

OPTIMIZE TABLEが内部的にALTER TABLEと同じということは、別に悪いことばかりではない。モノホンのOPTIMIZE TABLEだと実行中は参照も更新もブロックしてしまうことになるが、ALTER TABLEであればメンテナンス中も参照は可能なのである。

漢(オトコ)のコンピュータ道: 大人のためのInnoDBテーブルとの正しい付き合い方。

1年前 | | 2010年 10月 16日 | このエントリーを含むはてなブックマーク
2010年 10月 11日 はてなブックマーク -
タグ: #MySQL #InnoDB

見えざるCovering Index

クラスタインデックスにおけるセカンダリインデックスは、悪いことばかりではない。そもそも検索がセカンダリインデックスだけで済むようにCovering Indexにすれば非常に高速だ。その辺の事情については、過去記事「InnoDBでCOUNT()を扱う際の注意事項あれこれ。」にも書いてあるので参照して頂きたい。

セカンダリインデックスには主キーの値が格納されていることは先程述べた通りである。それは、即ちセカンダリインデックスの定義には、最後のカラムとして主キーが必ず含まれているようなものである。例えば、次のテーブル定義は全く同一なのである。

漢(オトコ)のコンピュータ道: 知って得するInnoDBセカンダリインデックス活用術!

InnoDBとMyISAMでは内部的には異なるインデックスが貼られる事になるという話です。


1年前 | | 2010年 10月 11日 | このエントリーを含むはてなブックマーク
2010年 8月 3日 はてなブックマーク -
タグ: #Linux #MySQL #InnoDB

InnoDBのデータファイル肥大化の傾向と対策

余裕でメモリに収まるサイズのデータファイルが膨れ上がって全てのクエリが遅くなる現象を過去に二例ぐらい経験したのでメモ。file per tableを有効にしている状態でも起こる。1台はもうサーバーごとリプレースしてしまったけど。

http://dev.mysql.com/doc/refman/5.1/ja/innodb-multi-versioning.html

ユー ザがテーブル内で大体同じくらいの比率で小さめのバッチの行を挿入、削除するというようなシナリオでは、パージ スレッドが遅れをとり始め、そしてテーブルが大きくなり続け、全てがディスクに頼った状態になり操作がとても遅くなる可能性があります。テーブルがたった の10MB の有効データしか持っていないとしても、たくさんの 「停止した」 行が10GB を占めるほどにまで大きくなる事があります。

確認するにはinnotopでトランザクションのステータスを開く。

CXN            History  Versions  Undo  Dirty Buf  Used Bufs  Txns  MaxTxnTime  LStrcts
xxx.xxxxxxx        509      1959  0 0      19.46%     93.92%   201       00:02        0

これで表示されるHistoryとVersionsの数値が異常に多くなっていて減らない状態だとデータファイルのサイズが肥大化していってしまう。100万行のテーブルで1億とかになったりする。

ドキュメントに書いてある通り、innodb_max_purge_lagというパラメータを調整することで解消することが出来る。

innodb_max_purge_lagはドキュメント読むと説明がクソわかりづらいのだけど、

  • 削除マークが付いている古いレコードを何行まで許容するか
  • この数値をオーバーしたらupdateやdeleteに遅延を入れてpurge処理が追いつくように調整する

みたいな感じだと思う。問題の起きてるDBでは100000にした。通常はいじる必要がない。あまり小さい数字にするとupdateやdeleteが大幅に遅くなる。

innodb_max_purge_lag調整後はデータファイルサイズが肥大化する現象が起こらなくなった。一度肥大化したらoptimize tableかけないと戻らないと思う。

引用元

更新:2010/06/28 02:21

うずら技術メモ

1年前 | | 2010年 8月 3日 | このエントリーを含むはてなブックマーク
2010年 8月 3日 はてなブックマーク -
タグ: #Linux #MySQL #InnoDB

innotop

innotopを使えば、現在どんなSQLが実行されているかをリアルタイムで知ることができる。 ここでは簡単な使い方と応用編としてSQLサンプリング、および解析スクリプトを紹介する。

ダウンロードは以下のURLから行う。 innotopperlスクリプトなので、MySQLに接続するためのモジュール(DBIやDBD)を予めインストールしておくこと。

http://sourceforge.net/projects/innotop/

ダウンロードしたアーカイブを展開したら、以下の手順を実行する。デフォルトでは/usr/bin以下にインストールされる。

$ tar xvfz innotop-1.6.0.tar.gz 
$ cd innotop-1.6.0
$ perl Makefile.PL 
$ make 
$ make install

初回実行時のみ初期設定を行う。

まず接続名を入力する。適当な名前でよい。ここでは”dbt2”とする。

次にDSNを入力する。データベース名やホスト名など適宜入力すること。

DBI:mysql:database=dbt2:host=localhost:port=3306 

あとはユーザ名やパスワードを入力すると、ホームディレクトリ以下に~/.innotop/というサブディレクトリが作られ、 イニシャルファイルinnotop.iniが作成される。


バージョン4.1以下の場合はinnotop.iniを編集する。

global=0

これは、バージョン4.1以下のSHOW STATUS文やSHOW PROCESSLIST文ではGLOBALオプションが無効だからである。

innotopコマンドを起動すると、実行中のSQLのリストが周期的に表示される。 起動時に”-d”オプションサンプリング周期を指定できる。

$ innotop -d 1

SQLサンプリング

innotopMySQLの標準コマンドmysqldumpslowを組み合わせると、簡単にSQLサンプリング検査ができる。

まず、innotopを”-n”オプション(Non-interactiveモード)で起動し、 SQLサンプリング結果をファイル(ここでは/tmp/innotop.log)に書き込む。

次の例では、0.5秒間隔で3600回、およそ30分にわたってサンプリングしている。 DB本体の負荷にならない程度のサンプリング間隔で、なるべく長期間データをとるとよいだろう。 Ctl-Cを打ち込めば途中で終了する。

$ innotop -d 0.5 --count 3600 -n | tee /tmp/innotop.log

得たサンプリング結果をmysqldumpslowコマンドが読み込めるように、 次のperlスクリプトを準備する。

$ cat /usr/local/bin/innotop2slowlog.pl
#!/usr/bin/perl -w
use strict;
while (<>) {
    chop;
    my @row = split(" ", $_);
    printf ("# Time:\n# User\@Host: %s(%s) @ %s\n", $row[2], $row[2], $row[3]);
    my $i = 5;
    while ($row[$i] !~ /[0-9]{2}\:[0-9]{2}$/ && $i < $#row) { $i++;}
    printf ("# Query_time: %s Lock_time = x.x Rows_sent:x Rows_examined: x\n", $row[$i]);
    print join(" ", @row[($i+2)..$#row]) . "\;\n";
}

あとは、innotop2slowlog.plでスロークエリログ形式に変換したファイル(ここでは/tmp/innotop2slowlog.log)を mysqldumpslowに処理させるだけである。

$ /usr/local/bin/innotop2slowlog.pl /tmp/innotop.log > /tmp/innotop2slowlog.log
$ mysqldumpslow -s c -r /tmp/innotop2slowlog.log

MySQL: innotopとサンプリング - The Programmer’s Guide to the Parallel World

1年前 | | 2010年 8月 3日 | このエントリーを含むはてなブックマーク
2010年 7月 15日 はてなブックマーク -
タグ: #MySQL #InnoDB
select t_b.trx_mysql_thread_id blocking_id,
       t_w.trx_mysql_thread_id requesting_id,
       p_b.HOST blocking_host,
       p_w.HOST requesting_host,
       l.lock_table lock_table,
       l.lock_index lock_index,
       l.lock_mode lock_mode,
       p_w.TIME seconds,
       p_b.INFO blocking_info,
       p_w.INFO requesting_info
from information_schema.INNODB_LOCK_WAITS w,
     information_schema.INNODB_LOCKS l,
     information_schema.INNODB_TRX t_b,
     information_schema.INNODB_TRX t_w,
     information_schema.PROCESSLIST p_b,
     information_schema.PROCESSLIST p_w
where w.blocking_lock_id = l.lock_id
  and w.blocking_trx_id = t_b.trx_id
  and w.requesting_trx_id = t_w.trx_id
  and t_b.trx_mysql_thread_id = p_b.ID
  and t_w.trx_mysql_thread_id = p_w.ID
order by requesting_id,
         blocking_id
\G

実行結果(横)です。

+-------------+---------------+-----------------+-----------------+---------------+------------+-----------+---------+---------------+---------------------------------------------------+
| blocking_id | requesting_id | blocking_host   | requesting_host | lock_table    | lock_index | lock_mode | seconds | blocking_info | requesting_info                                   |
+-------------+---------------+-----------------+-----------------+---------------+------------+-----------+---------+---------------+---------------------------------------------------+
|           8 |             9 | localhost:37001 | localhost:37002 | `scott`.`emp` | `PRIMARY`  | X         |      72 | NULL          | update emp set sal = sal + 200 where empno = 7788 |
+-------------+---------------+-----------------+-----------------+---------------+------------+-----------+---------+---------------+---------------------------------------------------+
1 row in set (0.01 sec)

実行結果(縦)です。

*************************** 1. row ***************************
    blocking_id: 8
  requesting_id: 9
  blocking_host: localhost:37001
requesting_host: localhost:37002
     lock_table: `scott`.`emp`
     lock_index: `PRIMARY`
      lock_mode: X
        seconds: 86
  blocking_info: NULL
requesting_info: update emp set sal = sal + 200 where empno = 7788
1 row in set (0.00 sec)

ここから、

といった情報を読み取ることができます。これはOracle Databaseと遜色のない内容になっており(参考:ロッ クをつぶせ! 最初に疑うべき原因(1/3) − @IT)、ほぼ完璧といってよいレ ベルです。

それから、今回の例のようにデー タベースTCP/IP経 由で接続している場合は、TCPの ポート番号からク ライアントプロセスを特定することができます。

# netstat -np | grep 37001
tcp        0      0 127.0.0.1:37001             127.0.0.1:3306              ESTABLISHED 6105/mysql
tcp        0      0 127.0.0.1:3306              127.0.0.1:37001             ESTABLISHED 6000/mysqld

この例では8番のク ライアントmysqlコ マンドラインツールであり、プロセスIDは6105番であることが分かります。ここまで分かればあとは該当のプロセスをkillするといった暫定 対処や、プログラムを修正するといった本格対処をとることができます。

MySQL InnoDBにおけるロック競合の解析手順 - SH2の日記

データベースの運用で避けられないのが、ロック競合によって起こるシステムトラブルへの対応です。「2時までに終わるはずのバッチ処理が朝になっても終わっていない」とか「負荷が高いわけでもないのにシステムが無応答になっている」といったトラブルが発生したとき、DBエンジニアはそれがロック競合によるものなのかどうかを切り分けて、適切に対処しなければなりません。

これまでInnoDBはロック競合に対してほとんど打つ手がなかったのですが、最近ようやく対処方法がでてきました。今日はその手順を確認していきたいと思います。
前提

今回ご紹介する手順は、MySQLの以下のバージョンを対象にしています。

* MySQL 5.1+InnoDB Plugin 1.0
* MySQL 5.4

いきなりハードルを上げてしまって申し訳ありませんが、バージョン5.0以下や素の5.1では使えませんのでご注意ください。以降の実行例はすべてMySQL Community Server 5.1.35+InnoDB Plugin 1.0.3で行ったものです。


というものです、


1年前 | | 2010年 7月 15日 | このエントリーを含むはてなブックマーク