MySQL InnoDBの利用

2005/01/12 変更

私もInnoDBをちょろちょろ使ってますので、自分用のメモとして書いてみました。


MyISAMとの違いについて

現在、MySQLでは色々なテーブル・タイプを使えますが、実際はMyISAMかInnoDBを使うことがほとんどだと思います。
そこで比較表を作ってみました。

比較内容 MyISAM InnoDB
テーブルのロック
外部キー ×
行レベルロック ×
トランザクション ×
UNION ○(MySQL4.0以上) ○(MySQL4.0以上)
サブ・クエリー ○(MySQL4.1以上) ○(MySQL4.1以上)

なお、確かに行レベルロックは便利なのですが、テーブル・ロックが便利な場合も存在します。 MySQLのテーブルは、ロックする順番を内部で変えているらしく、デッドロックはおこらないようなのです。 したがって、単純に「トランザクションのような処理」ができますし、サーバ負荷が軽いです。

また、MyISAMは開発も容易なので「どうしても行レベル・ロックが必要」という場合以外、私はMyISAMのほうがいいのではないかと思います。


テーブル・ロックについて

MyISAM, innoDBともテーブル・ロックが可能です。

テーブル・ロックは「LOCK TABLES テーブル名 (READ or WRITE), テーブル名 (READ or WRITE)...」と書きます。
READロックはほかで書き込みができないけど、読み込みは許す場合に使います。

実際に、同時に複数の接続でテーブル・ロックをしたとき、ロックした側は自由に読み書きできますが、ロックされてしまった側は、ロックが開放されるまでずっと待ちつづけます。

MyISAMではデッドロックにもならないし(テーブル・ロック以外のロック方式がないからデッドロックはおきません)、ロック・タイムアウトもおきませんので、プログラム的な工夫は不要です。MySQLサーバ側でうまく調整してくれるようです。

一方、innoDBでもテーブル・ロックできてしまいますが、デッドロックの自動検出ができないようなので、my.cnf(Win版ではmy.ini)に「innodb_lock_wait_timeout」の設定をしておきましょう。つまり、innoDBではテーブル・ロックでデッドロックするとタイムアウトまで待ってからエラーが返りますので、MySQL利用者自身がエラーコードをチェックして対応することになります。


InnoDBだけの機能


エラーコード

他のエラーはマニュアルを見てもらうこととして、ここではinnoDBを利用するとほぼ確実に発生するデッドロックとロック・タイムアウトについて書きます。
PHPではmysql_errno()関数で直前のエラーコードを取得できます。

エラーコード エラー内容
1205
ER_LOCK_WAIT_TIMEOUT
ロック・タイムアウト
1213
ER_LOCK_DEADLOCK
デッドロック

これらのエラーはMyISAMでは発生しません。しかし、innoDBではタイミングによっては発生します。したがって、このエラーが発生したらロールバックしてからトランザクションを再実行する必要があります。

Copyright©2001-2019 釣ったよ! All Right Reserved.    sg@tsuttayo.jpn.org