ちょっと硬派なコンピュータフリークのBlogです。

カスタム検索

2011-04-07

「優れたMySQL DBAを見分ける27+3の質問」に対する回答例

随分と更新が空いてしまったが、「優れたMySQL DBAを見分ける27+3の質問」に対する回答例(漢バージョン)を紹介しよう。実は質問を掲載した際「難しい!」というコメントが非常に多く、もう少し易しい質問にするべきだったかと思って次のように呟いてみたのだが・・・


そのような憂慮など吹き飛ばす回答を松信氏から頂いたのであった!!



非常に心強くて安心した。さすがに日本を代表するMySQLのエキスパートである。出題のレベルは間違ってはいなかった!!

そんなわけで、回答の方に移ろう。

MySQLのサーバープロセスはいくつある?

ひとつ。mysqldはシングルプロセス・マルチスレッドモデルを採用しているので、"サーバー"プロセスはひとつである。多くの場合、Linuxなどでmysqldを動かす場合には、お供にmysqld_safeも常に動いていることが多いが、mysqld_safeはサーバーではなく、mysqldのためのラッパーであるので数には含めない。

rootユーザーのパスワードを忘れたときの回復手順

--skip-grant-tablesオプションを使う。このオプションをつけてmysqldを起動するとパスワードなしでログインできるようになるので、

mysql> UPDATE mysql.user SET password=PASSWORD('新しいパスワード')
    -> WHERE user='root' AND host='localhost';

という具合にmysql.userテーブルを更新しよう。そして--skip-grant-tablesオプションを外して再起動すればバッチリである。作業中、外部からログインされないようにするには、--skip-networkingオプションを使うといいだろう。ただし、Windows環境下では--skip-networkingをするとログイン出来なくなってしまう(named pipeなどの代替の通信手段がない場合)ので、--init-fileを使ってパスワードの設定をする方法などを活用するといいだろう。

参照:How to Reset the Root Password - MySQL 5.5 Reference Manual

MySQLをオンラインバックアップする方法を3つ。(もっとでも可)

オンライン、すなわちMySQLへのアクセスを停止せずにバックアップする方法である。

  1. mysqldump
  2. MySQL Enterprise Backup(旧InnoDB Hotbackup)
  3. LVMなどのスナップショット

参照:MySQLバックアップ頂上決戦!! LVMスナップショット vs InnoDB Hot Backup

InnoDBのデータファイルが作成可能な場所はどこか。

2つ回答できれば正解。

  1. ファイルシステム上の、mysqldを実行するユーザーのアクセス権のある任意の場所
  2. rawデバイス

ちなみに、ログファイルはファイルシステム上のみ。

参照:Using Raw Devices for the Shared Tablespace - MySQL 5.5 Reference Manual

InnoDBのデフォルトの分離レベルは?

漢は黙って「REPEATABLE-READ」!である。

ネクストキーロックについて説明せよ。

この質問が答えられる人は、InnoDB道に入門済みであると言える。この聞きなれないロックの名前は、InnoDB独特の仕組みであり、レコードとレコードの間、つまり「ギャップ」に対してロックをかけることによって「ファントム」を防ぐための仕組みである。(レコードそのものではなく、レコードとレコードの間をロックするのである。)レコードとレコードの間をロックすると、そこへ新しいレコードを挿入することが出来ないので、ファントムが起きないという寸法だ。

参照:InnoDB Record, Gap, and Next-Key Locks - MySQL 5.5 Reference Manual

ロールバックセグメントにはどのようなデータが格納されるか?

Undoログ。文字通りロールバックしたときにUndoログを使ってデータを復元する他、同一のレコードに対するUndoログを複数保持しておくことによってMVCCを実現している。

参照:InnoDB Multi-Versioning - MySQL 5.5 Reference Manual

InnoDBでデッドロックが発生したときの挙動、および詳細な状態を確認する方法。

レコードレベルでロックをかけるDBMSにとって、デッドロックは避けることが出来ない問題である。InnoDBでは、デッドロックが発生したことを検知することが出来る。デッドロックを検知すると、その原因となった複数のトランザクションのうちの片方が、自動的にロールバックされる。これにより、残った方のトランザクションは処理を継続できるのである。どちらのトランザクションをロールバックするかは、InnoDBが独自に判断する。(更新が多い方というのが目安)

デッドロックが起きたことはアプリケーションがDBからのエラーによって判断できる他、SHOW ENGINE INNODB STATUSのLATEST DETECTED DEADLOCKセクションに表示される。

MyISAMがサポートしている特殊なインデックス2つ。

R-TREEおよびフルテキスト。これはちょっと言い方が曖昧だったかも知れないが、B+TREEでないという意味で「特殊」と表現した。

MySQLにおけるテーブル1行あたりの最大サイズ。

64KB(ただしBLOBやTEXTを除く)

参照:限界までMySQLを使い尽くす!!

構成可能なレプリケーションのトポロジを3つ。

  1. マスター・スレーブ(1:N)
  2. マルチ・マスター
  3. カスケード(スレーブにさらにスレーブ)

参照:Art of MySQL Replication - Slide Share

構成不可能なレプリケーションのトポロジは何か。

マルチソース。(複数のマスターからひとつのスレーブに対して複製を行うもの。)

レプリケーションをHAとして利用するとき気をつけるべきこと。

主に次の3つ。

  1. 非同期だから最後のほうの更新は失われるかもよん。
  2. 自動では切り替わらないよん。
  3. クラッシュしたマスターの復旧は面倒だよん。

レプリケーションに問題があるとき最初に確認するコマンドは?

SHOW SLAVE STATUS。これが鉄板!

出力された情報をどう見るべきかはまた色々とポイントがあるのだけど。

レプリケーションの遅れが生じる原因を3つ。

  1. クソ重い更新系のクエリを投げた。(そのクエリの実行にかかる時間の分きっちり遅れが生じる。)
  2. ネットワークの転送に時間がかかる。
  3. スレーブに対する参照の負荷が高すぎる。(Need more slaves!!)

ステータス変数を見るとき注意すべきポイント。

SHOW GLOBAL STATUSを時間をあけて2回実行して、差分をとるということ。1回だけ実行しても、それはmysqldが起動してからの累積値なのであまり参考にはならない。それよりも、問題が発生している時間に的を絞って、その時間帯だけのデータを採取するべきことのほうが多いだろう。その場合には、1分とかの時間をあけて、2回実行である。

最近アクセス数が多くなりレスポンスが低下しているようだ。パフォーマンスチューニングする際どこから手をつけるべきか。

チューニングをするということは、ボトルネックを探して潰すということに他ならない。データベースのボトルネックは、まず第一に重いクエリ、次にディスクI/Oである。それらをチューニングしてもダメならスケールアップやスケールアウトをすることになるだろう。

ボトルネックとなるような重いクエリを探すには、スロークエリログ、SHOW GLOBAL STATUS、クエリアナライザ(商用)などを駆使することになるだろう。

なぜサブクエリは遅いのか?またはMySQLで高速に実行できるサブクエリの種類は?

MySQLにおいて「遅い」とされるサブクエリは、DEPENDENT SUBQUERYである。この種類のサブクエリは、外部クエリにおいて行がひとつフェッチされるごとに、サブクエリが実行される。サブクエリごとに実行計画をたてて、改めてSELECTを実行することになるため、オーバーヘッドが大きいのである。

参照:なぜMySQLのサブクエリは遅いのか。

相関のないサブクエリはEXPLAINによって実行計画を見たときSUBQUERYと表示される。そのようなサブクエリは最初に一回だけ実行され、結果がキャッシュされるためとても高速である。

サブクエリが遅い場合、どのような書き換えを行う?

JOINに書き換えよう。

参照:Rewriting Subqueries as Joins - MySQL 5.5 Reference Manual

書き換えが出来ないサブクエリはどのようなものか。

GROUP BY(および集計関数)を含むようなものは書き換えが出来ない。MySQLにはマテリアライズド・ビューの機能はないので、集計用のテーブル自分で作成し、集計する対象のテーブルにトリガをしかけるなどしてメンテナンスするといいだろう。

参照:MySQL のトリガーの実用性を確認するために InnoDB の SELECT COUNT(*) を高速化してみる - Kazuho@Cybozu Labs

ホームディレクトリの.my.cnfに書くべき内容は?

ユーザーのホームディレクトリには、mysqlコマンドなど、クライアント系プログラムのためのオプションを記述しておくといいだろう。

[client]
password

[mysql]
show_warnings

passwordを引数ナシで書いておくと、パスワードを入力するためのプロンプトが表示される。(-pオプションを省略できるわけだ。)ちなみに、筆者の場合はもっぱらMySQL Sandboxばかり使っているので、user=msandbox、password=msandboxと書いてしまっている。

また、コマンド実行後の警告を見逃さないために、show_warningsオプションをつけておくことを強くお勧めする。

MySQLがサポートしているプラグインの種類8個。(5つで合格)

この問いに答えられる人は、恐らくMySQLのソースコードを理解しており、なおかつプラグインを自分で書いたことがあるほどのエキスパートである可能性が高い。

プラグインはMySQL 5.1から搭載された仕組みであり、MySQL 5.5でもいくつか追加された。答えはソースコードに書いてある。include/mysql/plugin.hを見てみよう。

/*
  The allowable types of plugins
*/
#define MYSQL_UDF_PLUGIN             0  /* User-defined function        */
#define MYSQL_STORAGE_ENGINE_PLUGIN  1  /* Storage Engine               */
#define MYSQL_FTPARSER_PLUGIN        2  /* Full-text parser plugin      */
#define MYSQL_DAEMON_PLUGIN          3  /* The daemon/raw plugin type */
#define MYSQL_INFORMATION_SCHEMA_PLUGIN  4  /* The I_S plugin type */
#define MYSQL_AUDIT_PLUGIN           5  /* The Audit plugin type        */
#define MYSQL_REPLICATION_PLUGIN     6  /* The replication plugin type */
#define MYSQL_AUTHENTICATION_PLUGIN  7  /* The authentication plugin type */
#define MYSQL_MAX_PLUGIN_TYPE_NUM    8  /* The number of plugin types   */

ちなみに、5つで合格としたのは、MySQL 5.1では5つだから。MySQL 5.5になって3つ追加された。

RDBMSにおけるリレーションとは何か?(ヒント:JOINは誤り。)

この問題はMySQLの問題ではないが、「そもそもRDBMSってなんだっけ?」という一般教養をテストするためのもの。リレーショナルモデルにおけるリレーションとはデータの集合のことである。つまり、RDBMSにおいてはテーブルおよびビューがリレーションに相当する。SQLとリレーショナルモデルは乖離があり、正確には、リレーションの操作を記述するには、データの集合であるリレーションそのものと、そのデータを代入するための関係変数(Relvar)が必要なのだが、RDBMSはテーブルが両方を兼ねている(ようなものである)。Relvarにまで言及出来れば満点。

JOINは最大何回可能か。

61回。

参照:限界までMySQLを使い尽くす!!

EXPLAINを実行すると、Using where; Using filesortと表示されている。これは問題か?

場合による。

まず、Using whereはインデックスによってレコードをフェッチした後に、さらに別の条件で絞り込みが行われる場合に表示される。適切なインデックスによって最初に絞り込みが行われていれば、問題がない場合が多い。

Using filesortはインデックスによるソート(インデックス順でレコードを読み込む)ができず、クイックソートをする必要がある場合に表示される。クイックソートは行数が少なければ十分に速いので問題になることはない。行数が多い場合にはmysqldの負荷上昇やレスポンスの低下の原因となるだろう。

1億件のテーブルを1日に数回スキャンする目的なら、どのストレージエンジンを使う?その理由は?

これは答えがひとつではない回答であるが、敢えて書いてみた。ストレージエンジンをひとつ挙げ、まっとうな理由を説明出来れば正解としたい。

例えばMyISAM。データサイズはコンパクトであり、テーブルスキャンが高速である。ファイルをコピーするだけで他のマシンへデータを簡単に移行できるというメリットもある。クラッシュセーフではないが、集計をするという目的には適している。

例えばInnoDB。データの空間効率はMyISAMに劣るとしても、巨大なメモリを有効活用出来るというメリットがある。全てのレコードがメモリ上に乗るようにすれば、ファイルアクセスは皆無であり、高速な処理が期待できる。

どちらの主張も場合によっては正しい。ナイスな主張が出来ればオッケーだ。

GPLに準拠して、自らのプログラムにGPLを適用しなければいけないのはどのような時か。

MySQLといえばライセンスはGPLv2。従って利用にあたっては、GPLについての基本的な知識も欠かせない。MySQLを利用したプログラムに対してGPLv2を適用しなければいけないのは、そのプログラムを頒布(≒公開、譲渡、販売etc)するときである。従って、社内利用やウェブサービスとして外部からアクセスしてもらうだけなら、GPLv2を適用する必要はない。

参照:GPLの境界線

番外ほっこり編。これがパーフェクトに答えらえればかなりのMySQL通であると言える。

MySQLはなんと発音するか?

マイ・エス・キュー・エル。マイ・シークェルではないので注意。

MySQLのマスコットであるイルカの名前は?

Sakila。2002年に開催されたイルカの名前つけコンテストで、6357通の応募の中から選ばれた。名付け親はスワジランドの開発者。

参照:The MySQL Dolphin Gets a Name: Sakila!

MyNAの読み方と名前の由来。

マイナ。理由はマイナーだから(MyNA発足当時)。今やすっかりメジャーになったのでもうマイナーなんて言わせない!?

まとめ

いかがだっただろうか。今回の回答にはできるだけ参照先のページなどを掲載したので、もっと詳しく知りたい人はリンク先を読むといいだろう。

もっと系統的にMySQLの知識を強化したい!と思う人は、ぜひ拙著「エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド」(通称鍵本)を読んで頂きたいと思う。恐らく上記の質問のうち、8割以上は拙著を読めば回答できるはずである。残念ながら今のところAmazonでは売り切れ御礼であるが、増刷されたら是非購入して頂きたい。

0 コメント:

コメントを投稿