第4章 データベース管理

目次

4.1. MySQL のコンフィギャ
4.1.1. mysqld コマンドラインオプション
4.1.2. my.cnf オプション設定ファイル
4.2. 同じマシン上で複数の MySQL サーバを実行する
4.2.1. Windows 上で複数のサーバを実行する
4.2.2. Unix 上で複数のサーバを実行する
4.2.3. 複数サーバ環境でクライアントプログラムを使用する
4.3. 一般的なセキュリティ関連事項と MySQL アクセス制御システム
4.3.1. 一般的なセキュリティガイドライン
4.3.2. MySQL のクラッカー対策
4.3.3. セキュリティ関連の mysqld スタートアップオプション
4.3.4. LOAD DATA LOCAL のセキュリティ関連事項
4.3.5. 権限システムが行うこと
4.3.6. 権限システムはどのように機能するか
4.3.7. MySQL が提供する権限
4.3.8. MySQL サーバへの接続
4.3.9. アクセス制御の段階 1: 接続確認
4.3.10. アクセス制御の段階 2: 要求確認
4.3.11. MySQL 4.1 のパスワードハッシュ
4.3.12. Access denied エラーの原因
4.4. MySQL のユーザ管理
4.4.1. GRANT および REVOKE の構文
4.4.2. MySQL のユーザ名とパスワード
4.4.3. 権限の変更はいつ反映されるか
4.4.4. MySQL 権限の初期設定
4.4.5. MySQL への新規ユーザの追加
4.4.6. MySQL ユーザの削除
4.4.7. ユーザリソースの制限
4.4.8. パスワードの設定
4.4.9. パスワードのセキュリティ
4.4.10. 安全な接続の使用
4.5. 障害の予防とリカバリ
4.5.1. データベースのバックアップ
4.5.2. BACKUP TABLE 構文
4.5.3. RESTORE TABLE 構文
4.5.4. CHECK TABLE 構文
4.5.5. REPAIR TABLE 構文
4.5.6. myisamchk を使用したテーブルの保守とクラッシュのリカバリ
4.5.7. テーブル保守計画
4.5.8. テーブル情報の取得
4.6. データベース管理言語リファレンス
4.6.1. OPTIMIZE TABLE 構文
4.6.2. ANALYZE TABLE 構文
4.6.3. CHECKSUM TABLE 構文
4.6.4. FLUSH 構文
4.6.5. RESET 構文
4.6.6. PURGE MASTER LOGS 構文
4.6.7. KILL 構文
4.6.8. SHOW 構文
4.7. MySQL のローカライズと国際的な使用
4.7.1. データおよびソート用キャラクタセット
4.7.2. 英語以外のエラーメッセージ
4.7.3. 新しいキャラクタセットの追加
4.7.4. キャラクタ定義配列
4.7.5. 文字列照合サポート
4.7.6. マルチバイト文字サポート
4.7.7. キャラクタセットに関する問題
4.8. MySQL サーバサイドのスクリプトとユーティリティ
4.8.1. サーバサイドのスクリプトとユーティリティの概要
4.8.2. mysqld_safemysqld のラッパ)
4.8.3. mysqld_multi(複数の MySQL サーバを管理するプログラム)
4.8.4. myisampack(MySQL 圧縮読み取り専用テーブルジェネレータ)
4.8.5. mysqld-max(拡張 mysqld サーバ)
4.9. MySQL クライアントサイドのスクリプトとユーティリティ
4.9.1. クライアントサイドのスクリプトとユーティリティの概要
4.9.2. mysql(コマンドラインツール)
4.9.3. mysqlcc(MySQL コントロールセンタ)
4.9.4. mysqladmin(MySQL サーバの管理)
4.9.5. mysqlbinlog(バイナリログからクエリを実行する)
4.9.6. mysqlcheck を使用したテーブルの保守とクラッシュのリカバリ
4.9.7. mysqldump(テーブル構造とデータのダンプ)
4.9.8. mysqlhotcopy(MySQL のデータベースとテーブルのコピー)
4.9.9. mysqlimport(テキストファイルからのデータのインポート)
4.9.10. mysqlshow(データベース、テーブル、およびカラムの表示)
4.9.11. mysql_config(クライアントをコンパイルするためのコンパイルオプションの取得)
4.9.12. perror(エラーコードの説明)
4.9.13. テキストファイルから SQL コマンドを実行する方法
4.10. MySQL ログファイル
4.10.1. エラーログ
4.10.2. 一般クエリログ
4.10.3. 更新ログ
4.10.4. バイナリログ
4.10.5. スロークエリログ
4.10.6. ログファイルの保守
4.11. MySQL のレプリケーション
4.11.1. はじめに
4.11.2. レプリケーション実装の概要
4.11.3. レプリケーションの実装の詳細
4.11.4. レプリケーションのセットアップ方法
4.11.5. レプリケーション機能と既知の問題
4.11.6. レプリケーションスタートアップオプション
4.11.7. マスタサーバを制御する SQL ステートメント
4.11.8. スレーブサーバを制御する SQL ステートメント
4.11.9. レプリケーション FAQ
4.11.10. レプリケーションのトラブルシューティング
4.11.11. レプリケーションバグのレポート

4.1. MySQL のコンフィギャ

4.1.1. mysqld コマンドラインオプション

通常、mysqld オプションはオプション設定ファイルから管理してください。 See 項4.1.2. 「my.cnf オプション設定ファイル」

mysqldmysqld.servermysqld グループと server グループからオプションを読み込みます。 mysqld_safemysqldservermysqld_safesafe_mysqld の各グループからオプションを読み込みます。 組み込み MySQL サーバは通常、serverembedded、および xxxxx_SERVER からオプションを読み込みます。ここで、xxxxx はアプリケーションの名前です。

mysqld には、多くのコマンドラインオプションがあります。以下、一般的なコマンドラインオプションについて説明します。 完全なオプション一覧を参照するには、mysqld --help を実行してください。 レプリケーション用のオプションについては、別のセクションで説明します。項4.11.6. 「レプリケーションスタートアップオプション」 を参照してください。

  • --ansi

    MySQL 構文ではなく、SQL-99 構文を使用する。 See 項1.8.2. 「ANSI モードでの MySQL の実行」

  • -b, --basedir=path

    インストールディレクトリのパス。すべてのパスは通常、このパスからの相対パスで解決される。

  • --big-tables

    すべてのテンポラリセットをファイルに保存することにより、大きな結果セットを可能にする。これによりほとんどの 'table full' エラーが解決されるが、メモリ内テーブルだけで事足りるクエリの実行速度も遅くなる。MySQL バージョン 3.23.2 以降、小さなテンポラリテーブルの場合はメモリを使用し、必要に応じて自動的にディスクテーブルに切り替わるようになっている。

  • --bind-address=IP

    バインドする IP アドレス。

  • --console

    --log-error が指定されている場合でも、stderr/stdout にエラーログメッセージを書き込む。このオプションを使用した場合、Windows では mysqld によりコンソール画面が開かれたままになる。

  • --character-sets-dir=path

    キャラクタセットが格納されているディレクトリ。 See 項4.7.1. 「データおよびソート用キャラクタセット」

  • --chroot=path

    起動時に chroot 環境に mysqld デーモンを配置する。MySQL 4.0 以降の推奨セキュリティ設定(MySQL 3.23 では、完全に閉じた chroot ジェイルを提供できない)。 ただし、LOAD DATA INFILESELECT ... INTO OUTFILE に制約が加わる。

  • --core-file

    mysqld が異常終了した場合に、コアファイルを作成する。システムによっては、mysqld_safe--core-file-size を指定することも必要になる。 See 項4.8.2. 「mysqld_safemysqld のラッパ)」。 注意: --user オプションも使用している場合、Solaris などシステムではコアファイルを作成できない。

  • -h, --datadir=path

    データベースルートのパス。

  • --debug[...]=

    MySQL を --with-debug でコンフィギャしている場合、このオプションを使用して mysqld の動作を示すトレースファイルを取得できる。 See 項E.1.2. 「トレースファイルの作成」

  • --default-character-set=charset

    デフォルトのキャラクタセットを設定する。 See 項4.7.1. 「データおよびソート用キャラクタセット」

  • --default-table-type=type

    デフォルトのテーブル型を設定する。 See 章?7. MySQL のテーブル型

  • --delay-key-write[= OFF | ON | ALL]

    MyISAM で、DELAYED KEYS をどのように使用するか指定する。 See 項5.5.2. 「サーバパラメータのチューニング」

  • --delay-key-write-for-all-tables(MySQL 4.0.3 では、--delay-key-write=ALL を使用)

    すべての MyISAM テーブルにおいて、書き込み間のキーバッファをフラッシュしない。 See 項5.5.2. 「サーバパラメータのチューニング」

  • --des-key-file=filename

    DES_ENCRYPT() および DES_DECRYPT() が使用するデフォルトキーをこのファイルから読み取る。

  • --enable-external-locking(以前は --enable-locking)

    システムロックを有効にする。注意: lockd が完全には機能しないシステム(Linux など)でこのオプションを使用すると、mysqld がデッドロックになる可能性が高くなる。

  • --enable-named-pipe

    名前付きパイプのサポートを有効化する(Windows NT/2000/XP のみ)。

  • -T, --exit-info

    mysqld サーバのデバッグに使用できる、複数の異なるフラグのビットマスク。完全に理解していない限り、このオプションは使用しないこと。

  • --flush

    各 SQL コマンド実行後、ディスクへの変更をすべてフラッシュする。通常、MySQL は各 SQL コマンドの後、ディスクへの変更の書き込みだけを行い、ディスクへの同期処理はオペレーティングシステムに任せる。 See 項A.4.1. 「MySQL が何度もクラッシュする場合に行うこと」

  • -?, --help

    ショートヘルプを表示して終了する。

  • --init-file=file

    起動時に、このファイルから SQL コマンドを読み取る。

  • -L, --language=...

    クライアントエラーメッセージに使用する言語。フルパスで指定できる。 See 項4.7.2. 「英語以外のエラーメッセージ」

  • -l, --log[=file]

    接続とクエリをログファイルに記録する。 See 項4.10.2. 「一般クエリログ」

  • --log-bin=[file]

    データを変更するクエリをすべてログファイルに記録する。バックアップおよびレプリケーション用に使用する。 See 項4.10.4. 「バイナリログ」

  • --log-bin-index[=file]

    バイナリログファイル名のインデックスファイル。 See 項4.10.4. 「バイナリログ」

  • --log-error[=file]

    エラーメッセージおよびスタートアップメッセージをこのログファイルに記録する。 See 項4.10.1. 「エラーログ」

  • --log-isam[=file]

    ISAM および MyISAM の変更をすべてログファイルに記録する(ISAM および MyISAM のデバッグ時のみ使用)。

  • --log-long-format

    追加情報をログファイルに記録する(更新ログ、バイナリ更新ログ、スロークエリログなど、有効化されているすべてのログ)。たとえば、クエリのユーザ名とタイムスタンプが記録される。--log-slow-queries--log-long-format を使用している場合、インデックスを使用しないクエリも、スロークエリログに記録される。 注意: --log-long-format は MySQL バージョン 4.1 で廃止され、--log-short-format が導入されている(long log format がバージョン 4.1 以降のデフォルト設定になった)。また、MySQL 4.1 から、インデックスを使用しないクエリをスロークエリログに記録するための --log-queries-not-using-indexes オプションが利用可能になっている。

  • --log-queries-not-using-indexes

    このオプションを --log-slow-queries と一緒に使用すると、インデックスを使用しないクエリも、スロークエリログに記録される。このオプションは MySQL 4.1 で導入された。 See 項4.10.5. 「スロークエリログ」

  • --log-short-format

    ログファイル(更新ログ、バイナリ更新ログ、スロークエリログなど、有効化されているすべてのログ)に記録される情報が少なくなる。たとえば、クエリのユーザ名とタイムスタンプが記録されなくなる。このオプションは MySQL 4.1 で導入。

  • --log-slow-queries[=file]

    実行時間が long_query_time 秒を超えたクエリをすべてログファイルに記録する。 注意: 記録されるデフォルトの情報量は MySQL 4.1 で変更された。詳細については、--log-long-format オプションおよび --log-long-format オプションの説明を参照のこと。 See 項4.10.5. 「スロークエリログ」

  • --log-update[=file]

    指定がなければ、更新を file.# に記録する。# は一意の番号。 See 項4.10.3. 「更新ログ」。 更新ログは MySQL 5.0 で廃止されるので、代わりにバイナリログ(--log-bin)を使用すること。 See 項4.10.4. 「バイナリログ」。 バージョン 5.0 からは、--log-update を使用すると単にバイナリログが有効になる。

  • --low-priority-updates

    テーブル編集操作(INSERTDELETEUPDATE)の優先順位が選択よりも低くなる。{INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ... を使用して 1 つのクエリだけ優先順位を低くしたり、SET LOW_PRIORITY_UPDATES=1 を使用して 1 つのスレッド内での優先順位を変更することもできる。 See 項5.3.2. 「テーブルロック関連の問題」

  • --memlock

    メモリ内の mysqld プロセスをロックする。これは、使用しているシステムが mlockall() システムコールをサポートしている場合(Solaris など)のみで使用可能。オペレーティングシステムが原因で mysqld のスワップが発生するという問題がある場合、その解決に役立つ。 注意: このオプションを使用するには、サーバを root として起動することが必要になるが、これはセキュリティ上好ましくない。

  • --myisam-recover [=option[,option...]]

    オプションは、DEFAULTBACKUPFORCE、および QUICK の任意の組み合わせ。このオプションを無効にするには、これを明示的に "" に設定する。このオプションを使用すると、mysqld はテーブルを開くときに、テーブルにクラッシュのマークが付いていないか、つまりテーブルが正しく閉じられているかどうかをチェックする (最後のオプションは、--skip-external-locking を使用している場合だけ有効)。テーブルにクラッシュマークが付いていた場合、mysqld はテーブルをチェックする。テーブルが破損していた場合、mysqld は修復を試みる。

    以下のオプションにより、修復方法が決定される。

    オプション説明
    DEFAULT--myisam-recover でどのオプションも指定しないのと同じ。
    BACKUP修復時にデータテーブルが変更された場合、table_name.MYD データファイルのバックアップを table_name-datetime.BAK として保存する。
    FORCE.MYD ファイルから複数のレコードが失われる場合でも修復を実行する。
    QUICK削除ブロックがない場合、テーブル内のレコードをチェックしない。

    テーブルを自動的に修復する前に、MySQL はそのことをエラーログに追加する。ユーザの介入なしにほとんどすべての問題をリカバリできるようにするには、オプション BACKUP,FORCE を使用する。これにより、いくつかのレコードが削除される場合でもテーブルの修復が行われるが、古いデータファイルがバックアップとして残るので後で調べることができる。

  • --new

    バージョン 4.0.12 から使用可能となったオプション。--new オプションを使用すると、特定の局面でサーバを 4.1 のように動作させることができ、簡単に 4.0 から 4.1 にアップグレードできる。

  • --pid-file=path

    mysqld_safe によって使用される PID ファイルのパス。

  • -P, --port=...

    TCP/IP 接続をリッスンするポート番号。

  • -o, --old-protocol

    非常に古いクライアントとの互換性のために 3.20 プロトコルを使用する。 See 項2.5.5. 「バージョン 3.20 から 3.21 へのアップグレード」

  • --one-thread

    1 スレッドのみ使用する(Linux でのデバッグ用)。 このオプションは、サーバのデバッグが有効になっている場合のみ使用可能。 See 項E.1. 「MySQL サーバのデバッグ」

  • --open-files-limit=

    mysqld で使用可能なファイル記述子の数を変更できる。 これが設定されていないか、または 0 に設定されている場合、mysqld は、setrlimit() で使用する値を使用してファイル記述子を予約する。この値が 0 の場合、mysqldmax_connections*5 または max_connections + table_cache*2 のいずれか大きい値をファイル数として予約する。mysqld で ' Too many open files ' のエラーが出る場合、この値を大きくする。

  • -O, --set-variable=name=value

    変数に値を設定する。--help により変数一覧を表示できる。すべての変数の詳細については、このマニュアルの SHOW VARIABLES セクションを参照のこと。 See 項4.6.8.4. 「SHOW VARIABLES。 これら変数を最適化する方法については、「サーバパラメータのチューニング」セクションを参照のこと。 注意: --set-variable=変数名=値 および -O 変数名=値 構文は、MySQL 4.0 で廃止。代わりに --変数名=値 を使用すること。 See 項5.5.2. 「サーバパラメータのチューニング」

    MySQL 4.0.2 では変数を --変数名=値 で直接設定できるので、set-variable は必要なくなった。

    SET で設定可能なスタートアップオプションの最大値を制限するには、--maximum-variable-name コマンドラインオプションを使用して定義する。 See 項5.5.6. 「SET 構文」

    注意: 変数に値を設定すると、その値が設定可能範囲に収まるように、また使用アルゴリズムに合うように自動的に変数値が修正される。

  • --safe-mode

    いくつかの最適化ステージをスキップする。

  • --safe-show-database

    このオプションを使用して SHOW DATABASES コマンドを実行すると、そのユーザが何らかの権限を持っているデータベースのみが戻り値として返る。 バージョン 4.0.2 からすべてのユーザが SHOW DATABASES 権限を持つようになったので、このオプションは廃止され、何もしない(このオプションはデフォルトで有効)。 See 項4.4.1. 「GRANT および REVOKE の構文」

  • --safe-user-create

    これを有効にした場合、ユーザに mysql.user テーブルあるいはそのテーブル内のカラムへの INSERT 権限がなければ、そのユーザは GRANT コマンドを使用して新規ユーザを作成できない。

  • --skip-bdb

    BDB テーブルの使用を無効にする。メモリの節約および演算処理のスピードアップに役立つ。

  • --skip-concurrent-insert

    MyISAM テーブルで SELECTINSERT を同時に実行できなくする(これは、この機能にバグがあると思われる場合だけ使用すること)。

  • --skip-delay-key-write

    MySQL 4.0.3 では、代わりに --delay-key-write=OFF を使用する。 すべてのテーブルの DELAY_KEY_WRITE オプションを無視する。 See 項5.5.2. 「サーバパラメータのチューニング」

  • --skip-grant-tables

    サーバが一切の権限システムを使用しないようにする。これによりすべての人が、すべてのデータベースにフルアクセスできるようになる(実行中のサーバに権限テーブルを再び使用させるには、mysqladmin flush-privileges または mysqladmin reload を実行する)。

  • --skip-host-cache

    IP への名前解決に、ホスト名キャッシュを使用せず、接続ごとに DNS サーバに対しクエリを発行する。 See 項5.5.5. 「MySQL の DNS の使用」

  • --skip-innodb

    Innodb テーブルの使用を無効にする。メモリとディスク領域の節約および演算処理のスピードアップに役立つ。

  • --skip-external-locking(以前は --skip-locking)

    システムロックを使用しない。isamchk または myisamchk を使用するには、サーバをシャットダウンする必要がある。 See 項1.2.3. 「MySQL の安定性」。 注意: MySQL バージョン 3.23 では、REPAIR および CHECK を使用して MyISAM テーブルを修復したりチェックすることができる。

  • --skip-name-resolve

    ホスト名を解決しない。権限テーブルの Host カラムの値がすべて IP アドレスまたは localhost であることが必要である。 See 項5.5.5. 「MySQL の DNS の使用」

  • --skip-networking

    TCP ポートを一切リッスンしない。mysqld とのやり取りはすべて、名前付きパイプまたは Unix ソケットを介して行う必要がある。ローカルからの接続要求のみが許可されているシステムにおいて、特にこのオプションが推奨される。 See 項5.5.5. 「MySQL の DNS の使用」

  • --skip-new

    新しくて間違っている可能性のあるルーチンを使用しない。

  • --skip-symlink

    4.0.13 で廃止。代わりに --skip-symbolic-links を使用すること。

  • --symbolic-links, --skip-symbolic-links

    シンボリックリンクのサポートを有効または無効にする。このオプションは、Windows と Unix では効果が異なる。

    Windows でシンボリックリンクを有効にすると、実際のディレクトリへのパスが含まれる directory.sym ファイルの作成により、データベースディレクトリへのシンボリックリンクを作成できるようになる。 See 項5.6.1.3. 「Windows 上のデータベースに対するシンボリックリンクの使用」

    Unix でシンボリックリンクを有効にすると、CREATE TABLE ステートメントの INDEX DIRECTORY オプションまたは DATA DIRECTORY オプションで MyISAM のインデックスファイルまたはデータファイルを別ディレクトリにリンクできるようになる。テーブルを削除したり名前を変更すると、そのシンボリックリンクがポイントするファイルも削除または名前変更される。

  • --skip-safemalloc

    MySQL を --with-debug=full でコンフィギャしていれば、すべてのプログラムが、メモリの割り当て時と解放時に必ずメモリのオーバーランをチェックする。このチェックには時間がかかるため、このチェックを行わないで済むサーバに対しては、--skip-safemalloc オプションによりチェックをスキップできる。

  • --skip-show-database

    ユーザが SHOW DATABASES 権限を持っていない場合に、SHOW DATABASES コマンドを無効にする。

  • --skip-stack-trace

    スタックトレースを書き込まない。このオプションは、デバッガで mysqld を実行するときに役立つ。システムによっては、コアファイルを取得するためにこのオプションの使用が必要な場合もある。 See 項E.1. 「MySQL サーバのデバッグ」

  • --skip-thread-priority

    応答時間を短くするため、スレッド優先度の使用を無効にする。

  • --socket=path

    Unix では、ローカル接続に使用するソケットファイル(デフォルトでは /tmp/mysql.sock)。 Windows では、名前付きパイプを使用するローカル接続用パイプ名(デフォルトでは MySQL)。

  • --sql-mode=value[,value[,value...]]

    オプション値として、次の任意の組み合わせを設定できる。 REAL_AS_FLOATPIPES_AS_CONCATANSI_QUOTESIGNORE_SPACEONLY_FULL_GROUP_BYNO_UNSIGNED_SUBTRACTIONNO_AUTO_VALUE_ON_ZERONO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_KEY_OPTIONSNO_DIR_IN_CREATEMYSQL323MYSQL40DB2MAXDBMSSQLORACLEPOSTGRESQL、および ANSI。 リセットするには、値を空白にする(--sql-mode="")。

    NO_AUTO_VALUE_ON_ZERO は、AUTO_INCREMENT カラムの処理に影響を与える。通常、NULL または 0 のいずれかをカラムに挿入することにより、カラムの次のシーケンス番号を生成する。 NO_AUTO_VALUE_ON_ZERO を指定すると、0 のこの働きが抑制されるため、NULL だけが次のシーケンス番号を生成することになる。このモードは、0 がテーブルの AUTO_INCREMENT カラムに保存されている場合に役に立つ(これは推奨されている方法ではないが)。たとえば、mysqldump でテーブルをダンプしてから再読み込みした場合、MySQL は通常、0 値に遭遇したときに新規シーケンス番号を生成するため、ダンプされたテーブルと再読み込みしたテーブルの内容が異なる結果になる。この場合、ダンプしたファイルを再読み込みする前に NO_AUTO_VALUE_ON_ZERO を有効にするとこの問題が解決する(このオプションが使用可能になった MySQL 4.1.1 以降、mysqldump によるダンプ出力には、自動的に NO_AUTO_VALUE_ON_ZERO を有効にするためのステートメントが含まれている)。

    他のサーバとの互換性のために使用するオプション値もある。 これらを指定することにより、SHOW CREATE TABLE の実行結果から、以前のバージョンの MySQL または他のデータベースサーバが理解できない出力が除外される。 これらのオプション値を使用すると、CREATE TABLE ステートメントの他のサーバへの移植性が高まる。

    • NO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_DIR_IN_CREATE、および NO_KEY_OPTIONS を使用すると、テーブルオプションや、カラムまたはインデックス定義に関するオプションが除外される。

    • MYSQL323MYSQL40 は、MySQL 3.23 と MySQL 4.0 との互換用。

    • 他のサーバとの互換性を維持するための値は、DB2MAXDBMSSQLORACLE、および POSTGRESQL

    mysqldumpSHOW CREATE TABLE を使用して、ダンプ出力に含むテーブル作成ステートメントを取得するため、これらのオプションは mysqldump の出力にも影響する。

    オプション値のいくつかは、値のセットまたはグループの略称なので、影響は複雑になる。 たとえば、--sql-mode=ANSI(または --ansi)オプションを使用して、サーバに ANSI モードで実行するように命令できる。これは以下のコマンドラインオプションを両方指定するのと同じ。

    --sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY
    --transaction-isolation=SERIALIZABLE
    

    注意: この方法で ANSI モードを指定すると、トランザクション分離レベルを設定することにもなる。 ANSI モードでのサーバの実行については、項1.8.2. 「ANSI モードでの MySQL の実行」 を参照のこと。

    他の ``グループ'' 値は、DB2MAXDBMSSQLORACLE、および POSTGRESQL。 これらのいずれの値を指定しても、PIPES_AS_CONCATANSI_QUOTESIGNORE_SPACENO_TABLE_OPTIONSNO_FIELD_OPTIONS、および NO_KEY_OPTIONS 値が有効になる。

    --sql-mode オプションは MySQL 3.23.41 で追加された。 NO_UNSIGNED_SUBTRACTION 値は 4.0.0 で追加された。 NO_DIR_IN_CREATE は 4.0.15 で追加された。 NO_AUTO_VALUE_ON_ZERONO_TABLE_OPTIONSNO_FIELD_OPTIONSNO_KEY_OPTIONSMYSQL323MYSQL40DB2MAXDBMSSQLORACLEPOSTGRESQL、および ANSI は 4.1.1 で追加された。

  • --temp-pool

    このオプションを使用すると、サーバによって作成される大部分のテンポラリファイルが、それぞれ一意の名前ではなく、小さな名前のセットを使用する。これは、多くの新規ファイルが異なる名前で作成され、それを Linux カーネルが処理する問題を回避するためである。Linux では、メモリがディスクキャッシュではなく、ディレクトリエントリキャッシュに割り当てられるため、以前の動作ではメモリの ``リーク'' が発生しやすい。

  • --transaction-isolation={ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE }

    デフォルトのトランザクション分離レベルを設定する。 See 項6.7.6. 「SET TRANSACTION 構文」

  • -t, --tmpdir=path

    テンポラリファイルの作成に使用されるディレクトリのパス。テンポラリファイルを保存するには小さすぎるパーティション上にデフォルトの /tmp ディレクトリがある場合、このオプションが役に立つ。 MySQL 4.1 以降、複数のパスの指定が可能になっている。これらのパスはラウンドロビン方式で使用される。Unix ではコロン(‘:’)を、Windows ではセミコロン(‘;’)を使用してパスを区切る。 メモリベースのファイルシステムを指すように tmpdir を設定することは可能。ただし、MySQL サーバがスレーブの場合はできない。スレーブの場合、マシンがリブートしてもテンポラリテーブルのレプリケーションまたは LOAD DATA INFILE のレプリケーション処理を続行するためのテンポラリファイルが必要となる。そのため、マシンのリブートで消去されるメモリベースの tmpdir は適しない。ディスクベースの tmpdir が必要。

  • -u, --user={user_name | user_id}

    mysqld サーバを、ユーザ名 user_name またはユーザ ID user_id を持つユーザとして実行する (ここでの ``ユーザ'' は、権限テーブルにリストされた MySQL ユーザではなく、システムログインアカウントを指す)。

    このオプションは、mysqldroot アカウントで起動する場合、必須である。 起動シーケンス中にサーバがそのユーザ ID を変更し、root ではなく、その特定のユーザとして実行する。 See 項4.3.2. 「MySQL のクラッカー対策」

    MySQL 3.23.56 および 4.0.12 以降では、 ユーザが --user=root オプションを my.cnf ファイルに追加するという(結果、サーバは root として稼動)セキュリティホールを回避するため、mysqld は指定された最初の --user オプションだけを使用し、複数の --user オプションがあった場合は警告を出力する。/etc/my.cnf および datadir/my.cnf 内のオプションは、コマンドラインオプションの前に処理されるため、--user オプションを /etc/my.cnf に含めて root 以外の値を指定することを推奨する。/etc/my.cnf 内のオプションは他の --user オプションより先に検出され、サーバは確実に root 以外のユーザとして実行され、他の --user オプションが検出されると警告が出力される。

  • -V, --version

    バージョン情報を表示して終了する。

  • -W, --log-warnings

    Aborted connection... などの警告を .err ファイルに出力する。レプリケーションを使用する場合は、このオプションを有効にすることを推奨する(ネットワークエラーや再接続に関するメッセージなど、現在何が起こっているかについての情報をより多く取得できる)。 See 項A.2.10. 「通信エラー/Aborted connection」

    このオプションは以前の --warnings

実行中のサーバに対して、ほとんどの値を SET コマンドで変更できます。 See 項5.5.6. 「SET 構文」

4.1.2. my.cnf オプション設定ファイル

MySQL ではバージョン 3.22 以降、サーバとクライアントのデフォルトスタートアップオプションをオプション設定ファイルから読み取ることができるようになっています。

Windows では、MySQL はデフォルトオプションを以下のファイルから読み取ります。

ファイル名用途
windows-directory\my.iniグローバルオプション
C:\my.cnfグローバルオプション

windows-directory は Windows ディレクトリの保存場所です。

Unix では、MySQL はデフォルトオプションを以下のファイルから読み取ります。

ファイル名用途
/etc/my.cnfグローバルオプション
DATADIR/my.cnfサーバ固有オプション
defaults-extra-file--defaults-extra-file=path で指定されたファイル
~/.my.cnfユーザ固有オプション

DATADIR は MySQL データディレクトリです(通常、バイナリインストールの場合は /usr/local/mysql/data、ソースインストールの場合は /usr/local/var)。 注意: これは、コンフィギャ時に指定されたディレクトリです。mysqld 起動時に --datadir で指定したディレクトリではありません。サーバはコマンドラインの引数を処理する前にオプション設定ファイルを探すため、--datadir による指定は、サーバがオプション設定ファイルを探す場所に影響しません。

注意: Windows では、オプション設定ファイル内のすべてのパスを ‘\’ ではなく、‘/’ で指定してください。‘\’ は MySQL の エスケープ文字であるため、‘\’ を使用する場合は 2 回指定する必要があります。

MySQL は、オプション設定ファイルを上記の順序で読み取ろうとします。複数のオプション設定ファイルが存在する場合、後で読み取られたファイルに指定されているオプションの方が、先に読み取られたファイル内の同一オプションより優先されます。コマンドラインで指定されたオプションは、オプション設定ファイルで指定されたオプションよりも優先されます。オプションによっては、環境変数を使用して指定できるものもあります。 コマンドラインまたはオプション設定ファイルで指定されたオプションの方が、環境変数値よりも優先されます。 See 付録?F. 環境変数

オプション設定ファイルをサポートするプログラムは、mysqlmysqladminmysqldmysqld_safemysql.servermysqldumpmysqlimportmysqlshowmysqlcheckmyisamchk、および myisampack です。

バージョン 4.0.2 より、loose プリフィックスをコマンドラインオプション(または my.cnf のオプション)に使用できます。オプションの前に loose を付けると、オプションが未知の場合でも、それを読み取ったプログラムはエラー終了せず、以下の警告を出力します。

shell> mysql --loose-no-such-option

MySQL プログラム実行時にコマンドラインで指定できる長いオプションは、オプション設定ファイルで指定できます(ダッシュ2つを前に付けない)。使用可能なオプションの一覧を表示するには、--help オプション付きでそのプログラムを実行してください。

オプション設定ファイルには、以下の形式の行を含めることができます。

  • #comment

    コメント行は、‘#’ または ‘;’ で始める。MySQL 4.0.14 より、コメントを行の途中からでも開始できるようになった。空白行は無視される。

  • [group]

    group は、オプションを設定するプログラムまたはグループの名前。グループ行の後の option行または set-variable 行はすべてそのグループに適用される。これは、オプション設定ファイルの最後、または他のグループ行が指定されるまで有効。

  • option

    これは、コマンドラインの --option と同等。

  • option=value

    これは、コマンドラインの --option=value と同等。注意: オプションの引数にコメント文字が含まれる場合、引数を二重引用符で囲む必要がある。

  • set-variable = name=value

    これは、コマンドラインの --set-variable=name=value と同等。 注意: --set-variable は MySQL 4.0 で廃止された。MySQL 4.0 では、プログラム変数名をオプション名として使用できる。コマンドラインでは、--name=value を使用する。オプション設定ファイルでは、name=value を使用する。

[client] グループにより、すべての MySQL クライアント(mysqld ではなく)に適用されるオプションを指定できます。これは、サーバに接続する際に使用するパスワードを指定するための理想的なグループです(ただし、管理者以外のユーザがオプション設定ファイルを読み書きできないようにしてください)。

特定のバージョンの mysqld サーバだけが読み取れるオプションを作成するには、[mysqld-4.0][mysqld-4.1] などを使用します。

[mysqld-4.0]
new

上記の new オプションは、MySQL サーババージョン 4.0.x でのみ使用されます。

注意: オプションおよび値に対して、その前後にある空白は自動的に削除されます。エスケープシーケンス '\b'、'\t'、'\n'、'\r'、'\\'、および '\s' を値文字列に使用することができます('\s' == blank)。

次に、一般的なグローバルオプション設定ファイルの例を示します。

[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
port=3306
socket=/tmp/mysql.sock
set-variable = key_buffer_size=16M
set-variable = max_allowed_packet=1M

[mysqldump]
quick

次に、一般的なユーザオプション設定ファイルの例を示します。

[client]
# 以下のパスワードは、標準の MySQL クライアント全てに使用されます
password="my_password"

[mysql]
no-auto-rehash
set-variable = connect_timeout=2

[mysqlhotcopy]
interactive-timeout

ソースディストリビューションがあれば、my-xxxx.cnf という名前の設定ファイルのサンプルが support-files ディレクトリに含まれています。 バイナリディストリビューションの場合は、DIR/support-files ディレクトリにあります。ここで、DIR は MySQL インストールディレクトリのパスです(通常、C:\mysql または /usr/local/mysql)。現在、小、中、大、および特大システム用のサンプル設定ファイルが用意されています。my-xxxx.cnf を自分のホームディレクトリにコピーして、名前を .my.cnf に変更し、このファイルを使用してみてください。

オプション設定ファイルをサポートする MySQL プログラムはすべて、以下のオプションをサポートします。

オプション説明
--no-defaultsオプション設定ファイルを一切読み取らない。
--print-defaultsプログラム名と、取得するすべてのオプションを出力する。
--defaults-file=full-path-to-default-file指定された設定ファイルだけを使用する。
--defaults-extra-file=full-path-to-default-fileグローバル設定ファイルを読み取った後、ユーザ設定ファイルの前にこの設定ファイルを読み取る。

注意: これらのオプションは、コマンド行の最初に置く必要があります。ただし、--print-defaults だけは、--defaults-file または --defaults-extra-file の直後に置くことができます。

開発者向け注意: オプション設定ファイルの処理としては、コマンドライン引数を処理する前に、オプション設定ファイル内のすべての合致するオプション(該当グループのオプション)が処理されるようになっています。複数回指定されているオプションの最後のインスタンスを使用するプログラムにとっては、この処理で問題ありません。複数回指定されているオプションを処理するが、オプション設定ファイルは読み取らない旧式のプログラムについては、2 行追加するだけでその機能を装備できます。 その方法については、標準 MySQL クライアントのいずれかのソースコードを確認してください。

シェルスクリプトで、my_print_defaults コマンドを使用してオプション設定ファイルを解析することができます。以下の例は、[client] グループと [mysql] グループに属すオプションの表示要求があった場合に、my_print_defaults が生成する可能性のある出力です。

shell> my_print_defaults client mysql
--port=3306
--socket=/tmp/mysql.sock
--no-auto-rehash

4.2. 同じマシン上で複数の MySQL サーバを実行する

場合によっては、同じマシン上で複数の mysqld サーバを実行することが必要になります。たとえば、既存の稼働環境のままにして、新しい MySQL リリースをテストしたい場合が考えられます。 また、ユーザごとに異なる mysqld サーバへのアクセス権を与える場合などもあります(たとえば、顧客ごとに独立した MySQL インストールを提供するインターネットサービスプロバイダなど)。

単一のマシン上で複数のサーバを実行するには、いくつかのパラメータでサーバ固有の値を設定する必要があります。これらはコマンドラインまたはオプション設定ファイルで設定できます。 項4.1.1. 「mysqld コマンドラインオプション」 および 項4.1.2. 「my.cnf オプション設定ファイル」 を参照してください。

少なくとも以下のオプションはサーバごとに異なります。

  • --port=port_num

  • --socket=path

  • --shared-memory-base-name=name(Windows のみ、MySQL 4.1 で導入)

  • --pid-file=path(Unix のみ)

--port は、TCP/IP 接続のポート番号を制御します。 --socket は、Unix ではソケットファイルパスを、Windows では名前付きパイプの名前を制御します(名前付きパイプ接続をサポートしているサーバに対してのみ、Windows 上で一意のパイプ名を指定する必要があります)。 --shared-memory-base-name は、Windows サーバが使用する共有メモリ名を指定します。これにより、クライアントはその共有メモリを介して接続できるようになります。 --pid-file は、Unix サーバがプロセス ID を書き込むファイルの名前を示します。

以下のオプションを使用する場合、サーバごとに異なる値を設定する必要があります。

  • --log=path

  • --log-bin=path

  • --log-update=path

  • --log-error=path

  • --log-isam=path

  • --bdb-logdir=path

パフォーマンスを高めるには、以下のオプションをサーバごとに個別に設定し、負荷を複数のディスクに分散します。

  • --tmpdir=path

  • --bdb-tmpdir=path

複数のテンポラリディレクトリを上記のように設定し、どの MySQL サーバにどのテンポラリファイルが属するのかわかりやすくしておくことを推奨します。

一般的に、データディレクトリについても、各サーバが異なるディレクトリを使用するようにします。これは --datadir=path オプションで指定します。

警告: 2 つのサーバから同じデータベースのデータを更新しないようにしてください。使用しているオペレーティングシステムが障害からの保護をおこなうようなシステムロックをサポートしていない場合、予期しない事態が発生する可能性があります。また、複数のサーバが同じデータディレクトリを使用し、ログが有効になっている場合、適切なオプションを使用して各サーバに異なるログファイル名を指定する必要があります。そうしないと、サーバは同じファイルにログしてしまいます。

サーバ間でのデータディレクトリ共有に関するこの警告は、NFS 環境にも当てはまります。NFS 環境で複数の MySQL サーバに同じデータディレクトリへのアクセスを認めることは避けてください

  • 主要な問題は、NFS が速度のボトルネックになること。 NFS はそのような使用を考慮していない。

  • 2 つ以上のサーバが互いに干渉しないようにすることも困難。通常、NFS ファイルロックは lockd デーモンによって処理されるが、現在のところ、どのような状況でも 100% の信頼性でロックを実行できるプラットフォームは存在しない。

簡単な方法を選択してください。NFS で複数のサーバにデータディレクトリを共有させるアイデアは良いアイデアではありません。 また、複数の CPU を持つ 1 台のコンピュータを用意し、スレッドを効率的に処理するオペレーティングシステムを使用することを推奨します。

複数の MySQL インストールを異なるロケーションで行う場合、--basedir=path オプションを使用して各サーバに対してベースディレクトリを指定し、各サーバがそれぞれ別のデータディレクトリ、ログファイル、および PID ファイルを使用するようにできます(これらの値のデフォルトは、ベースディレクトリに相対して決定されます)。その場合、他に指定する必要があるオプションは --socket--port だけです。たとえば、.tar ファイルバイナリディストリビューションを使用して MySQL の複数のバージョンをインストールするとします。これらは別々のロケーションにインストールされるので、対応するベースディレクトリ以下で ./bin/mysqld_safe コマンドを使用して、各インストールのサーバを起動することができます。 mysqld_safe が、mysqld に渡す適切な --basedir オプションを特定するので、--socket オプションと --port オプションを mysqld_safe に設定するだけで済みます。

以下のセクションで説明するように、環境変数の設定または適切なコマンドラインオプションの指定により、追加サーバを起動することが可能です。ただし、より永続的に複数のサーバを実行する必要がある場合には、オプション設定ファイルを使用して各サーバ固有のオプション値を指定する方法が便利です。

4.2.1. Windows 上で複数のサーバを実行する

適切なパラメータを使用し、コマンドラインからサーバを手動で起動することにより、Windows 上で複数のサーバを実行することができます。Windows NT ベースのシステムでは、複数のサーバを Windows サービスとしてインストールし、Windows サービスとして実行する方法もあります。コマンドラインから、またはサービスとして MySQL サーバを実行する方法についての一般的な説明は、項2.6.1. 「Windows の注意事項」 に記載されています。このセクションでは、データディレクトリなど、サーバ固有であることが必要なスタートアップオプション値をサーバごとに設定してサーバを起動する方法について説明します(これらのオプションについては、項4.2. 「同じマシン上で複数の MySQL サーバを実行する」 を参照してください)。

4.2.1.1. コマンドラインから複数の Windows サーバを起動する

コマンドラインから手動で複数のサーバを起動するには、コマンドラインまたはオプション設定ファイルで必要なオプションを指定します。オプション設定ファイルでオプションを設定する方が便利ですが、各サーバに独自のオプションセットを確実に設定する必要があります。これを行うには各サーバ用のオプション設定ファイルを作成し、サーバ起動時に --defaults-file を使用してそのサーバにファイル名を指定します。

たとえば、mysqld を、データディレクトリ C:\mydata1 を使用してポート 3307 で実行し、mysqld-max を、データディレクトリ C:\mydata2 を使用してポート 3308 で実行するとします。このためには、2 つのオプション設定ファイルを作成します。たとえば、以下のような C:\my-opts1.cnf ファイルを作成します。

[mysqld]
datadir = C:/mydata1
port = 3307

次に、以下のような 2 つ目のファイル C:\my-opts2.cnf を作成します。

[mysqld]
datadir = C:/mydata2
port = 3308

そして、それぞれのオプション設定ファイルを使って各サーバを起動します。

shell> mysqld --defaults-file=C:\my-opts1.cnf
shell> mysqld-max --defaults-file=C:\my-opts2.cnf

Windows NT では、サーバがフォアグラウンドで起動するため、2 つのコマンドを別々のコンソールウィンドウで実行する必要があります。

サーバをシャットダウンするには、該当するポート番号に接続する必要があります。

shell> mysqladmin --port=3307 shutdown
shell> mysqladmin --port=3308 shutdown

この例のように設定されているサーバは、クライアントに対して TCP/IP 接続を許可します。名前付きパイプ接続も可能にするには、mysqld-nt サーバまたは mysqld-max-nt サーバを使用し、名前付きパイプを有効にするオプションを指定し、その名前を指定します(名前付きパイプ接続をサポートするサーバは、それぞれ固有のパイプ名を使用することが必要です)。たとえば、C:\my-opts1.cnf ファイルを以下のように修正します。

[mysqld]
datadir = C:/mydata1
port = 3307
enable-named-pipe
socket = mypipe1

そして、サーバを次のように起動します。

shell> mysqld-nt --defaults-file=C:\my-opts1.cnf

2 つ目のサーバで使用する C:\my-opts2.cnf も同様に修正します。

4.2.1.2. 複数の Windows サーバをサービスとして起動する

Windows NT ベースのシステムでは、MySQL サーバを Windows サービスとして実行できます。単一の MySQL サービスのインストール、制御、および削除の手順については、項2.1.1.7. 「Windows NT、2000、または XP での MySQL の起動」 を参照してください。

MySQL 4.0.2 より、複数のサーバをサービスとしてインストールできるようになっています。 その場合、各サーバが異なるサービス名を使用することが必要です。また、サーバごとに一意であることが必要なその他のパラメータにも注意が必要です。

以下の手順は、C:\mysql-4.0.8 および C:\mysql-4.0.17 にインストールされた 2 つの異なる MySQL バージョンから mysqld-nt サーバを実行する場合を想定しています(たとえば、本稼働サーバとして 4.0.8 を実行しているときに、アップグレード前に 4.0.17 をテストする場合など)。

--install オプションで MySQL サービスをインストールする場合、以下の原則が当てはまります。

  • サービス名を指定しないと、サーバは MySQL のデフォルトサービス名を使用し、標準オプション設定ファイルの [mysqld] グループからオプションを読み取る。

  • --install オプションの後でサービス名を指定すると、サーバは [mysqld] オプショングループを無視し、サービスと同じ名前のグループからオプションを読み取る。サーバは、標準オプション設定ファイルからオプションを読み取る。

  • サービス名の後に --defaults-file オプションを指定すると、サーバは標準オプション設定ファイルを無視し、指定ファイルの [mysqld] グループからのみオプションを読み取る。

これらの原則は、--install-manual オプションを使用してサーバをインストールした場合にも当てはまります。

以上の情報に基づいて、複数のサービスをセットアップする方法はいくつかあります。 次に、いくつかの例を示します。いずれを試す場合でも、最初に既存の MySQL サービスをシャットダウンして削除しておくことが必要です。

  • 標準オプション設定ファイルの 1 つで、すべてのサービスにオプションを指定する。 これを行う場合は、各サーバに異なる名前を使用する。 たとえば、4.0.8 mysqld-ntmysqld1 のサービス名で実行し、4.0.17 mysqld-ntmysqld2 のサービス名で実行する場合、 4.0.8 には [mysqld1] グループを、4.0.17 には [mysqld2] グループを使用できる。 たとえば、以下のように C:\my.cnf をセットアップできる。

    # options for mysqld1 service
    [mysqld1]
    basedir = C:/mysql-4.0.8
    port = 3307
    enable-named-pipe
    socket = mypipe1
    
    # options for mysqld2 service
    [mysqld2]
    basedir = C:/mysql-4.0.17
    port = 3308
    enable-named-pipe
    socket = mypipe2
    

    Windows が各サービス用の正しい実行可能プログラムを登録できるように、サーバのフルパス名を指定して、以下のようにサービスをインストールする。

    shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
    shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
    

    サービスを開始するには、サービスマネージャを使用するか、適切なサービス名で NET START を使用する。

    shell> NET START mysqld1
    shell> NET START mysqld2
    

    サービスを停止するには、サービスマネージャを使用するか、適切なサービス名で NET STOP を使用する。

    shell> NET STOP mysqld1
    shell> NET STOP mysqld2
    

    注意: MySQL 4.0.17 より前のバージョンでは、デフォルトサービス名(MySQL)を使用してインストールされたサーバか、mysqld のサービス名で明示的にインストールされたサーバだけが、標準オプション設定ファイルの [mysqld] グループを読み取ります。4.0.17 以降では、他のサービス名を使用してインストールされたサーバでも、標準オプション設定ファイルを読み取るサーバであればすべて、[mysqld] グループを読み取ります。これにより、すべての MySQL サービスに適用するオプション用に [mysqld] グループを使用し、各サービスの名前が付けられたオプショングループを、そのサービス名でインストールされたサーバ用に使用できます。

  • 個別のファイルで各サーバにオプションを指定し、サービスのインストール時に --defaults-file を使用して、各サーバにどのファイルを使用するか指定する。このとき、各ファイルに [mysqld] グループを使用してオプションをリストアップすることが必要。

    この方法で 4.0.8 mysqld-nt のオプションを指定するには、以下のような C:\my-opts1.cnf ファイルを作成する。

    [mysqld]
    basedir = C:/mysql-4.0.8
    port = 3307
    enable-named-pipe
    socket = mypipe1
    

    4.0.17 mysqld-nt に対しては、以下のような C:\my-opts2.cnf ファイルを作成する。

    [mysqld]
    basedir = C:/mysql-4.0.17
    port = 3308
    enable-named-pipe
    socket = mypipe2
    

    以下のようにサービスをインストールする(各コマンドは 1 行で入力)。

    shell> C:\mysql-4.0.8\bin\mysqld-nt --install mysqld1
               --defaults-file=C:\my-opts1.cnf
    shell> C:\mysql-4.0.17\bin\mysqld-nt --install mysqld2
               --defaults-file=C:\my-opts2.cnf
    

    MySQL サーバをサービスとしてインストールする際に --defaults-file オプションを使用するには、オプションの前にサービス名を付ける必要がある。

    サービスのインストール後、起動と停止は前の例と同じように行う。

複数のサービスを削除するには、mysqld --remove を使用して 1 つずつ削除します。削除するサービスがデフォルト名でない場合は、--remove オプションの後にサービス名を指定します。

4.2.2. Unix 上で複数のサーバを実行する

複数のサーバを Unix 上で実行する最も簡単な方法は、異なる TCP/IP ポートとソケットファイルを使用するようにしてサーバをコンパイルし、それぞれが別のネットワークインタフェースで接続するようにすることです。また、各インストールを別々のベースディレクトリでコンパイルすることにより、データディレクトリ、ログファイル、および PID ファイルの場所をサーバ別にすることができます。

既存サーバがデフォルトのポート番号とソケットファイルでコンフィギャされているとします。新しいサーバを別のパラメータでコンフィギャするには、以下のように configure コマンドを使用します。

shell> ./configure --with-tcp-port=port_number \
             --with-unix-socket-path=file_name \
             --prefix=/usr/local/mysql-4.0.17

ここで、port_numberfile_name に、デフォルト以外のポート番号とソケットファイルのパス名を指定します。および、--prefix の値も、既存の MySQL インストールの場所とは別のインストールディレクトリを指定します。

MySQL サーバが特定のポート番号をリッスンしている場合、以下のコマンドを使用して、ベースディレクトリやソケット名など、重要な変数の値を確認できます。

shell> mysqladmin --host=host_name --port=port_number variables

このコマンドで表示される情報により、追加サーバを設定するときにどのオプション値を使用してはいけないかがわかります。

注意: ``localhost'' をホスト名として指定すると、mysqladmin は TCP/IP ではなく、Unix ソケット接続をデフォルト使用します。 MySQL 4.1 では、--protocol={TCP | SOCKET | PIPE | MEMORY} オプションを使用して、使用する接続プロトコルを明示的に指定できます。

別のソケットファイルおよび TCP/IP ポート番号で起動するために、新たに MySQL サーバをコンパイルする必要はありません。実行時に値を指定することも可能です。これを行う 1 つの方法として、コマンドラインオプションの使用があります。

shell> /path/to/mysqld_safe --socket=file_name --port=port_number

2 番目のサーバに別のデータベースディレクトリを使用するため、--datadir=path オプションを mysqld_safe に渡します。

同様の効果を得る別の方法として、環境変数を使用してソケット名とポート番号を設定することもできます。

shell> MYSQL_UNIX_PORT=/tmp/mysqld-new.sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
shell> scripts/mysql_install_db
shell> bin/mysqld_safe &

この方法を使用すると、テスト用に 2 つ目のサーバをすばやく起動できます。この方法の長所は、上記のシェルから呼び出したどのクライアントプログラムにもこの環境変数が適用される点です。そのため、これらのクライアントの接続は自動的に 2 つ目のサーバにダイレクトされます。

付録?F. 環境変数 に、mysqld を制御する他の環境変数の一覧が記載されています。

自動サーバ実行では、ブート時に実行されるスタートアップスクリプトにより、サーバごとに以下のコマンドが 1 回ずつ実行される必要があります。その際、各コマンドに対して適切なオプション設定ファイルのパスを設定します。

mysqld_safe --defaults-file=path-to-option-file

各オプション設定ファイルには、特定のサーバに固有のオプション値が含まれていることが必要です。

Unix では、mysqld_multi スクリプトを使用して複数のサーバを開始することもできます。 See 項4.8.3. 「mysqld_multi(複数の MySQL サーバを管理するプログラム)」

4.2.3. 複数サーバ環境でクライアントプログラムを使用する

クライアントにコンパイルされたネットワークインタフェース以外のネットワークインタフェースをリッスンしている MySQL サーバにそのクライアントから接続するには、以下のいずれかの方法を実行します。

  • TCP/IP 経由でリモートホストに接続する場合は --host=host_name --port=port_number でクライアントを開始する。Unix ソケットまたは Windows の名前付きパイプを使用してローカルホストに接続する場合は --host=localhost --socket=file_name でクライアントを開始する。

  • MySQL 4.1 では、TCP/IP 経由で接続する場合は --protocol=tcp を、Unix ソケットを使用する場合は --protocol=socket を、名前付きパイプを使用する場合は --protocol=pipe を、共有メモリを使用する場合には --protocol=memory を指定してクライアントを開始する。TCP/IP 接続では、--host オプションと --port オプションを指定することが必要な場合もある。他の接続タイプでは、場合によっては、--socket オプションでソケットまたは名前付きパイプ名を指定したり、--shared-memory-base-name オプションで共有メモリ名を指定することが必要になる。

  • Unix では、クライアントを起動する前に、MYSQL_UNIX_PORT 環境変数と MYSQL_TCP_PORT 環境変数を設定して Unix ソケットおよび TCP/IP ポート番号を指定する。 特定のソケットまたはポートを永続的に使用する場合、これらの環境変数を設定するコマンドを .login ファイルに置いて、ログインのたびにこれらの環境変数が適用されるようにできる。 See 付録?F. 環境変数

  • オプション設定ファイルの [client] グループにデフォルトソケットと TCP/IP ポートを指定する。たとえば、Windows では C:\my.cnf を、Unix ではホームディレクトリの .my.cnf ファイルを使用できる。 See 項4.1.2. 「my.cnf オプション設定ファイル」

  • C プログラムでは、ポートまたはソケット引数を mysql_real_connect() の呼び出しで指定できる。また、mysql_options() を呼び出して、プログラムにオプション設定ファイルを読み取らせることもできる。 See 項11.1.3. 「C API 関数の説明」

  • Perl DBD::mysql モジュールを使用している場合、MySQL オプション設定ファイルからオプションを読み取ることができる。次に例を示す。

    $dsn = "DBI:mysql:test;mysql_read_default_group=client;"
            . "mysql_read_default_file=/usr/local/mysql/data/my.cnf";
    $dbh = DBI->connect($dsn, $user, $password);
    

    See 項11.5.2. 「DBI インタフェース」

4.3. 一般的なセキュリティ関連事項と MySQL アクセス制御システム

MySQL には、非標準ですが、上級のセキュリティおよび権限システムがあります。このセクションでは、その機能について説明します。

4.3.1. 一般的なセキュリティガイドライン

インターネットに接続されたコンピュータで MySQL を使用するユーザはすべて、このセクションを読んで、頻発しているセキュリティ侵害を回避するようにしてください。

盗聴傍受、改ざん、再生、サービス妨害など、あらゆるタイプの攻撃に対して、MySQL サーバだけでなく、サーバホスト全体を、最大限の努力をもって保護することが必要です。ここでは、可用性および耐障害性のすべてについてはカバーしていません。

MySQL では、すべての接続、クエリなど、ユーザが実行する可能性のある操作に対して、そのセキュリティを、アクセス制御リスト(ACL)をベースにして保護しています。MySQL クライアントとサーバ間の SSL 暗号化接続もサポートしています。ここで説明する概念の多くは、MySQL 固有ではありません。ほとんどすべてのアプリケーションに当てはまります。

MySQL を実行する際には、可能な限り以下のガイドラインに従ってください。

  • mysql root ユーザ以外のだれにも mysql データベースの user テーブルへのアクセス権を与えないこと。これは非常に重要である。 MySQL では、暗号化されたパスワードが実際のパスワードである。 user テーブル内のリストに含まれているパスワードを知り得、そのアカウントのリストに含まれているホストに対するアクセス権を持つ者はだれでも、簡単にそのユーザとしてログインできる

  • MySQL アクセス権限システムを理解すること。MySQL へのアクセスを制御するには GRANT コマンドと REVOKE コマンドを使用する。必要以上の権限をユーザに設定しないこと。すべてのホストに対する権限は決して与えないこと。

    チェックリスト

    • mysql -u root を試す。パスワードなしでサーバに正常に接続できるようだと問題がある。この場合、すべての権限を持つ root ユーザとして、MySQL サーバに接続できるということである。 特に root パスワードの設定に関する項目に注意して、MySQL インストール手順を見直すこと。

    • SHOW GRANTS コマンドを使用して、だれが何にアクセスできるかをチェックする。REVOKE コマンドを使用して不要な権限を削除する。

  • データベースには、テキスト形式のパスワードを保存しないこと。コンピュータがクラックされたとき、パスワードの完全なリストが奪われて不正使用される結果になる。MD5()SHA1()、または別の一方向ハッシング関数を使用する。

  • 辞書を使用してパスワードを選択しない。特殊プログラムで解読されてしまう。``xfish98'' のようなパスワードも良くない。標準 QWERTY キーボードで ``fish'' を 1 列左でタイプした ``duag98'' などを推奨。また、``Mary had a little lamb'' の頭文字を取って ``Mhall'' とするのも良い。 この方法だと覚えやすく、また部外者が類推することも困難。

  • ファイアウォールに投資する。これにより、少なくとも 50% の攻撃を防ぐことができる。MySQL をファイアウォール内つまり非武装地帯に配置する。

    チェックリスト

    • nmap などのツールを使用して、インターネットから自分のポートをスキャンしてみる。MySQL はデフォルトでポート 3306 を使用する。このポートは、信頼されていないホストからアクセスできてはいけない。他にも、MySQL ポートが開いているかどうか確かめる簡単な方法として、リモートコンピュータから以下のコマンドを実行するという方法がある。ここで、server_host は MySQL サーバのホスト名である。

      shell> telnet server_host 3306
      

      接続できて意味不明な文字が返ればポートが開いている。開いておく正当な理由がない限り、ファイアウォールまたはルータで閉じておく。telnet がハングするか、接続が拒否されれば正常である。つまり、ポートは閉じている。

  • ユーザが入力するデータを信頼しないこと。Web フォーム、URL、その他のアプリケーションから特殊文字またはエスケープ文字シーケンスが入力され、不正操作が行われる可能性がある。ユーザが ``; DROP DATABASE mysql;'' などのような入力をしても、アプリケーションが安全に保たれるようにしなければならない。これは極端な例であるが予防策を講じておかないと、クラッカーによる同様の手段によって、重大なセキュリティリークやデータの紛失が発生する可能性がある。

    また、数値データもチェックすること。文字列だけを保護するのは、よくあるミスである。公開されているデータのみのデータベースは保護する必要がないという考えもよくある考えだが、これも間違っている。そのようなデータベースにも、サービス妨害タイプの攻撃が可能である。このタイプの攻撃を防ぐ最もシンプルな方法は、数値定数をアポストロフィで囲むこと。SELECT * FROM table WHERE ID=234 ではなく、SELECT * FROM table WHERE ID='234' のようにする。 MySQL は自動的のこの文字列を数値に変換し、非数値記号を削除する。

    チェックリスト

    • すべての Web アプリケーション

      • すべての Web フォームで ‘'’ および ‘"’ を入力してみる。何らかの MySQL エラーが発生した場合は、すぐにその問題を調べる。

      • URL で %22(‘"’)、%23(‘#’)、および %27(‘'’)を追加して動的 URL の修正を試みる。

      • 前の例の文字を含む動的 URL のデータ型を数値型から文字型に変更する。このような攻撃があってもアプリケーションが影響されないようにする。

      • 数値フィールドに数値ではなく、文字、スペース、および特殊記号を入力してみる。MySQL に渡すことなくアプリケーションがそれらの値を削除するか、エラーを生成することが必要である。値がチェックされずに MySQL に渡ると非常に危険である。

      • MySQL に渡す前にデータサイズをチェックする。

      • 管理目的で使用するユーザ名とは別のユーザ名で、アプリケーションをデータベースに接続させる。アプリケーションに、必要以上のアクセス権を設定しない。

    • PHP のユーザ

      • addslashes() 関数をチェックする。 PHP 4.0.3 より、mysql_escape_string() 関数が利用可能になっている。これは、MySQL C API の同じ名前の関数をベースにしている。

    • MySQL C API のユーザ

      • mysql_real_escape_string() API 呼び出しをチェックする。

    • MySQL++ のユーザ

      • クエリストリームの escape および quote の修飾子をチェックする。

    • Perl DBI のユーザ

      • quote() メソッドをチェックするか、プレースホルダを使用する。

    • Java JDBC のユーザ

      • PreparedStatement オブジェクトおよびプレースホルダを使用する。

  • インターネット上で暗号化されていないデータを送信しないこと。これらのデータは、悪意のある第三者によって盗聴され、悪用される可能性がある。SSL や SSH などの暗号化プロトコルを使用する。MySQL では、バージョン 4.0.0 より内部 SSL 接続をサポートしている。 SSH ポート転送を使用して、暗号化(および圧縮)された通信トンネルを作成できる。

  • tcpdump ユーティリティおよび strings ユーティリティの使用法を理解すること。ほとんどの場合、以下のようなコマンドで、MySQL データストリームが暗号化されているかどうかをチェックできる。

    shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
    

    これは、Linux システムで有効。他のシステムでも、少し修正するだけで使用できる。 警告: データを見ることができなくても、必ずしも実際に暗号化されているとは限らない。高度なセキュリティが必要な場合は、専門家に相談すること。

4.3.2. MySQL のクラッカー対策

MySQL サーバに接続するとき、通常はパスワードを使用します。パスワードはテキスト形式で送信されるわけではありませんが、暗号化アルゴリズムはそれほど強力なものではありません。クライアントとサーバ間のトラフィックを盗聴できれば、クラッカーは少しの努力でパスワードを探り当てることができます。クライアントとサーバ間の接続が信頼されていないネットワークを通る場合には、SSH トンネルを使用して通信を暗号化してください。

その他の情報はすべてテキストとして転送されるので、その接続を見ることができる人はだれでもそれらの情報を読むことができます。これに不安を感じる場合は、圧縮プロトコル(MySQL バージョン 3.22 以降)を使用してトラフィックの解読をより困難にすることができます。セキュリティをさらに高めるには、ssh を使用してください。オープンソースssh クライアントは http://www.openssh.org/ に、商用 ssh クライアントは http://www.ssh.com/ にあります。これを使用すると、MySQL サーバと MySQL クライアント間で暗号化 TCP/IP 接続を利用できます。

MySQL 4.0 を使用している場合、内部 OpenSSL サポートも利用できます。 See 項4.4.10. 「安全な接続の使用」

MySQL システムのセキュリティを確保するためには、以下の事項を強く推奨します。

  • すべての MySQL ユーザにパスワードを使用する。other_user にパスワードが設定されていなければ、だれでも mysql -u other_user db_name として簡単に他人になりすましてログインできる。クライアント/サーバ型のアプリケーションでは、クライアント側で任意のユーザ名を指定できるのが一般的。mysql_install_db スクリプトを実行前に編集することにより、すべてのユーザのパスワードを変更できる。また、MySQL root ユーザのパスワードのみ変更するには、以下のように行う。

    shell> mysql -u root mysql
    mysql> UPDATE user SET Password=PASSWORD('new_password')
        ->             WHERE user='root';
    mysql> FLUSH PRIVILEGES;
    
  • MySQL デーモンを Unix root アカウントで実行しないこと。このことは、FILE 権限のあるユーザであればだれでも root(たとえば ~root/.bashrc)としてファイルを作成できてしまうので、非常に危険である。これを防ぐため、--user=root オプションを使用して直接指定された場合を除き、mysqldroot として実行することを拒否するようになっている。

    mysqld は、普通の権限なしユーザとして実行できる。 新しい Unix アカウント mysql を作成してさらにセキュリティを高めることもできる。別の Unix アカウントで mysqld を実行する場合、user テーブル内の root ユーザ名を変更する必要はない。MySQL ユーザ名と Unix アカウント名はお互い関係ない。別の Unix アカウントで mysqld を開始するには、サーバのデータディレクトリにある my.cnf または /etc/my.cnf のオプション設定ファイルの [mysqld] グループに、アカウント名を指定する user 行を追加する。次に例を示す。

    [mysqld]
    user=mysql
    

    これで、サーバを手動で起動した場合も、mysqld_safe または mysql.server を使用して起動した場合でも、指定のアカウントでサーバが起動する。 詳細については、項A.3.2. 「一般ユーザで MySQL を実行する方法」 を参照のこと。

  • テーブルへのシンボリックリンクをサポートしない(これは --skip-symlink オプションで無効にできる)。このことは、rootmysqld を実行する場合、mysqld データディレクトリへの書き込み権限があるすべてのユーザが、システムのすべてのファイルを削除できることになるので、特に重要である。 See 項5.6.1.2. 「Unix 上のテーブルに対するシンボリックリンクの使用」

  • mysqld を実行する Unix アカウントだけに、データベースディレクトリの読み取り権限と書き込み権限があることを確認する。

  • PROCESS 権限をすべてのユーザには与えない。mysqladmin processlist の出力には、現在実行中のクエリのテキストが表示される。そのため、このコマンドを実行できるユーザは、UPDATE user SET password=PASSWORD('not_secure') クエリを実行する他のユーザを特定できる可能性がある。

    mysqld は、PROCESS 権限を持つユーザ用に特別接続枠を予約しているので、すべての通常接続が使用中の場合でも、MySQL root ユーザはログインしてサーバの状態をチェックできる。

  • FILE 権限をすべてのユーザには与えない。この権限を持つユーザは、mysqld デーモンの権限でファイルシステムのどの場所にでもファイルを書き込める。安全対策として、SELECT ... INTO OUTFILE で生成されるファイルについてはだれでも書き込み可能だが、既存のファイルには書き込めないようになっている。

    FILE 権限は、サーバを実行している Unix ユーザがアクセスできるすべての読み取り可能ファイルを読む場合にも使用される。また、ユーザが何らかの権限を持っているカレントデータベースに任意のファイルを読み込むことができる。 これは、不正使用される可能性がある。たとえば、LOAD DATA を使用して /etc/passwd をテーブルにロードし、SELECT で読むことができる。

  • DNS を信頼しない場合、権限テーブルで、ホスト名ではなく IP アドレスを使用すること。いずれにしても、ワイルドカードを含むホスト名を使用して権限テーブルを作成する際には特に注意が必要である。

  • 単一ユーザの接続数を制限する場合は、mysqldmax_user_connections 変数を設定する。

4.3.3. セキュリティ関連の mysqld スタートアップオプション

セキュリティに影響する mysqld オプションは以下のとおりです。

  • --local-infile[=(0|1)]

    --local-infile=0 を使用すると、LOAD DATA LOCAL INFILE を使用できなくなる。

  • --safe-show-database

    このオプションを使用すると、SHOW DATABASES コマンドで、そのユーザが何らかの権限を持っているデータベースのみが返される。 現在は、SHOW DATABASES 権限が存在するため、バージョン 4.0.2 以降、このオプションは廃止されており、何もしない(デフォルトで有効になっている)。 See 項4.4.1. 「GRANT および REVOKE の構文」

  • --safe-user-create

    このオプションが有効になっている場合、ユーザに mysql.user テーブルへの INSERT 権限がなければ、そのユーザは GRANT コマンドを使用して新規ユーザを作成できない。ユーザが事前設定された権限で新規ユーザを作成できるようにするには、そのユーザに以下の権限を設定することが必要である。

    mysql> GRANT INSERT(user) ON mysql.user TO 'user'@'hostname';
    

    これで、ユーザは権限カラムを直接変更できないが、GRANT コマンドを使用して他のユーザに権限を与えることができるようになる。

  • --skip-grant-tables

    サーバが権限システムをまったく使用しないようにする。これによりすべての人が、すべてのデータベースにフルアクセスできるようになる。実行中のサーバに権限テーブルを再び使用させるためには、mysqladmin flush-privilegesmysqladmin reload または FLUSH PRIVILEGES; を実行すればよい。

  • --skip-name-resolve

    ホスト名を解決しない。権限テーブルの Host カラム値はすべて IP アドレスか localhost でなければならない。

  • --skip-networking

    TCP/IP 経由の接続を認めない。mysqld への接続をすべて Unix ソケットで行う。 このオプションは、3.23.27 より前の MySQL バージョンで MIT-pthreads パッケージを利用しているものには適さない。その当時、Unix ソケットは MIT-pthreads によってサポートされていなかったからである。

  • --skip-show-database

    SHOW DATABASES 権限のないユーザに SHOW DATABASES コマンドの使用を認めない。バージョン 4.0.2 から、このオプションは必要なくなった。現在では、SHOW DATABASES 権限が割り当てられることでコマンドを使用できるようになっている。

4.3.4. LOAD DATA LOCAL のセキュリティ関連事項

MySQL 3.23.49 および MySQL 4.0.2(Windows では 4.0.13)で、LOAD DATA LOCAL に関するセキュリティ対策としていくつかの新しいオプションが追加されました。

このコマンドには次のような潜在的な問題が 2 つあります。

ファイルの読み取りがサーバ側から開始されるため、理論的には、改悪した MySQL サーバを作成しておけば、クライアントがテーブルに対してクエリを実行した時に、そのクライアントコンピュータ上に存在する全てのファイル(カレントユーザが読み取り権を持つ)を、改悪した MySQL サーバが読み取れるということになります。

クライアントが Web サーバから接続する Web 環境では、ユーザは LOAD DATA LOCAL を使用して、Web サーバプロセスが読み取りアクセス権を持つどのファイルでも読み取ることができます(ユーザが SQL サーバに対してすべてのコマンドを実行できる場合)。

これには 2 つの解決方法があります。

MySQL を --enable-local-infile でコンフィギャしていなければ、mysql_options(... MYSQL_OPT_LOCAL_INFILE, 0) を呼び出さないクライアントは LOAD DATA LOCAL を使用できません。 See 項11.1.3.40. 「mysql_options()

mysql コマンドラインクライアントに対しては、--local-infile[=1] オプションで LOAD DATA LOCAL を有効にでき、--local-infile=0 オプションで無効にできます。

デフォルトでは、すべての MySQL クライアントとライブラリが --enable-local-infile でコンパイルされ、MySQL 3.23.48 以前との互換性が保たれるようになっています。

MySQL サーバですべての LOAD DATA LOCAL コマンドを無効にするには、mysqld--local-infile=0 で開始します。

LOAD DATA LOCAL INFILE がサーバまたはクライアントで無効になっている場合、次のエラーメッセージ(1148)が表示されます。

The used command is not allowed with this MySQL version

4.3.5. 権限システムが行うこと

MySQL 権限システムは、主に、任意のホストから接続したユーザを認証し、そのユーザを、データベース上に登録されている権限(SELECTINSERTUPDATEDELETE)と関連付けます。

さらに、匿名ユーザを作成し、LOAD DATA INFILE や管理操作機能など MySQL 固有の機能を実行するための権限を設定します。

4.3.6. 権限システムはどのように機能するか

MySQL 権限システムは、すべてのユーザがそれぞれ許可された操作だけを実行できるようにします。MySQL サーバに接続すると、ユーザの ID は接続元のホストおよび指定したユーザ名によって特定されます。権限システムは、ユーザ ID と行いたい操作に応じて権限を設定します。

MySQL では、ホスト名とユーザ名を使用してユーザを認証します。1 つのユーザ名がインターネット上のどこででも同じユーザを示しているという保証がないためです。たとえば、office.com から接続したユーザ joe は、elsewhere.com から接続した joe と同一人物とは限りません。 MySQL では、同じユーザ名でも異なるホストから接続するユーザ間で区別することにより、このことを処理しています。joe に対して、office.com から接続した場合の権限セットと、elsewhere.com から接続した場合の権限セットを別々に設定できます。

MySQL のアクセス制御には 2 段階があります。

  • 段階 1: ユーザに接続する権限があるかどうかサーバがチェックする。

  • 段階 2: 接続できた場合、要求ごとにそれを実行できる権限があるかどうかサーバがチェックする。たとえば、データベースのあるテーブルからレコードを SELECT したり、データベースのテーブルを DROP しようとすると、ユーザにそのテーブルの SELECT 権限があるかどうか、あるいはデータベースの DROP 権限があるかどうかをサーバがチェックする。

注意: 接続中に権限が変更された場合(ユーザ自身または第三者によって)、必ずしもその変更は次のクエリに反映されません。詳細については、項4.4.3. 「権限の変更はいつ反映されるか」 を参照してください。

サーバはアクセス制御の両方の段階で、mysql データベースの userdbhost の各テーブルを使用します。これらの権限テーブルのフィールドを以下に示します。

テーブル名userdbhost
スコープフィールドHostHostHost
?UserDbDb
?PasswordUser?
権限フィールドSelect_privSelect_privSelect_priv
?Insert_privInsert_privInsert_priv
?Update_privUpdate_privUpdate_priv
?Delete_privDelete_privDelete_priv
?Index_privIndex_privIndex_priv
?Alter_privAlter_privAlter_priv
?Create_privCreate_privCreate_priv
?Drop_privDrop_privDrop_priv
?Grant_privGrant_privGrant_priv
?References_privReferences_privReferences_priv
?Reload_priv??
?Shutdown_priv??
?Process_priv??
?File_priv??
?Show_db_priv??
?Super_priv??
?Create_tmp_table_privCreate_tmp_table_privCreate_tmp_table_priv
?Lock_tables_privLock_tables_privLock_tables_priv
?Execute_priv??
?Repl_slave_priv??
?Repl_client_priv??
?ssl_type??
?ssl_cypher??
?x509_issuer??
?x509_cubject??
?max_questions??
?max_updates??
?max_connections??

アクセス制御の 2 段階目(要求確認)で、要求がテーブルに関連するものである場合、サーバがさらに tables_priv テーブルおよび columns_priv テーブルを参照することがあります。これらのテーブルのフィールドを以下に示します。

テーブル名tables_privcolumns_priv
スコープフィールドHostHost
?DbDb
?UserUser
?Table_nameTable_name
??Column_name
権限フィールドTable_privColumn_priv
?Column_priv?
その他のフィールドTimestampTimestamp
?Grantor?

各権限テーブルには、スコープフィールドと権限フィールドがあります。

スコープフィールドは、テーブルの各登録の範囲を特定します。たとえば、HostUser の値が 'thomas.loc.gov' および 'bob' である user テーブルエントリは、thomas.loc.gov ホストからサーバに接続しようとする bob を認証します。同様に、HostUserDb の各フィールドの値が 'thomas.loc.gov''bob'、および 'reports' である db テーブルエントリは、thomas.loc.gov ホストから reports データベースに接続しようとする bob を認証します。tables_priv テーブルおよび columns_priv テーブルには、各エントリに許可されているテーブルまたはテーブルとカラムの組み合わせを示すスコープフィールドが含まれています。

アクセスをチェックする目的において、Host 値は大文字と小文字の区別がありません。UserPasswordDb、および Table_name の値については大文字と小文字が区別されます。 Column_name 値は、MySQL バージョン 3.22.12 以降では大文字と小文字が区別されなくなっています。

権限フィールドは、テーブル内のエントリごとに設定されている権限、つまり何の操作を実行できるかを示します。サーバはさまざまな権限テーブルの情報を組み合わせて、ユーザの権限についての完全な記述を生成します。 この動作に適用されるルールについては、項4.3.10. 「アクセス制御の段階 2: 要求確認」 を参照してください。

スコープフィールドは文字列です。ここで示されているように、それぞれのデフォルト値は空の文字列です。

フィールド名注意
HostCHAR(60)?
UserCHAR(16)?
PasswordCHAR(16)?
DbCHAR(64)tables_priv テーブルおよび columns_priv テーブルでは CHAR(60)
Table_nameCHAR(60)?
Column_nameCHAR(60)?

userdbhost の各テーブルでは、すべての権限フィールドが ENUM('N','Y') として宣言されます。それぞれの値は 'N' または 'Y' で、デフォルト値は 'N' です。

tables_priv テーブルおよび columns_priv テーブルでは、権限フィールドは SET フィールドとして宣言されます。

テーブル名フィールド名設定可能な要素
tables_privTable_priv'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
tables_privColumn_priv'Select', 'Insert', 'Update', 'References'
columns_privColumn_priv'Select', 'Insert', 'Update', 'References'

以下、サーバが権限テーブルをどのように使用するか簡潔に説明します。

  • user テーブルのスコープフィールドにより、着信した接続を許可するか拒否するか決定する。許可された接続について、user テーブルに設定されている権限はいずれも、そのユーザのグローバル(スーパーユーザ)権限になる。 これらの権限は、サーバのすべてのデータベースに適用される。

  • db テーブルと host テーブルは一緒に使用される。

    • db テーブルのスコープフィールドにより、どのユーザがどのホストからどのデータベースにアクセスできるかを決定する。権限フィールドから、何の操作が許可されているか判断する。

    • host テーブルは、任意の db テーブルエントリをいくつかのホストに適用する場合、db テーブルを補完するものとして使用される。たとえば、1 人のユーザにネットワーク内のいくつかのホストからデータベースへアクセスすることを許可する場合、ユーザの db テーブルエントリの Host 値を空白のままにしておき、それらのホストの各エントリを host テーブルに入力する。このメカニズムの詳細については、項4.3.10. 「アクセス制御の段階 2: 要求確認」を参照のこと。

  • tables_priv テーブルおよび columns_priv テーブルは db テーブルに似ているが、より詳細な設定が可能。データベースレベルではなく、テーブルおよびカラムレベルで適用される。

注意: 管理者権限(RELOADSHUTDOWN など)は、user テーブルでのみ指定します。管理操作はデータベース固有ではなく、サーバそのもので行う操作なので、この権限を他の権限テーブルで設定する必要はありません。実際、管理操作を実行できるかどうか決定する際には、user テーブルを参照するだけで済みます。

FILE 権限も user テーブルだけで指定します。 これは管理者権限ではありませんが、サーバホスト上でのファイルの読み書きは、アクセスしているデータベースに依存しません。

mysqld サーバは権限テーブルの内容を、起動時に 1 回読み取ります。権限テーブルへの変更の反映については、項4.4.3. 「権限の変更はいつ反映されるか」 を参照してください。

権限テーブルの内容を変更する場合、その変更によって、目的の権限が適切に設定されていることを確認してください。問題診断のヘルプについては、項4.3.12. 「Access denied エラーの原因」 を参照してください。セキュリティに関するアドバイスについては、項4.3.2. 「MySQL のクラッカー対策」 を参照してください。

便利な診断ツールとして、mysqlaccess スクリプトがあります。これは、Yves Carlier が MySQL ディストリビューション用に提供したものです。このツールの動作を確認したい場合には、mysqlaccess--help オプションで起動してください。 注意: mysqlaccessuserdb、および host テーブルだけを使用してアクセスをチェックします。テーブルまたはカラムレベルの権限はチェックしません。

4.3.7. MySQL が提供する権限

ユーザ権限に関する情報は、mysql データベース(mysql という名前のデータベース)の userdbhosttables_privcolumns_priv の各テーブルに保存されています。MySQL サーバは起動時と、項4.4.3. 「権限の変更はいつ反映されるか」 で説明されている状況下において、これらのテーブルを読み取ります。

以下、このマニュアルで使用されている MySQL バージョン 4.0.2 提供の権限名を、それに関連付けられているテーブルカラム名およびその適用範囲とともに示します。各権限の意味については、項4.4.1. 「GRANT および REVOKE の構文」 を参照してください。

権限カラム適用範囲
ALTERAlter_privテーブル
DELETEDelete_privテーブル
INDEXIndex_privテーブル
INSERTInsert_privテーブル
SELECTSelect_privテーブル
UPDATEUpdate_privテーブル
CREATECreate_privデータベース、テーブル、またはインデックス
DROPDrop_privデータベースまたはテーブル
GRANTGrant_privデータベースまたはテーブル
REFERENCESReferences_privデータベースまたはテーブル
CREATE TEMPORARY TABLESCreate_tmp_table_privサーバ管理
EXECUTEExecute_privサーバ管理
FILEFile_privサーバ上のファイルアクセス
LOCK TABLESLock_tables_privサーバ管理
PROCESSProcess_privサーバ管理
RELOADReload_privサーバ管理
REPLICATION CLIENTRepl_client_privサーバ管理
REPLICATION SLAVERepl_slave_privサーバ管理
SHOW DATABASESShow_db_privサーバ管理
SHUTDOWNShutdown_privサーバ管理
SUPERSuper_privサーバ管理

SELECTINSERTUPDATEDELETE の各権限は、データベース上の既存テーブルのレコードに対する各操作を許可するものです。

SELECT ステートメントは、テーブルからレコードを実際に取り出す場合のみ、SELECT 権限が必要となります。サーバのデータベースへのアクセス権がなくても実行できる SELECT ステートメントもあります。たとえば、mysql クライアントをシンプルな計算機として使用するような場合です。

mysql> SELECT 1+1;
mysql> SELECT PI()*2;

INDEX 権限では、インデックスを作成または破棄(削除)できます。

ALTER 権限では、ALTER TABLE を使用できます。

CREATE および DROP 権限では、新規データベースおよびテーブルの作成、既存データベースおよびテーブルの破棄(削除)を行えます。

注意: ユーザに mysql データベースに対する DROP 権限を与えると、そのユーザは MySQL アクセス権限が保存されているデータベースを破棄できるということになるので注意が必要です。

GRANT 権限では、ユーザが所有している権限を他のユーザに与えることができます。

FILE 権限では、LOAD DATA INFILE および SELECT ... INTO OUTFILE ステートメントを使用してサーバ上でファイルの読み書きを行えます。この権限を与えられたユーザはだれでも、MySQL サーバによってアクセス可能な読み取り可能ファイルをすべて読むことができ、また MySQL サーバによって書き込めるどのディレクトリにも新規読み取り可能ファイルを作成できます。 このユーザはまた、カレントデータベースディレクトリ内のすべてのファイルを読むことができます。 ただし、既存ファイルの変更はできません。

これら以外の権限は、mysqladmin プログラムを使用して実行される管理操作用に使用されます。以下の表で、どの管理権限でどの mysqladmin コマンドを実行できるかを示します。

権限実行可能なコマンド
RELOADreloadrefreshflush-privilegesflush-hostsflush-logsflush-tables
SHUTDOWNshutdown
PROCESSprocesslist
SUPERkill

reload コマンドは、権限テーブルを再読み込みするようにサーバに命令します。refresh コマンドは、すべてのテーブルをフラッシュし、ログファイルを開いて閉じます。flush-privilegesreload のシノニムです。他の flush-* コマンドも refresh と同様の機能を果たしますが、範囲が限られており、状況によって使い分けてください。たとえば、ログファイルだけをフラッシュするには、refresh の代わりに flush-logs を使用します。

shutdown コマンドはサーバをシャットダウンします。

processlist コマンドは、サーバで実行中のスレッドに関する情報を表示します。kill コマンドはサーバスレッドを強制終了します。ユーザはいつでも自分のスレッドを表示および強制終了することができますが、他のユーザによって開始されたスレッドを表示するには PROCESS 権限が、強制終了するには SUPER 権限が必要です。 See 項4.6.7. 「KILL 構文」

一般的な指針として、ユーザにはそのユーザが必要とする権限だけを与えてください。また、以下の権限を与える際には注意が必要です。

  • GRANT 権限は、ユーザが自分の権限を他のユーザに与えることができる。2 人のユーザが異なる権限を持ち、両方とも GRANT 権限がある場合、お互いの権限を組み合わせることができる。

  • ALTER 権限は、テーブルの名前を変更することにより、権限システムを崩壊させることができる。

  • FILE 権限を悪用すれば、サーバの読み取り可能ファイルまたはカレントデータベースディレクトリのファイルをデータベーステーブルに読み込んで、SELECT を使用してその内容にアクセスできる。

  • SHUTDOWN 権限を悪用すれば、サーバを終了して、他のユーザへのサービス妨害を行うことができる。

  • PROCESS 権限は、パスワードの設定や変更を行うクエリなども含め、現在実行中のクエリのプレーンテキストを表示することができる。

  • mysql データベースの権限があれば、パスワードおよびその他のアクセス権限情報を変更することができる(パスワードは暗号化されて保存されているため、悪意のあるユーザが単に読み取ってもテキスト形式のパスワードを知ることはできない)。mysql.user パスワードカラムにアクセスできれば、それを使用して特定ユーザの MySQL サーバにログインできる(必要とされる権限を持っていれば、そのユーザはパスワードを書き換えることもできる)。

MySQL 権限システムでは達成できないこともいくつかあります。

  • 特定ユーザからのアクセスを拒否するよう明示的に指定できない。 つまり、ユーザを特定して、その接続を拒否することはできない。

  • データベース内のテーブルの作成および破棄の権限をユーザに与え、それと同時にデータベースの作成および破棄をできないようには指定できない。

4.3.8. MySQL サーバへの接続

MySQL クライアントでは通常、MySQL サーバにアクセスする際、接続先のホスト、ユーザ名、パスワードといった接続パラメータを指定する必要があります。たとえば、mysql クライアントは以下のように開始することができます(オプション引数は ‘[’ と ‘]’ で囲んであります)。

shell> mysql [-h host_name] [-u user_name] [-pyour_pass]

-h-u、および -p オプションの別の形として、--host=host_name--user=user_name、および --password=your_pass があります。注意: -p または --password= とそれに続くパスワードの間にスペースは入りません

注意: コマンドラインでパスワードを指定するのは安全ではありません。 同じシステム内のどのユーザでも、ps auxww のようなコマンドを使用してパスワードを知ることができてしまいます。 See 項4.1.2. 「my.cnf オプション設定ファイル」

mysql は、コマンドラインで指定されなかった接続パラメータに以下のデフォルト値を使用します。

  • デフォルトホスト名は localhost

  • デフォルトユーザ名はユーザの Unix ログイン名。

  • -p が指定されなければ、パスワードは無しになる。

したがって、Unix ユーザ joe では、以下のコマンドがいずれも同じ意味になります。

shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql

他の MySQL クライアントでも同様です。

Unix システムでは、接続時に別のデフォルト値を使用するように設定することができます。これにより、クライアントプログラムを起動するたびにコマンドラインで指定する必要がなくなります。設定方法は 2 つあります。

  • ホームディレクトリ内にある .my.cnf 設定ファイルの [client] セクションで接続パラメータを指定する。このセクションは以下のようになる。

    [client]
    host=host_name
    user=user_name
    password=your_pass
    

    See 項4.1.2. 「my.cnf オプション設定ファイル」

  • 環境変数を使用して接続パラメータを指定する。mysql のホストは、MYSQL_HOST を使用して指定できる。MySQL ユーザ名は、USER を使用して指定できる(Windows のみ)。パスワードは、MYSQL_PWD を使用して指定できる(ただし、これは安全ではない。次のセクションを参照のこと)。 See 付録?F. 環境変数

4.3.9. アクセス制御の段階 1: 接続確認

ユーザが MySQL サーバに接続しようとした場合、そのユーザ ID、およびそれを正しいパスワードで裏付けできるかどうかによって、サーバは接続の許可または拒否を行います。パスワードが正しくない場合、サーバはアクセスを完全に拒否します。正しければ、サーバは接続を許可し、段階 2 に進んで要求を待ちます。

ユーザ ID は、2 つの情報に基づきます。

  • 接続元のホスト

  • MySQL ユーザ名

ID チェックには、user テーブルの 3 つのスコープフィールド(HostUserPassword)が使用されます。user テーブルエントリが、指定されたホスト名とユーザ名に一致し、入力したパスワードが正しかった場合のみ、接続が許可されます。

user テーブルのスコープフィールドには次の方法で値を指定できます。

  • Host 値にはホスト名または IP アドレスを使用できる。ローカルホストを指定する場合は 'localhost' を使用する。

  • ワイルドカード文字 ‘%’ および ‘_’ を Host フィールドに使用できる。

  • Host 値としての '%' は、すべてのホスト名を意味する。

  • 空白の Host 値は、該当するホスト名に一致する host テーブルによって決定することを意味する。 詳細については、次の章を参照のこと。

  • MySQL バージョン 3.23 より、IP アドレスとして指定する Host 値に、ネットワークアドレスを示すためのネットマスクを使用できるようになっている。次に例を示す。

    mysql> GRANT ALL PRIVILEGES ON db.*
        -> TO david@'192.58.197.0/255.255.255.0';
    

    これにより、以下の条件に当てはまる IP からだれでも接続できるようになる。

    user_ip & netmask = host_ip.
    

    上の例では、192.58.197.0 ? 192.58.197.255 間の IP すべてが MySQL サーバに接続できる。

  • User フィールドにワイルドカード文字は使用できないが、空白の値は使用でき、これは任意のユーザ名と一致する。 user テーブルエントリに空白のユーザ名があり、接続が空白ユーザーにマッチした場合、そのユーザはクライアントが実際に指定した名前のユーザではなく、匿名ユーザ(名前なしのユーザ)と見なされる。この場合、接続中(段階 2 の間)に行われる後続のアクセスチェックはすべて、空白のユーザ名で行われる。

  • Password フィールドは空白にできる。これはどのパスワードにも一致するという意味ではなく、そのユーザがパスワード指定せずに接続する必要があるという意味である。

空白ではない Password 値は、暗号化パスワードを表します。 MySQL では、パスワードを平文テキストでは保存しません。接続しようとするユーザが入力したパスワードは、暗号化されます(PASSWORD() 関数を使用)。クライアントおよびサーバがパスワードの確認を行う際、その暗号化されたパスワードが使用されます(このとき、その接続を使って、暗号化されたパスワードが転送されることはありません)。注意: MySQL から見ると暗号化されたパスワードが実際のパスワードなので、暗号化パスワードにだれにもアクセスできないようにしてください。特に、一般のユーザに mysql データベース内のテーブルの読み取りアクセス権を与えないでください。 バージョン 4.1 より、MySQL は従来とは異なるパスワードおよびログインメカニズムを採用しており、TCP/IP パケットが盗み見されたり、mysql データベースがキャプチャされた場合でも安全になっています。

以下の例は、user テーブルエントリの Host 値および User 値のさまざまな組み合わせがどのように着信の接続に適用されるかを示したものです。

Host User エントリによって許可される接続
'thomas.loc.gov''fred'thomas.loc.gov から接続する fred
'thomas.loc.gov'''thomas.loc.gov から接続するすべてのユーザ
'%''fred'任意のホストから接続する fred
'%'''任意のホストから接続するすべてのユーザ
'%.loc.gov''fred'loc.gov ドメイン内の任意のホストから接続する fred
'x.y.%''fred'x.y.netx.y.comx.y.edu などから接続する fred(これは実用的ではない)
'144.155.166.177''fred'IP アドレス 144.155.166.177 のホストから接続する fred
'144.155.166.%''fred'144.155.166 クラス C サブネットの任意のホストから接続する fred
'144.155.166.0/255.255.255.0''fred'1 つ上の例と同じ

Host フィールドでは IP のワイルドカード値を使用できるので(たとえば、'144.155.166.%' で、サブネットのすべてのホストに一致)、ホストを 144.155.166.somewhere.com などと名付けてこの機能が悪用される可能性があります。これを防ぐため、MySQL は数値やドットで始まるホスト名を認めません。したがって、1.2.foo.com などのホスト名は、権限テーブルの Host カラムと決して一致しません。IP アドレスのみ IP ワイルドカード値との突き合わせが可能です。

ある接続が、user テーブルの複数のエントリと一致することがあります。たとえば、thomas.loc.gov からの fred による接続は、上記の表のいくつかのエントリと一致します。複数のエントリが一致した場合、サーバは次のようにエントリを選択します。起動時に user テーブルを読み込んだ後、それをソートします。ユーザが接続しようとしたとき、そのソート順でエントリとの突き合わせを行います。そして最初に一致したエントリを使用します。

user テーブルのソートは以下のように行われます。user テーブルが以下の内容であるとします。

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-

サーバがテーブルを読み込むと、最も具体的な Host 値を最初にもってきます(Host カラムの '%' は ``任意のホスト'' を意味し、具体性が低いとなります)。同じ Host 値のエントリ間で、最も具体的な User 値を最初にもってきます(空白の User 値は ``任意のユーザ'' を意味し、具体性が低いとなります)。ソートされた user テーブルは以下のようになります。

+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-

接続が試みられると、サーバはソートされたエントリで突き合わせを行い、最初に一致したものを使用します。localhost からの jeffrey による接続に対しては、Host カラムが 'localhost' のエントリが最初に一致します。これらのうち、空白ユーザ名のエントリが接続ホスト名とユーザ名の両方で一致します('%'/'jeffrey' エントリも一致しますが、これはテーブル内での最初の突き合わせにはなりません)。

もう 1 つ例を示します。user テーブルが以下の内容であるとします。

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-

ソートされたテーブルは以下のようになります。

+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-

thomas.loc.gov からの jeffrey による接続は最初のエントリと一致し、whitehouse.gov からの jeffrey による接続は 2 番目のエントリと一致します。

サーバが接続の突き合わせを行うとき、指定されたユーザ名を明示的に示すすべてのエントリが最初に使用されると誤解しがちです。これは間違っています。上記の例でもわかるように、thomas.loc.gov からの jeffrey による接続は、'jeffrey'User フィールド値であるエントリではなく、ユーザ名なしのエントリと最初に一致します。

サーバへの接続がうまくいかない場合、user テーブルを出力して、最初の突き合わせがどれか確認してください。 正常に接続が行われても、権限が予期したものと違う場合、CURRENT_USER() 関数(バージョン 4.0.6 で導入)を使用して、その接続に実際に一致しているユーザとホストの組み合わせを確認できます。 See 項6.3.6.2. 「その他の各種関数」

4.3.10. アクセス制御の段階 2: 要求確認

接続が確立すると、サーバは段階 2 に移行します。その接続での要求ごとに、サーバはユーザにそれを実行できる権限があるかどうかを、操作タイプに基づいてチェックします。ここで、権限テーブルの権限フィールドが関係してきます。権限は、userdbhosttables_privcolumns_priv のテーブルで設定できます。権限テーブルの設定は、GRANT コマンドと REVOKE コマンドで行います。 See 項4.4.1. 「GRANT および REVOKE の構文」。 各権限テーブルのフィールドのリストについては、項4.3.6. 「権限システムはどのように機能するか」 を参照してください。

user テーブルは、カレントデータベースに関係なく、ユーザに対してグローバルに権限を設定します。たとえば、user テーブルで DELETE 権限が設定されたユーザは、そのサーバホストのどのデータベースのレコードでも削除できます。つまり、user テーブルで許可された権限はスーパーユーザ権限です。user テーブルで権限を設定する対象は、サーバ管理者やデータベース管理者などのスーパーユーザだけにしておくのが賢明です。他のユーザについては、user テーブルの権限を 'N' に設定しておき、db テーブルおよび host テーブルを使用してデータベース依存で権限を設定してください。

db テーブルおよび host テーブルは、データベース依存の権限を設定します。 スコープフィールドには次の方法で値を指定できます。

  • ワイルドカード文字の ‘%’ および ‘_’ を、両テーブルの Host フィールドと Db フィールドで使用できる。たとえば、‘_’ 文字をデータベース名の一部として使用するには、GRANT コマンドで '\_' として指定する。

  • db テーブルの '%' Host 値は、``任意のホスト'' を意味する。db テーブルの空白の Host 値は、``host テーブルを参照すること'' を意味する。

  • host テーブルの '%' または空白の Host 値は、``任意のホスト'' を意味する。

  • 両テーブルにおいて '%' または空白の Db 値は、``任意のデータベース'' を意味する。

  • 両テーブルにおいて空白の User 値は、匿名ユーザを意味する。

db テーブルおよび host テーブルは、サーバ起動時に読み取られてソートされます(user テーブル読み込みと同時)。db テーブルは HostDb、および User のスコープフィールドでソートされ、host テーブルは HostDb のスコープフィールドでソートされます。user テーブルでは、最も具体的な値が最初に、最も抽象的な値が最後にソートされ、サーバによるエントリの突き合わせでは、最初に一致したエントリが使用されます。

tables_priv テーブルと columns_priv テーブルはそれぞれ、テーブル依存およびカラム依存の権限を設定します。スコープフィールドには次の方法で値を指定できます。

  • ワイルドカード文字の ‘%’ および ‘_’ を両テーブルの Host フィールドで使用できる。

  • 両テーブルにおいて '%' または空白の Host 値は、``任意のホスト'' を意味する。

  • 両テーブルの DbTable_nameColumn_name の各フィールドで、ワイルドカードおよび空白を使用できない。

tables_priv テーブルおよび columns_priv テーブルは、HostDb、および User のフィールドでソートされます。これは db テーブルのソートと同様ですが、ワイルドカードの使用が Host フィールドだけに限定されるので、よりシンプルです。

以下、要求確認プロセスについて説明します。アクセスチェックのソースコードを知っている読者は、ここでの説明とコードで使用されるアルゴリズムに少し違いがあることに気付かれるでしょうが、説明はコードが実際に行うことと同じで、違いは説明をシンプルにするためのものです。

管理要求(SHUTDOWNRELOAD など)に対して、サーバは user テーブルエントリだけをチェックします。管理権限を指定するのはこのテーブルのみであるためです。そのエントリが要求された操作を許可している場合はアクセスが認められ、そうでない場合は拒否されます。たとえば、mysqladmin shutdown を実行しようとしても、user テーブルエントリで SHUTDOWN 権限が設定されていなければ、db テーブルや host テーブルをチェックすることなくアクセスは拒否されます(これらのテーブルには Shutdown_priv カラムがなく、チェックの必要性がありません)。

データベース関連の要求(INSERTUPDATE など)に対しては、サーバは最初に、user テーブルエントリでユーザのグローバル(スーパーユーザ)権限をチェックします。ここで、要求されている操作が許可されていれば、アクセスが認められます。user テーブルのグローバル権限では十分でない場合、サーバはユーザのデータベースに関する権限を db テーブルおよび host テーブルでチェックします。

  1. サーバは、db テーブルの HostDbUser の各フィールドをチェックする。Host フィールドと User フィールドでは、接続ユーザのホスト名と MySQL ユーザ名がチェックされる。Db フィールドでは、ユーザがアクセスしようとしているデータベースがチェックされる。Host および User に該当するエントリがない場合、アクセスは拒否される。

  2. db テーブルに、マッチするエントリがあり、その Host フィールドが空白でなければ、そのエントリが、ユーザのデータベースに対する権限を定義する。

  3. db テーブルにある、マッチするエントリの Host フィールドが空白の場合、これは host テーブルが、データベースにアクセスできるホストを指定することを意味する。この場合、host テーブルの Host フィールドと Db フィールドがチェックされる。 host テーブル内にマッチするエントリがなければ、アクセスは拒否される。マッチするエントリがあれば、ユーザのデータベースに対する権限が、db および host テーブルエントリの(和集合ではなく)共通集合として計算される。これは、両方のエントリで 'Y' に設定されている権限を指す。このように、db テーブルエントリで全般的な権限を設定し、host テーブルエントリでホストごとに権限を制限することができる。

サーバは、db および host テーブルエントリからデータベースに対する権限を特定したら、それらの権限を user テーブルで設定されているグローバル権限に足し合わせます。その結果、要求されている操作が許可されていれば、アクセスが認められます。そうでない場合、サーバは tables_priv テーブルと columns_priv テーブルでユーザのテーブル権限とカラム権限をチェックし、これらをユーザの権限に追加します。その結果に基づき、アクセスが許可または拒否されます。

ブール値で表すと、上記のユーザ権限算出法は以下のようにまとめることができます。

グローバル権限
OR (database アクセス権 AND host アクセス権)
OR table アクセス権
OR column アクセス権

user 内のグローバル権限が十分ではない場合に、サーバがその不十分なグローバル権限を、データベース、テーブル、およびカラム権限と足し合わせる理由はわかりにくいかもしてません。 その理由は、要求に複数の権限が必要な場合があるからです。たとえば、INSERT ... SELECT ステートメントを実行するには、INSERT 権限および SELECT 権限の両方が必要です。 そのうち 1 つの権限が user テーブル内のエントリにあり、もう 1 つの権限が db テーブル内のエントリにある場合があります。その場合、要求を実行するのに必要な権限をユーザは持っていますが、サーバはどちらか一方のテーブルだけでは判断できません。この場合、両テーブルのエントリにある権限を組み合わせる必要があります。

host テーブルを使用して、セキュリティで保護されたサーバのリストを管理することができます。

TcX DataKonsult AB では、host テーブルに、ローカルネットワーク上のすべてのコンピュータの一覧を入れています。これらにすべての権限を設定しています。

host テーブルを使用して、セキュリティで保護されていないホストを示すこともできます。 セキュリティで保護されていない公開エリア内に、コンピュータ public.your.domain があるとします。以下のように、host テーブルのエントリを使用して、ネットワーク内のそのコンピュータ以外の全ホストにアクセスを許可することができます。

+--------------------+----+-
| Host               | Db | ...
+--------------------+----+-
| public.your.domain | %  | ... (全権限を 'N' にセット)
| %.your.domain      | %  | ... (全権限を 'Y' にセット)
+--------------------+----+-

当然、権限テーブルは常にテストして(mysqlaccess などを使用)、アクセス権限が目的どおりに設定されていることを確認してください。

4.3.11. MySQL 4.1 のパスワードハッシュ

MySQL ユーザアカウントは、mysql データベースの user テーブルにリストアップされています。各 MySQL アカウントにはパスワードが割り当てられますが、user テーブルの Password カラムに保存されるのは平文テキストのパスワードではなく、パスワードから計算されたハッシュ値です。パスワードハッシュ値は、PASSWORD() 関数によって計算されます。

MySQL は、クライアントとサーバ間通信の 2 つのフェーズでパスワードを使用します。

  • まず、クライアントがサーバに接続しようとするとき、初期認証ステップとして、クライアントはパスワードを提示する。このパスワードは、クライアントが使用を希望するアカウントの、ユーザテーブルに保存されたハッシュ値と一致している必要がある。

  • 次に、クライアントが接続した後、クライアントは、user テーブルに含まれているパスワードハッシュを設定または変更することができる(適切な権限がある場合)。このためには、クライアントは、PASSWORD() 関数を使用してパスワードハッシュを生成するか、GRANT または SET PASSWORD ステートメントを使用する。

つまり、クライアントが最初に接続しようとする際、サーバが認証するのにハッシュ値を使用します。接続したクライアントが PASSWORD() 関数を実行したり、GRANT または SET PASSWORD ステートメントを使用してパスワードの設定または変更を行うと、サーバがハッシュ値を生成します。

パスワードハッシュメカニズムは MySQL 4.1 で更新され、セキュリティが向上し、パスワード盗難の危険性が少なくなっています。 ただし、この新しいメカニズムは 4.1 サーバと 4.1 クライアントしか理解できないため、互換性の問題があります。 4.1 クライアントはパスワードハッシュの新旧メカニズムの両方を理解できるので、4.1 より前のサーバにでも接続できます。しかし、4.1 より前のクライアントが 4.1 サーバに接続しようとすると、問題が発生する可能性があります。たとえば、4.0 mysql クライアントが 4.1 サーバに接続しようとすると、以下のエラーメッセージが表示される可能性があります。

shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client

以下、以前のパスワードメカニズムと新しいパスワードメカニズムとの違い、およびサーバを 4.1 にアップグレードしたときに 4.1 より前のクライアントと互換性を保つ方法について説明します。

注意: ここでの説明は 4.1 とそれ以前の動作を対比するものですが、ここで説明する 4.1 の動作は実際には 4.1.1 からのものです。MySQL 4.1.0 の動作は、4.1.1 以降で導入されたメカニズムと少し異なります。4.1.0 とそれ以降のバージョンとの違いについては、後で説明します。

MySQL 4.1 より前は、PASSWORD() 関数によって計算されるパスワードハッシュは 16 バイト長でした。次に例を示します。

mysql> SELECT PASSWORD('mypass');
+--------------------+
| PASSWORD('mypass') |
+--------------------+
| 6f8c114b58f2ce9e   |
+--------------------+

MySQL 4.1 より前は、user テーブルの Password カラム(ハッシュが保存される場所)も 16 バイト長でした。

MySQL 4.1 から、PASSWORD() 関数が、より長い 41 バイトのハッシュ値を生成するようになっています。

mysql> SELECT PASSWORD('mypass');
+-----------------------------------------------+
| PASSWORD('mypass')                            |
+-----------------------------------------------+
| *43c8aa34cdc98eddd3de1fe9a9c2c2a9f92bb2098d75 |
+-----------------------------------------------+

したがって、この長さの値を保存するため、user テーブルの Password カラムも 41 バイト長であることが必要です。

  • MySQL 4.1 の新規インストールを実行すると、Password カラムは自動的に 41 バイト長になる。

  • 旧バージョンを 4.1 にアップグレードした場合、mysql_fix_privilege_tables スクリプトを実行して Password カラムを 16 バイト長から 41 バイト長に変更する必要がある。このスクリプトは既存のパスワード値を変更しない。既存のものは 16 バイト長のままである。

拡張された Password カラムは、新旧どちらの形式のパスワードハッシュも保存できます。与えられたパスワードハッシュ値の形式は次の 2 つの違いにより判断されます。

  • 16 バイトと 41 バイトという長さ自体が違う。

  • 2 つ目の違いとしては、新しい形式のパスワードハッシュは常に ‘*’ 文字で始まり、旧形式のパスワードはそれ以外の文字で始まる。

長いパスワードハッシュ形式の方が暗号化の面で優れており、クライアント認証において旧形式の短いハッシュよりもセキュリティが高いと言えます。

パスワードハッシュの長短の違いは、認証時にサーバがパスワードを使用する方法と、パスワードを変更する接続クライアントに対してサーバがパスワードハッシュを生成する方法に関係してきます。

認証時にサーバがパスワードを使用する方法は、Password カラムの幅により次のような影響を受けます。

  • カラムが短い場合、短いハッシュ認証だけが使用される。

  • カラムが長い場合、長短のハッシュどちらでも保存でき、サーバはどちらの形式でも使用できる。

    • 4.1 より前のクライアントは接続はできても、旧ハッシュメカニズムしか理解できないため、短いハッシュのアカウントしか認証できない。

    • 4.1 クライアントは、長短どちらのハッシュのアカウントでも認証できる。

短いハッシュのアカウントでも、4.1 クライアントの方が旧クライアントよりも認証プロセスのセキュリティが少し向上しています。認証のセキュリティは以下の順で高くなります。

  • 短いパスワードハッシュのアカウントに対する 4.1 より前のクライアント認証

  • 短いパスワードハッシュのアカウントに対する 4.1 クライアント認証

  • 長いパスワードハッシュのアカウントに対する 4.1 クライアント認証

接続クライアントに対してサーバがパスワードハッシュを生成する方法は、Password カラムの幅と --old-passwords オプションにより影響を受けます。4.1 サーバは、次の条件が満たされた場合だけ、長いハッシュを生成します。 Password カラムが長いハッシュ値を保存できる長さであること、および --old-passwords オプションが指定されていないことが必要です。 これらの条件は以下のように適用されます。

  • Password カラムが長いハッシュを保存できる長さ(41 バイト)であること。 カラムが更新されておらず、4.1 より前の長さ(16 バイト)のままだと、クライアントが PASSWORD()GRANT、または SET PASSWORD を使用してパスワード変更操作を行ったとき、長いハッシュが収まらないことをサーバが認識し、短いハッシュを生成する (4.1 にアップグレードしたが、mysql_fix_privilege_tables スクリプトを実行せず、Password カラムが長くなっていない場合にこのようになる)。

  • Password カラムが長ければ、長短どちらのパスワードハッシュも保存できる。この場合、サーバが --old-passwords オプションで起動されていなければ、PASSWORD()GRANT、および SET PASSWORD により長いハッシュが生成される。 このオプションが指定されていると、強制的に短いパスワードハッシュが生成される。

--old-passwords オプションの目的は、サーバが長いパスワードハッシュを生成する環境において、4.1 より前のクライアントと下位互換性を保てるようにすることです。これは認証には影響しませんが(4.1 クライアントは長いパスワードハッシュのアカウントを使用できる)、パスワード変更操作の結果として user テーブルで長いパスワードハッシュが生成されることを防ぎます。長いパスワードハッシュが生成されると、そのアカウントは 4.1 より前のクライアントでは使用できなくなります。--old-passwords オプションを指定しない場合、以下のシナリオが想定されます。

  • 旧クライアントが、短いパスワードハッシュのアカウントに接続する。

  • クライアントがアカウントのパスワードを変更する。--old-passwords が指定されていない場合、アカウントに対して長いパスワードハッシュが生成される。

  • 次回、旧クライアントがこのアカウントに接続しようとしても、認証時にアカウントが新規ハッシュメカニズムを必要とするため、接続できない。user テーブルでアカウントに対して長いパスワードハッシュが生成された場合、4.1 クライアントのみそれを認証できる。4.1 より前のクライアントでは長いハッシュを理解できない。

このシナリオでは、4.1 より前の旧クライアントをサポートする必要がある場合、--old-passwords オプションを使用せずに 4.1 サーバを起動するのは危険であることを示しています。--old-passwords を指定してサーバを起動することにより、パスワード変更操作を行っても長いパスワードハッシュは生成されません。したがって、旧クライアントがアカウントにアクセスできなくなることがありません(旧クライアントが、パスワード変更時、偶発的に長いパスワードハッシュを生成して自らをロックアウトすることはありません)。

--old-passwords オプションの欠点は、4.1 クライアントでも、パスワード作成または変更時に短いハッシュを使用するということです。そのため、長いパスワードハッシュによる高いセキュリティを活用できません。4.1 クライアント用などに長いハッシュのアカウントを作成したい場合には、--old-passwords なしでサーバを実行する必要があります。

4.1 サーバの実行には以下のシナリオが想定されます。

シナリオ 1. user テーブルの短い Password カラム

  • Password カラムには短いハッシュのみ保存できる。

  • サーバはクライアント認証時、短いハッシュだけを使用する。

  • 接続クライアントは、PASSWORD()GRANT、または SET PASSWORD を使用するパスワードハッシュ生成操作で短いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず短いパスワードハッシュになる。

  • --old-passwords オプションは使用できるが、意味がない。短い Password カラムでは、サーバは短いパスワードハッシュしか生成しない。

シナリオ 2. 長い Password カラム、サーバを --old-passwords オプションなしで起動

  • Password カラムには長短いずれのハッシュも保存できる。

  • 4.1 クライアントは、長短どちらのハッシュのアカウントでも認証できる。

  • 4.1 より前のクライアントは、短いハッシュのアカウントのみ認証できる。

  • 接続クライアントは、PASSWORD()GRANT、または SET PASSWORD を使用するパスワードハッシュ生成操作で長いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず長いパスワードハッシュになる。

  • OLD_PASSWORD() を使用して、明示的に短いハッシュを生成するようにできる。たとえば、アカウントに短いパスワードを割り当てるには、以下のように UPDATE を使用する。

    mysql> UPDATE user SET Password = OLD_PASSWORD('mypass')
        -> WHERE Host = 'some_host' AND User = 'some_user';
    mysql> FLUSH PRIVILEGES;
    

上述したように、このシナリオでは、短いパスワードハッシュのアカウントに、4.1 より前のクライアントがアクセスできなくなる危険性があります。GRANTSET PASSWORD、または PASSWORD() を使用してアカウントのパスワードを変更すると、新規パスワードハッシュが長くなるため、4.1 より前のクライアントは、4.1 にアップグレードしないとそのアカウントを認証できなくなります。

シナリオ 3. 長い Password カラム、サーバを --old-passwords オプションで起動

  • Password カラムには長短いずれのハッシュも保存できる。

  • 4.1 クライアントは長短いずれのハッシュのアカウントでも認証できる(注意: 長いハッシュの作成は、サーバを --old-passwords なしで起動したときだけ可能)。

  • 4.1 より前のクライアントは、短いハッシュのアカウントのみ認証できる。

  • 接続クライアントは、PASSWORD()GRANT、または SET PASSWORD を使用するパスワードハッシュ生成操作で短いハッシュだけを使用する。アカウントのパスワードを変更すると、必ず短いパスワードハッシュになる。

このシナリオでは、--old-passwords によって長いハッシュが生成されないため、長いパスワードハッシュのアカウントを作成できません。また、--old-passwords オプションを使用する前に長いハッシュのアカウントを作成した場合でも、--old-passwords の有効時にアカウントのパスワードを変更すると短いパスワードになってしまうので、長いハッシュが持つセキュリティ上の利点が失われます。

これらのシナリオの欠点はそれぞれ以下のように要約できます。

シナリオ 1. セキュリティの高い認証を提供する長いハッシュを活用できない。

シナリオ 2. OLD_PASSWORD() を使用せずにパスワードを変更すると、短いハッシュのアカウントに 4.1 より前のクライアントがアクセスできなくなる。

シナリオ 3. --old-passwords によって、短いハッシュのアカウントがアクセス不能になることは防がれるが、長いハッシュをパスワード変更すると短いハッシュになってしまい、--old-passwords が有効な間はそれを元の長さに戻せない。

アプリケーションプログラムに対するパスワードハッシュ変更の影響

MySQL 4.1 にアップグレードすると、独自の目的で PASSWORD() を使用してパスワードを生成するアプリケーションとの互換性に問題が生じます。本来、PASSWORD() は MySQL ユーザのパスワード管理専用なので、アプリケーションでこれを実行すべきではありません。しかし現状では、いくつかのアプリケーションが独自の目的で PASSWORD() を使用しています。4.1 にアップグレードし、長いパスワードハッシュが生成される状態でサーバを実行すると、独自の目的で PASSWORD() を使用するアプリケーションは壊れます。推奨される対処法は、アプリケーションを修正して SHA1() または MD5() など、別の関数を使用してハッシュ値を生成するように設定することです。 それが可能でなければ、OLD_PASSWORD() 関数を使用することができます。これは、旧形式の短いハッシュを生成するためのものです(注意: ただし、OLD_PASSWORD() は将来サポートされなくなる可能性があります)。

短いハッシュを生成する状態でサーバが実行中の場合、OLD_PASSWORD() は利用可能ですが、PASSWORD() と同じになります。

MySQL 4.1.0 のパスワードハッシュは 4.1.1 以降のパスワードハッシュと異なります。 4.1.0 の違いは以下のとおりです。

  • パスワードハッシュは 41 バイトではなく、45 バイト長である。

  • PASSWORD() 関数は繰り返し不可。つまり、特定の引数 X で、連続して PASSWORD(X) を呼び出すと異なる結果が生成される。

4.3.12. Access denied エラーの原因

MySQL サーバに接続しようとして Access denied エラーが発生した場合の対処法を、以下に示します。

  • MySQL のインストール後、mysql_install_db スクリプトを実行して権限テーブルを初期設定していなければ、これを行う。 See 項4.4.4. 「MySQL 権限の初期設定」。 以下のコマンドを実行して初期権限をテストする。

    shell> mysql -u root test
    

    エラーが発生することなく接続できるはずである。また、MySQL データベースディレクトリに user.MYD ファイルがあることを確認する。 通常、これは PATH/var/mysql/user.MYD である。ここで PATH は、MySQL インストール先ディレクトリのパス名である。

  • 初期インストール後、サーバに接続してユーザとそのアクセス権をセットアップする。

    shell> mysql -u root mysql
    

    MySQL root ユーザには、最初パスワードがないため、問題なく接続できるはずである。これはセキュリティ上のリスクでもあるため、他の MySQL ユーザをセットアップするとき、同時に root パスワードも設定すべきである。

    root として接続しようとして以下のエラーが表示された場合

    Access denied for user: '@unknown' to database mysql
    

    これは、user テーブルの User カラムに 'root' 値がなく、mysqld がクライアントのホスト名を解決できないことを意味する。この場合、--skip-grant-tables オプションでサーバを再起動し、/etc/hosts ファイルまたは \windows\hosts ファイルを編集してホストのエントリを追加する必要がある。

  • 以下のエラーが発生した場合

    shell> mysqladmin -u root -pxxxx ver
    Access denied for user: 'root@localhost' (Using password: YES)
    

    入力したパスワードが正しくないことを意味する。 See 項4.4.8. 「パスワードの設定」

    root のパスワードを忘れた場合、--skip-grant-tables オプションで mysqld を再起動してパスワードを変更できる。 See 項A.4.2. 「忘れたルートパスワードをリセットする方法」

    パスワードを指定していないにもかかわらず上記のエラーが発生する場合、何らかの my.cnf ファイルに正しくないパスワードが存在していることを意味する。See 項4.1.2. 「my.cnf オプション設定ファイル」。 以下のように --no-defaults オプションを使用すると、オプション設定ファイルの使用を避けることができる。

    shell> mysqladmin --no-defaults -u root ver
    
  • 既存の MySQL インストールを、バージョン 3.22.11 より前からバージョン 3.22.11 以降にアップグレードした後で、mysql_fix_privilege_tables スクリプトを実行していなければ、これを実行する。GRANT ステートメントが導入された MySQL バージョン 3.22.11 では、権限テーブルの構造が変更されている。 See 項2.5.6. 「権限テーブルのアップグレード」

  • セッション途中で権限が変更されているようであれば、スーパーユーザが変更した可能性がある。権限テーブルを再読み込みすると、新しいクライアント接続に影響し、また、項4.4.3. 「権限の変更はいつ反映されるか」 で説明されているように、既存の接続にも影響する。

  • パスワードが機能しない場合に INSERTUPDATE、または SET PASSWORD ステートメントを使用してパスワードを設定する際には PASSWORD() 関数を使用することが必要である。GRANT ... IDENTIFIED BY ステートメントまたは mysqladmin password コマンドを使用してパスワードを指定する場合には、PASSWORD() 関数は不要である。 See 項4.4.8. 「パスワードの設定」

  • localhost は、ユーザのローカルホスト名のシノニムである。また、ホストを明示的に指定せずにクライアントが接続しようとした場合のデフォルトホストでもある。ただし、MIT-pthread を使用するバージョン 3.23.27 より前の MySQL を使用している場合、localhost への接続は行われない(localhost 接続は Unix ソケットを使用して行われるが、これは当時の MIT-pthread にはサポートされていなかった)。このようなシステムでこの問題を回避するには、--host オプションを使用してサーバホストを明示的に指定する。これにより、mysqld サーバへの TCP/IP 接続が行われる。この場合、サーバホストの user テーブルエントリに実際のホスト名があることが必要である(これは、サーバと同じホスト上でクライアントプログラムを実行している場合も同様である)。

  • mysql -u user_name db_name でデータベースに接続しようとして Access denied エラーが発生する場合、user テーブルに問題がある可能性がある。mysql -u root mysql を実行し、以下の SQL ステートメントを実行して、これをチェックする。

    mysql> SELECT * FROM user;
    

    この結果に、使用コンピュータのホスト名および MySQL ユーザ名とマッチする Host カラムおよび User カラムのエントリが含まれていなければならない。

  • Access denied エラーメッセージには、ログインしようとしているユーザ名、接続元のホスト、およびパスワードを使用したかどうかが示される。通常、エラーメッセージで表示されたホスト名とユーザ名に完全にマッチするエントリが 1 つ、user テーブルに存在していなければならない。Using password: NO を含むエラーメッセージが表示された場合、パスワードなしでログインしようとしたことを意味する。

  • MySQL サーバを実行しているホスト以外のホストから接続しようとして以下のエラーが発生する場合、そのホストと一致するレコードが user テーブルにないということである。

    Host ... is not allowed to connect to this MySQL server
    

    これを解決するには、コマンドラインツール mysql をサーバホスト上で使用して、userdb、または host テーブルに、接続しようとしているユーザとホスト名の組み合わせのレコードを追加し、mysqladmin flush-privileges を実行する。 実行している MySQL がバージョン 3.22 ではなく、接続しようとしているコンピュータの IP アドレスまたはホスト名がわからない場合、user テーブルの Host カラムに '%' を設定し、サーバマシン上で --log オプションを使用して mysqld を再起動する。クライアントマシンから接続を試行すると、MySQL ログの情報により、実際の接続がどのように行われたかわかる。次に、user テーブルエントリの '%' の値を、ログで表示された実際のホスト名に置き換える。そうしないと、システムのセキュリティを保てない。

    Linux 上でこの問題が発生した場合、考えられる他の原因としては、使用している glibc とは違うバージョンの glibc でコンパイルされたバイナリ MySQL バージョンを使用していることが挙げられる。この場合、OS/glibc をアップグレードするか、ソース MySQL バージョンをダウンロードして自分でコンパイルする。ソース RPM は通常、コンパイルおよびインストールが簡単なので、これは大きな問題ではない。

  • ホスト名で接続しようとしたにもかかわらず、エラーメッセージにホスト名が表示されない、またはホスト名が IP で表示される場合

    shell> mysqladmin -u root -pxxxx -h some-hostname ver
    Access denied for user: 'root@' (Using password: YES)
    

    これは、IP からホスト名に逆引きしようとしたときに MySQL でエラーが発生したことを意味する。この場合、mysqladmin flush-hosts を実行して内部 DNS キャッシュをリセットすることができる。 See 項5.5.5. 「MySQL の DNS の使用」

    恒久的な解決方法

    • DNS サーバでの問題点を見つけ、それを修正する。

    • MySQL 権限テーブルで、ホスト名の代わりに IP を指定する。

    • --skip-name-resolve オプションで mysqld を開始する。

    • --skip-host-cache オプションで mysqld を開始する。

    • 同じマシン上でサーバとクライアントを実行している場合は、localhost に接続する。

    • /etc/hosts にクライアントマシン名を記入する。

  • mysql -u root test は正常終了するのに mysql -h your_hostname -u root test では Access denied となる場合、user テーブルに正しいホスト名がない可能性がある。 通常、このような場合、user テーブルエントリの Host 値が完全修飾されていないホスト名を指定し、システムの名前解決ルーチンが完全修飾されたドメイン名を返している(またはその逆)。 たとえば、user テーブルにホスト 'tcx' のエントリがあるが、DNS に MySQL にホスト名として 'tcx.subnet.se' を指示した場合、これは機能しない。この場合、Host カラム値としてホストの IP アドレスを持つ user テーブルエントリを追加してみる。または、Host 値として 'tcx.%' などのワイルドカードを含む user テーブルエントリを追加することもできる。ただし、‘%’ で終わるホスト名の使用は、安全ではないので、推奨できない

  • mysql -u user_name test は正常終了するのに、mysql -u user_name other_db_name ではエラーが発生する場合、db テーブルに other_db_name のエントリがない。

  • サーバマシンでは mysql -u user_name db_name が動作するのに、別のクライアントマシンでは mysql -h host_name -u user_name db_name が動作しない場合、user テーブルまたは db テーブルにクライアントマシンが登録されていない。

  • Access denied の原因がわからない場合は、user テーブルから Host 値にワイルドカードが含まれているエントリ(‘%’ または ‘_’ を含むエントリ)をすべて削除する。 よくある間違いは、Host='%' および User='some user' の新規エントリを挿入し、これで、同一マシンから接続する際には localhost を指定できると考えていることである。これがうまくいかない理由は、デフォルト権限として、Host='localhost' および User='' のエントリが含まれているためである。Host 値が 'localhost' の場合、'%' よりも具体的なため、localhost からの接続時に新しいエントリよりもデフォルト権限が優先される。正しい指定の方法は、Host='localhost' および User='some_user' の 2 つ目のエントリを挿入するか、Host='localhost' および User='' のエントリを削除することである。

  • 以下のエラーが発生した場合、db テーブルまたは host テーブルに問題がある可能性がある。

    Access to database denied
    

    db テーブルの Host カラムに空白値がある場合、その db テーブルエントリに対してホストを指定するエントリが 1 つ以上、host テーブルに存在していることを確認する。

    SQL コマンド SELECT ...INTO OUTFILE または LOAD DATA INFILE 使用時にエラーが発生する場合、user テーブルの該当エントリで FILE 権限が有効化されていないと考えられる。

  • クライアントプログラムは、オプション設定ファイルまたは環境変数で指定された接続パラメータを使用する。See 付録?F. 環境変数。 コマンドラインで接続パラメータを指定しなかったときに、クライアントが間違ったデフォルトの接続パラメータを送っているようであれば、ホームディレクトリの .my.cnf ファイルおよび環境変数を確認する。システムレベルの MySQL オプション設定ファイルも確認できるが、ここでクライアント接続パラメータが指定されている可能性は低い。See 項4.1.2. 「my.cnf オプション設定ファイル」。 クライアントをオプションなしで実行して Access denied が発生する場合、オプション設定ファイルに古いパスワードが指定されていないか確認する。 See 項4.1.2. 「my.cnf オプション設定ファイル」

  • 権限テーブルを(INSERT または UPDATE ステートメントを使用して)直接変更した場合、その変更は無視されたように見えることがある。サーバに権限テーブルを再読み込みさせるには、FLUSH PRIVILEGES ステートメントを発行するか mysqladmin flush-privileges コマンドを実行する必要がある。このことを行わない場合、変更は次回のサーバ再起動時まで有効とならない。UPDATE コマンドで root パスワードを設定しても、権限をフラッシュするまでは、パスワードが変更されたことをサーバがまだ認識しないため、そのパスワードを指定する必要はない。

  • Perl、PHP、Ruby、Python、または ODBC プログラムでアクセスに問題があった場合、mysql -u user_name db_name または mysql -u user_name -pyour_pass db_name を使用して接続してみる。mysql クライアントを使用して接続できる場合、問題はプログラムにあり、アクセス権限にはない。 注意: -p とパスワードの間にスペースは入れない。また、--password=your_pass 構文を使用してパスワードを指定することもできる。-p オプションだけを使用した場合、パスワードが要求される。

  • テスト用に、--skip-grant-tables オプションで mysqld デーモンを開始する。次に MySQL 権限テーブルを変更し、変更によって意図した結果が得られているかどうか mysqlaccess スクリプトを使用してチェックできる。変更が意図したとおりであれば、mysqladmin flush-privileges を実行し、新しい権限テーブルを使用して起動するように mysqld サーバに指示する。注意: 権限テーブルを再読み込みすると、--skip-grant-tables オプションが無効になる。これにより、サーバをシャットダウンして再起動することなく、権限テーブルの使用を始めることができる。

  • 上記のいずれでもうまくいかない場合は、デバッグオプション(--debug=d,general,query など)で mysqld デーモンを開始する。試された接続に関するホスト情報、ユーザ情報、および発行された各コマンドに関する情報が出力される。 See 項E.1.2. 「トレースファイルの作成」

  • MySQL 権限テーブルに関するその他の問題が発生し、その旨メーリングリストに投稿する場合は、MySQL 権限テーブルのダンプも必ず提供すること。mysqldump mysql コマンドを使用すれば権限テーブルをダンプできる。問題を投稿するときは、必ず mysqlbug スクリプトを使用すること。See 項1.7.1.3. 「バグまたは問題を報告する方法」mysqldump を実行する際、--skip-grant-tablesmysqld を再起動することが必要な場合もある。

4.4. MySQL のユーザ管理

4.4.1. GRANT および REVOKE の構文

GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    TO user_name [IDENTIFIED BY [PASSWORD] 'password']
        [, user_name [IDENTIFIED BY [PASSWORD] 'password'] ...]
    [REQUIRE
        NONE |
        [{SSL| X509}]
        [CIPHER cipher [AND]]
        [ISSUER issuer [AND]]
        [SUBJECT subject]]
    [WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # |
                          MAX_UPDATES_PER_HOUR # |
                          MAX_CONNECTIONS_PER_HOUR #]]

REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    FROM user_name [, user_name ...]

GRANT は、MySQL バージョン 3.22.11 以降で実装されています。それより前の MySQL バージョンでは、GRANT ステートメントは何もしません。

システム管理者は、GRANT コマンドと REVOKE コマンドを使用して、ユーザを作成し、MySQL ユーザに対して次の 4 つのレベルの権限を与えたり取り消すことができます。

  • グローバルレベル

    グローバル権限は特定のサーバ上のすべてのデータベースに適用される。これらの権限は、mysql.user テーブルに保存される。 GRANT ALL ON *.* および REVOKE ALL ON *.* は、グローバル権限の付与および取り消しのみを行う。

  • データベースレベル

    データベース権限は、指定したデータベースのすべてのテーブルに適用される。これらの権限は、mysql.db テーブルおよび mysql.host テーブルに保存される。 GRANT ALL ON db.* および REVOKE ALL ON db.* は、データベース権限の付与および取り消しのみを行う。

  • テーブルレベル

    テーブル権限は、指定したテーブルのすべてのカラムに適用される。これらの権限は、mysql.tables_priv テーブルに保存される。 GRANT ALL ON db.table および REVOKE ALL ON db.table は、テーブル権限の付与および取り消しのみを行う。

  • カラムレベル

    カラム権限は、指定したテーブルの一つのカラムに適用される。これらの権限は、mysql.columns_priv テーブルに保存される。 REVOKE を使用する際は、対象となるカラムを指定することが必要である。

GRANT および REVOKE ステートメントの priv_type には以下のいずれかを指定できます。

ALL [PRIVILEGES]WITH GRANT OPTION 以外のすべての権限を設定
ALTERALTER TABLE の使用を許可
CREATECREATE TABLE の使用を許可
CREATE TEMPORARY TABLESCREATE TEMPORARY TABLE の使用を許可
DELETEDELETE の使用を許可
DROPDROP TABLE の使用を許可
EXECUTEストアドプロシージャの使用を許可(MySQL 5.0)
FILESELECT ... INTO OUTFILE および LOAD DATA INFILE の使用を許可
INDEXCREATE INDEX および DROP INDEX の使用を許可
INSERTINSERT の使用を許可
LOCK TABLESSELECT 権限を持つテーブルで LOCK TABLES の使用を許可
PROCESSSHOW FULL PROCESSLIST の使用を許可
REFERENCES将来のために予約
RELOADFLUSH の使用を許可
REPLICATION CLIENTスレーブおよびマスタのサーバーを知る権利を付与
REPLICATION SLAVEレプリケーションのスレーブに必要(マスタからバイナリログを読み取るため)
SELECTSELECT の使用を許可
SHOW DATABASESSHOW DATABASES によりすべてのデータベースが表示される
SHUTDOWNmysqladmin shutdown の使用を許可
SUPER最大接続数に達していても接続を 1 つだけ許可し、コマンド CHANGE MASTERKILL threadmysqladmin debugPURGE MASTER LOGS、および SET GLOBAL の実行を許可
UPDATEUPDATE の使用を許可
USAGE``権限なし'' のシノニム
GRANT OPTIONWITH GRANT OPTION のシノニム

USAGE を使用すると、権限なしのユーザを作成できます。

CREATE TEMPORARY TABLESEXECUTELOCK TABLESREPLICATION ...SHOW DATABASES、および SUPER は、バージョン 4.0.2 で新しく導入された権限です。4.0.2 にアップグレードした後でこれらの権限を使用するには、mysql_fix_privilege_tables スクリプトを実行する必要があります。 See 項2.5.6. 「権限テーブルのアップグレード」

古い MySQL バージョンでは、PROCESS 権限が新しい SUPER 権限と同じ働きをします。

ユーザの GRANT 権限を取り消すには、次のように priv_type 値として GRANT OPTION を使用します。

mysql> REVOKE GRANT OPTION ON ... FROM ...;

テーブルに対して指定できる priv_type 値は、SELECTINSERTUPDATEDELETECREATEDROPGRANT OPTIONINDEX、および ALTER だけです。

カラムに対して指定できる(つまり、column_list 節を使用する場合の)priv_type 値は、SELECTINSERT、および UPDATE だけです。

MySQL では、データベースが存在しない場合でもデータベースレベルの権限を作成でき、データベース使用の準備を行えます。 ただし現在のところ、テーブルが存在しない場合にはテーブルレベルの権限は作成できません。テーブルやデータベースを破棄した場合でも、MySQL が自動的に権限を取り消すことはありません。

グローバル権限は ON *.* 構文を使用して設定できます。データベース権限は ON db_name.* 構文を使用して設定できます。ON * を指定したときにカレントデータベースがあれば、そのデータベースの権限が設定されます。警告: ON * を指定したときにカレントデータベースがなければ、グローバル権限に影響します。

注意: GRANT コマンドでデータベース名を指定する際、‘_’ および ‘%’ ワイルドカードを使用できます。データベース名の一部として、たとえば ‘_’ 文字を使用したい場合、GRANT コマンドでは GRANT ... ON `foo\_bar`.* TO ... などのように、'\_' として指定するようしてください。そうしないと、ワイルドカードパターンに一致する別のデータベースにもユーザがアクセスできるようになります。

MySQL では、任意のホストのユーザに権限を付与できるように、user_name 値を user@host 形式で指定できるようになっています。特殊文字(‘-’ など)を含む user 文字列を指定したり、特殊文字またはワイルドカード文字(‘%’ など)を含む host 文字列を指定したい場合、ユーザ名またはホスト名を引用符で囲むことができます(たとえば、'test-user'@'test-hostname')。

ホスト名にワイルドカードを使用できます。たとえば、user@'%.loc.gov'loc.gov ドメインのどのホストの user にも当てはまり、user@'144.155.166.%'144.155.166 クラス C のどのホストの user にも当てはまります。

シンプルな形式 useruser@"%" のシノニムです。

MySQL では、ユーザ名でのワイルドカード使用をサポートしていません。匿名ユーザの定義には、User='' のエントリを mysql.user テーブルに挿入するか、GRANT コマンドで空白名のユーザを作成します。

注意: 匿名ユーザが MySQL サーバに接続できるようにする場合、すべてのローカルユーザに対して、user@localhost として権限を設定する必要があります。そうしないと、ユーザがローカルマシンから MySQL サーバにログインしようとしたときに、mysql.user テーブルのローカルホストの匿名ユーザエントリが使用されるからです。

これを確認するには、以下のクエリを実行します。

mysql> SELECT Host,User FROM mysql.user WHERE User='';

現在のところ、GRANT ではホスト、テーブル、データベース、およびカラムの名前に最大 60 文字まで使用できます。ユーザ名は最大 16 文字までです。

テーブルまたはカラムに対する権限は、4 つのレベルの権限の論理和(OR)で形成されます。たとえば、mysql.user テーブルでユーザにグローバル SELECT 権限が設定されている場合、これがデータベース、テーブル、またはカラムレベルのエントリで拒否されることはありません。

カラムに対する権限は以下のように計算されます。

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

多くの場合、ユーザへの権限設定には権限レベルを 1 つだけしか使用しないので、上述のように複雑にはなりません。権限チェックプロシージャの詳細については、項4.3. 「一般的なセキュリティ関連事項と MySQL アクセス制御システム」 を参照してください。

mysql.user テーブルに存在しないユーザとホスト名の組み合わせに権限を付与すると、そのエントリはテーブルに追加され、DELETE コマンドで削除されるまでそこに残ります。つまり、GRANTuser テーブルエントリを作成できますが、REVOKE ではそのエントリを削除できません。削除するには明示的に DELETE を使用する必要があります。

MySQL バージョン 3.22.12 以降では、新規ユーザが作成された場合、またはグローバル権限を付与する場合、IDENTIFIED BY 節でパスワードが指定されていれば、それがそのユーザのパスワードになります。すでにユーザにパスワードがある場合は、新しいパスワードに置き換えられます。

テキスト形式でパスワードを送信するのが望ましくなければ、PASSWORD オプションを使用して、SQL 関数 PASSWORD() または C API 関数 make_scrambled_password(char *to, const char *password) で生成した暗号化パスワードを設定できます。

警告: 新規ユーザを作成した際、IDENTIFIED BY 節を指定しなければそのユーザはパスワードなしになります。つまり、危険です。

パスワードの設定には、SET PASSWORD コマンドを使用することもできます。 See 項5.5.6. 「SET 構文」

データベースに対する権限を設定する場合、必要に応じて mysql.db テーブルにエントリが作成されます。REVOKE でそのデータベースのすべての権限が削除されると、このエントリも削除されます。

ユーザがテーブルに何の権限も持っていない場合、SHOW TABLES ステートメントなどでテーブルのリストを要求しても、テーブルは表示されません。SHOW DATABASES でも同様です。

WITH GRANT OPTION 節を使用すると、ユーザは自分が所有する権限を他のユーザに与えることができます。 GRANT 権限をユーザに設定する際は注意が必要です。2 人のユーザがお互いの権限を組み合わせることが可能になるからです。

MAX_QUERIES_PER_HOUR #MAX_UPDATES_PER_HOUR #、および MAX_CONNECTIONS_PER_HOUR # は MySQL バージョン 4.0.2 で新しく導入されました。 これらのオプションは、1 時間でユーザが実行できるクエリ、更新、およびログインの回数を制限します。# が 0(デフォルト)の場合、そのユーザに制限はないということです。 See 項4.4.7. 「ユーザリソースの制限」。 注意: 既存ユーザに追加権限を設定することなくこれらのオプションを指定するには、GRANT USAGE ON *.* ... WITH MAX_... を使用します。

自分自身が持っていない権限を他のユーザに与えることはできません。GRANT 権限では、自分が所有する権限だけを他のユーザに与えることができます。

あるレベルの GRANT 権限をユーザに設定すると、そのユーザがそのレベルで所有する(および将来所有する)すべての権限を、そのユーザは他のユーザに設定できるということに注意してください。 あるユーザにデータベースに対する INSERT 権限を付与したと仮定します。次にデータベースの SELECT 権限を付与する際 WITH GRANT OPTION を指定した場合、そのユーザは SELECT 権限だけでなく INSERT 権限も他のユーザに与えることができます。さらにデータベースの UPDATE 権限をそのユーザに与えると、そのユーザは INSERTSELECT、および UPDATE 権限を他のユーザに与えることができるようになります。

ALTER 権限は一般ユーザには付与しないでください。設定すると、そのユーザはテーブルの名前を変更して、権限システムを破ることができるようになります。

注意: 1 人のユーザだけにテーブル権限またはカラム権限を設定した場合でも、サーバはすべてのユーザのテーブル権限とカラム権限を調べるため、MySQL の処理速度は少し低下します。

mysqld の起動時、すべての権限がメモリに読み込まれます。 データベース権限、テーブル権限、およびカラム権限はすぐに反映されますが、ユーザレベルの権限はユーザが次回接続したときに有効となります。 GRANT または REVOKE によって行われた権限テーブルへの変更については、サーバは即座に認識します。 INSERTUPDATE などを使って手動で権限テーブルを変更した場合、FLUSH PRIVILEGES ステートメントまたは mysqladmin flush-privileges を実行してサーバに権限テーブルを再読み込みさせる必要があります。 See 項4.4.3. 「権限の変更はいつ反映されるか」

GRANT の標準 SQL のバージョンと MySQL バージョンでの最大の違いは以下のとおりです。

  • MySQL の権限は、ユーザ名のみではなく、ユーザ名とホスト名の組み合わせで指定される。

  • SQL-99 にはグローバル権限およびデータベースレベルの権限がなく、MySQL がサポートするタイプの権限すべてをサポートしない。 MySQL は、SQL-99 の TRIGGER 権限と UNDER 権限をサポートしない。

  • SQL-99 権限は、階層的に構成されている。あるユーザを削除すると、そのユーザに設定されているすべての権限が取り消される。MySQL では、設定された権限が自動的に取り消されることはなく、必要な場合は自分で取り消す必要がある。

  • MySQL では、テーブルの一部のカラムで INSERT 権限が設定されている場合、そのテーブルに対して INSERT ステートメントを実行できる。この場合、INSERT 権限のないカラムにはデフォルト値が設定される。SQL-99 では、すべてのカラムで INSERT 権限が必要となる。

  • SQL99 でテーブルを破棄すると、そのテーブルのすべての権限が取り消される。 SQL-99 では、1 つの権限を取り消すと、その権限をベースとするすべての権限も取り消される。MySQL で権限を破棄するには、明示的に REVOKE コマンドを使用するか MySQL 権限テーブルを操作することが必要である。

REQUIRE の使用法については、項4.4.10. 「安全な接続の使用」 を参照してください。

4.4.2. MySQL のユーザ名とパスワード

MySQL でのユーザ名およびパスワードの使用法と、Unix および Windows での使用法にはいくつかの相違点があります。

  • MySQL で認証目的に使用するパスワードは、Unix ユーザ名(ログイン名)や Windows ユーザ名とは関係ない。ほとんどの MySQL クライアントはデフォルトで、現在の Unix ユーザ名を MySQL ユーザ名としてログインしようとするが、これは利便性のためだけである。 クライアントプログラムで、-u オプションまたは --user オプションにより別の名前を指定することが可能である。これは、すべての MySQL ユーザ名にパスワードを設定しないと、データベースを安全に保てないことを意味する。パスワードを設定しなければ、だれでも任意の名前でサーバへの接続を試みることができ、パスワードのない名前を指定すれば接続に成功してしまう。

  • MySQL ユーザ名には最大 16 文字まで使用できるが、Unix ユーザ名は通常 8 文字まで。

  • MySQL パスワードは、Unix パスワードと関係ない。Unix マシンにログインするパスワードと、そのマシンでデータベースにアクセスするためのパスワードには関連性がない。

  • MySQL では、Unix ログインプロセスで使用されるアルゴリズムとは別のアルゴリズムで、パスワードを暗号化する。PASSWORD() 関数および ENCRYPT() 関数の詳細については、項6.3.6.2. 「その他の各種関数」 を参照のこと。注意: パスワードが '暗号化' されて格納されていても、その '暗号化' されたパスワードを知るだけで MySQL サーバに接続できる。 バージョン 4.1 より、MySQL は従来とは異なるパスワードとログインメカニズムを採用しており、TCP/IP パケットがスニフされたり、mysql データベースがキャプチャされた場合でもセキュリティを保持できるようになっている。

MySQL ユーザおよびその権限は通常、GRANT コマンドで作成します。 See 項4.4.1. 「GRANT および REVOKE の構文」

MySQL サーバにコマンドラインクライアントでログインする場合は、--password=your-password でパスワードを指定してください。 See 項4.3.8. 「MySQL サーバへの接続」

mysql --user=monty --password=guess database_name

クライアントにパスワードを要求させたい場合には、引数なしで --password を使用します。

mysql --user=monty --password database_name

または次の短い形式

mysql -u monty -p database_name

注意: 上記の例で、パスワードが 'database_name' なわけではありません

-p オプションを使用してパスワードを指定するには、以下のように行います。

mysql -u monty -pguess database_name

システムによっては、MySQL がパスワードを要求する際のライブラリコールにより、自動的にパスワードが 8 文字に切り詰められます。MySQL の内部では、パスワード長に制限はありません。

4.4.3. 権限の変更はいつ反映されるか

mysqld の起動時、すべての権限テーブルがメモリに読み込まれ、この時点で有効となります。

GRANTREVOKE、または SET PASSWORD を使用して行った権限テーブルの変更は、すぐにサーバに認識されます。

INSERTUPDATE などを使用して手動で権限テーブルを変更した場合、FLUSH PRIVILEGES ステートメント、mysqladmin flush-privileges、または mysqladmin reload を実行してサーバに権限テーブルを再読み込みさせる必要があります。そうしなければ、サーバを再起動するまで、変更は反映されません。権限テーブルを手動で変更した後、権限の再読み込みを忘れると、当然変更は反映されません。

サーバが権限テーブルの変更を認識すると、既存のクライアント接続は以下のような影響を受けます。

  • テーブル権限とカラム権限の変更は、クライアントの次回の要求から反映される。

  • データベース権限の変更は、次回の USE db_name コマンドから反映される。

  • グローバル権限の変更およびパスワードの変更は、クライアントの次回の接続から反映される。

4.4.4. MySQL 権限の初期設定

MySQL のインストール後、scripts/mysql_install_db を実行してアクセス権限を初期設定します。 See 項2.3.1. 「クイックインストールの概要」mysql_install_db スクリプトは mysqld サーバを起動し、以下の権限を含むように権限テーブルを初期化します。

  • MySQL root ユーザが、すべての操作を実行できるスーパーユーザとして作成される。接続は、ローカルホストから行う必要がある。

    注意: 初期状態では、root パスワードは空白のため、だれでも root ユーザとしてパスワードなしで接続でき、すべての権限を得られる。

  • 'test' という名前のデータベース、または 'test_' で始まる名前のデータベースにおいてすべての操作を実行できる匿名ユーザが作成される。接続は、ローカルホストから行う必要がある。どのローカルユーザでもパスワードなしで接続でき、その場合、匿名ユーザとして扱われることを意味する。

  • その他の権限は拒否される。たとえば、一般ユーザは mysqladmin shutdownmysqladmin processlist を使用できない。

注意: Windows のデフォルト権限とは異なります。 See 項2.1.1.8. 「Windows での MySQL の実行」

初期インストール時はアクセスが開放されている状態なので、インストール後はまず、MySQL root ユーザにパスワードを設定してください。これは以下のように行います(注意: PASSWORD() 関数を使用してパスワードを指定します)。

shell> mysql -u root mysql
mysql> SET PASSWORD FOR root@localhost=PASSWORD('new_password');

'new_password' に、使用するパスワードを指定します。

方法を理解していれば、権限テーブルを直接操作することもできます。

shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('new_password')
    ->     WHERE user='root';
mysql> FLUSH PRIVILEGES;

mysqladmin コマンドを使用しても、パスワードを設定できます。

shell> mysqladmin -u root password new_password

mysql データベースの書き込み権限および更新権限のあるユーザだけが、他のユーザのパスワードを変更できます。すべての一般ユーザ(匿名ユーザ以外)は、上記のコマンドまたは SET PASSWORD=PASSWORD('new_password') を使用して自分のパスワードだけを変更できます。

注意: UPDATE を使用して user テーブルで直接パスワードを更新する場合、FLUSH PRIVILEGES を使用してサーバに権限テーブルを再読み込みさせる必要があります。そうしないと変更が認識されません。

root パスワードをいったん設定するとそれ以降、root としてサーバに接続する際は常にそのパスワードを入力する必要があります。

追加設定やテストを行っている最中にパスワードを入力しないで済むように、root パスワードを空白のままにしたい場合もあるでしょう。しかし、実稼動で使用する前には必ずパスワードを設定してください。

デフォルト権限の設定については、scripts/mysql_install_db スクリプトを参照してください。このスクリプトは、他のユーザを追加する際にその基本として使用できます。

上記の初期権限とは違う初期権限を設定したい場合には、mysql_install_db を編集してから実行してください。

権限テーブルを完全に再生成するには、mysql データベースが含まれるディレクトリ内の .frm.MYI、および .MYD ファイルをすべて削除します(このディレクトリは、データディレクトリの下にある mysql という名前のディレクトリです。データディレクトリは mysqld --help を実行すると表示されます)。そして、必要に応じて権限を編集してから、mysql_install_db スクリプトを実行します。

注意: MySQL バージョン 3.22.10 より前では、.frm ファイルを削除しないでください。うっかり削除してしまった場合は、mysql_install_db を実行する前に、MySQL ディストリビューションからコピーし直してください。

4.4.5. MySQL への新規ユーザの追加

ユーザの追加には、2 つの方法があります。GRANT ステートメントを使用する方法と、MySQL 権限テーブルを直接操作する方法です。正確でエラーが発生しにくい GRANT ステートメントの使用を推奨します。 See 項4.4.1. 「GRANT および REVOKE の構文」

ユーザの作成および管理に使用できるコントリビューションプログラムもいくつかあります(phpMyAdmin など)。

以下の例では、mysql クライアントを使用して新規ユーザを設定する方法を示します。この例では、前のセクションで説明したデフォルト設定に従って権限がセットアップされていることを前提にしています。そのため変更を行うには、mysqld を実行しているマシンにログインしていること、MySQL root ユーザとして接続していること、root ユーザに mysql データベースに対する INSERT 権限と RELOAD 管理者権限があることが必要条件となります。また、root ユーザパスワードを変更している場合、ここで、mysql コマンドを使用してそのパスワードを指定する必要があります。

まず、mysql プログラムを使用してサーバに MySQL root ユーザとして接続します。

shell> mysql --user=root mysql

次に、GRANT ステートメントを実行して新規ユーザを追加できます。

mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@'%'
    ->     IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
mysql> GRANT USAGE ON *.* TO dummy@localhost;

これらの GRANT ステートメントでは、以下の 3 人の新規ユーザが追加されます。

  • monty

    どこからでもサーバに接続できる完全なスーパーユーザ。ただし、パスワード 'some_pass' の使用が必要。注意: GRANT ステートメントを monty@localhostmonty@"%" の両方に対して発行することが必要である。localhost のエントリを追加しないと、ローカルホストから接続したとき、mysql_install_db によって作成された localhost のエントリの方が、Host フィールド値がより具体的であり、user テーブルのソート順序で上位になるため優先されることになる。

  • admin

    localhost からパスワードなしで接続でき、RELOAD および PROCESS の管理権限のあるユーザ。このユーザは、mysqladmin reloadmysqladmin refreshmysqladmin flush-* の各コマンド、および mysqladmin processlist を実行できる。データベースレベルの権限は設定されていない(GRANT ステートメントを実行して後で追加できる)。

  • dummy

    パスワードなしでローカルホストからのみ接続できるユーザ。権限は設定されていない。USAGE 権限タイプにより、このような権限なしのユーザを作成できる。これは、すべてのグローバル権限を 'N' に設定するのと同じことである。これは、後でこのアカウントに固有の権限を設定することを想定している。

INSERT ステートメントを発行してサーバに権限テーブルを再度読み込ませることにより、同じユーザアクセス情報を直接追加することもできます。

shell> mysql --user=root mysql
mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('some_pass'),
    ->          'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user VALUES('%','monty',PASSWORD('some_pass'),
    ->          'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
    ->           Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
    ->                  VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;

MySQL バージョンによっては、上記 'Y' 値の数が違う場合があります(3.22.11 より前のバージョンでは権限カラムが少なく、4.0.2 以降では多くなります)。admin ユーザに対しては、バージョン 3.22.11 以降で利用可能になった SET を使用する拡張 INSERT 構文が使用されています。

注意: スーパーユーザを設定する場合は、権限フィールドを 'Y' に設定した user テーブルエントリを作成するだけで済みます。db テーブルや host テーブルのエントリは必要ありません。

最後の INSERT ステートメント(dummy ユーザ)では、user テーブルレコードの HostUser、および Password カラムだけが値を割り当てられています。権限カラムはどれも明示的に設定されていないため、MySQL はこれらすべてにデフォルト値の 'N' を設定します。これは、GRANT USAGE と同じ機能です。

以下の例では、ユーザ custom を追加します。このユーザは bankaccount データベースにはローカルホストからのみ、expenses データベースにはホスト whitehouse.gov からのみ、customer データベースにはホスト server.domain からのみアクセスできるとします。3 つのホストすべてでパスワード obscure を使用します。

GRANT ステートメントを使用してこのユーザの権限を設定するには、以下のコマンドを実行します。

shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON bankaccount.*
    ->     TO custom@localhost
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON expenses.*
    ->     TO custom@'whitehouse.gov'
    ->     IDENTIFIED BY 'obscure';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
    ->     ON customer.*
    ->     TO custom@'server.domain'
    ->     IDENTIFIED BY 'obscure';

権限テーブルを直接変更してユーザの権限を設定するには、以下のコマンドを実行します(注意: 最後の FLUSH PRIVILEGES に注目)。

shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('localhost','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('whitehouse.gov','custom',PASSWORD('obscure'));
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('server.domain','custom',PASSWORD('obscure'));
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES
    -> ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES
    -> ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
    -> (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
    ->  Create_priv,Drop_priv)
    -> VALUES('server.domain','customer','custom','Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;

INSERT ステートメントを使用した前の例と同様、MySQL のバージョンによっては 'Y' の値の数が異なります。

最初の 3 つの INSERT ステートメントは user テーブルエントリを追加し、ユーザ custom がさまざまなホストから指定のパスワードで接続できるようにしますが、権限については何も設定していません(権限はすべて、デフォルト値の 'N' に設定されています)。次の 3 つの INSERT ステートメントは、db テーブルエントリを追加し、custombankaccountexpensescustomer の各データベースに対する権限を設定します。これらの権限は、適切なホストからアクセスしたときにだけ適用されるものです。権限テーブルを直接変更した場合、FLUSH PRIVILEGES を使用してサーバに権限テーブルを再度読み込ませ、権限の変更を反映させる必要があります。

特定のユーザに、あるドメイン(たとえば mydomain.com)のすべてのマシンからのアクセスを許可するには、以下のような GRANT ステートメントを実行します。

mysql> GRANT ...
    ->     ON *.*
    ->     TO myusername@'%.mydomain.com'
    ->     IDENTIFIED BY 'mypassword';

権限テーブルを直接変更して同じことを行うには、以下を実行します。

mysql> INSERT INTO user VALUES ('%.mydomain.com', 'myusername',
    ->             PASSWORD('mypassword'),...);
mysql> FLUSH PRIVILEGES;

4.4.6. MySQL ユーザの削除

DROP USER user_name

このコマンドは MySQL 4.1.1 で追加されたコマンドです。

このコマンドにより、権限を持たないユーザが削除されます。

MySQL からユーザを削除するには、以下の手順に従います。

  1. SHOW PRIVILEGES を使用してユーザの権限を確認する。 See 項4.6.8.11. 「SHOW PRIVILEGES

  2. REVOKE を使用してユーザから権限をすべて削除する。 See 項4.4.1. 「GRANT および REVOKE の構文」

  3. DROP USER を使用してユーザを削除する。

古い MySQL バージョンを使用している場合は、まず権限を取り消してからユーザを削除します。

mysql> DELETE FROM mysql.user WHERE user='username' and host='hostname';
mysql> FLUSH PRIVILEGES;

4.4.7. ユーザリソースの制限

MySQL 4.0.2 以降、特定のリソースをユーザごとに制限できるようになりました。

今までは、MySQL サーバリソースの使用を制限するには、スタートアップ変数の max_user_connections をゼロ以外の値に設定するしかありませんでした。しかしこの方法はグローバルに適用されるため、インターネットサービスプロバイダが関心のある個別ユーザの管理には使用できませんでした。

そのため、個別ユーザレベルで 3 つのリソースを管理する方法が導入されました。

  • 時間単位の全クエリ数: 1 ユーザが実行できるクエリ。

  • 時間単位の全更新数: テーブルまたはデータベースを変更するクエリ。

  • 時間単位の接続数: 1 時間に新しく開かれる接続。

上記コンテキストの 1 ユーザとは user テーブルの 1 エントリです。このエントリは user カラムと host カラムによって識別されます。

制限を設定しない限り、すべてのユーザはデフォルトで、上記リソースを制限なく使用できます。これらの制限は、以下の構文を使用してグローバルな GRANT (*.*)のみ設定できます。

GRANT ... WITH MAX_QUERIES_PER_HOUR N1
               MAX_UPDATES_PER_HOUR N2
               MAX_CONNECTIONS_PER_HOUR N3;

上記のリソースはどのような組み合わせでも指定可能です。 N1N2、および N3 は整数で、時間単位のカウント数を表します。

ユーザが時間単位の接続数に達すると、その 1 時間が経過するまで、以降の接続は拒否されます。同様に、ユーザがクエリまたは更新の制限回数に達すると、その 1 時間が経過するまで、以降のクエリまたは更新は拒否されます。いずれの場合も、適切なエラーメッセージが表示されます。

特定ユーザの現在の使用値をフラッシュ(ゼロに設定)するには、上記の任意の節の GRANT ステートメントを発行します。その際 GRANT ステートメントの値を現在の値にします。

また、すべてのユーザの現在の値をフラッシュするには、権限を再読み込みするか(サーバ内部で行うか、mysqladmin reload を使用)、FLUSH USER_RESOURCES コマンドを実行します。

リソース制限機能は、単一ユーザにリソースを制限する GRANT 節が設定されるとすぐに有効になります。

この機能を有効化する前提条件として、scripts サブディレクトリにあるテーブル作成スクリプト mysql_install_db および mysql_install_db.sh で定義されている追加カラムが、mysql データベースの user テーブルに含まれていることが必要です。

4.4.8. パスワードの設定

ほとんどの場合において、ユーザとパスワードの設定には GRANT を使用します。以下の方法は上級ユーザ対象です。 See 項4.4.1. 「GRANT および REVOKE の構文」

前のセクションでは、例を用いて重要な原則を示しました。INSERT または UPDATE ステートメントを使用して空白でないパスワードを保存する際には、PASSWORD() 関数を使用して暗号化しなければならないということです。これは、user テーブルがパスワードを平文テキストではなく、暗号化された形式で保存するためです。たとえば、この原則を忘れて、以下のようにパスワードを設定してしまったとします。

shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('%','jeffrey','biscuit');
mysql> FLUSH PRIVILEGES;

この場合、平文テキストの 'biscuit' が、パスワードとして user テーブルに保存されます。ユーザ jeffrey がこのパスワードを使用してサーバに接続しようとすると、mysql クライアントは PASSWORD() でそれを暗号化し、暗号化されたパスワードと、サーバから取得したランダム番号に基づいて認証ベクトルを生成し、それをサーバに送信します。 サーバは user テーブルの password 値(この場合、暗号化されていない 'biscuit')を使用して同じ計算を実行し、結果を比較します。 比較は失敗し、サーバは接続を拒否します。

shell> mysql -u jeffrey -pbiscuit test
Access denied

user テーブルにパスワードを挿入するとき、パスワードは暗号化しておく必要があります。したがって、INSERT ステートメントを以下のように指定します。

mysql> INSERT INTO user (Host,User,Password)
    -> VALUES('%','jeffrey',PASSWORD('biscuit'));

SET PASSWORD ステートメントを使用するときも、PASSWORD() 関数を使用する必要があります。

mysql> SET PASSWORD FOR jeffrey@"%" = PASSWORD('biscuit');

GRANT ... IDENTIFIED BY ステートメントまたは mysqladmin password コマンドを使用してパスワードを設定する場合、PASSWORD() 関数は必要ありません。両方ともパスワードを暗号化するので、以下のようにパスワードを 'biscuit' と指定します。

mysql> GRANT USAGE ON *.* TO jeffrey@"%" IDENTIFIED BY 'biscuit';

または

shell> mysqladmin -u jeffrey password biscuit

注意: PASSWORD() は、Unix のパスワード暗号化とは異なります。 See 項4.4.2. 「MySQL のユーザ名とパスワード」

4.4.9. パスワードのセキュリティ

自分のパスワードを他のユーザがわかるような方法で指定することは危険です。 クライアントプログラムを実行する際、パスワードの指定に使用できる方法を以下に示します。それぞれの危険度についても示します。

  • 一般ユーザに mysql.user テーブルへのアクセス権を与えてはいけない。暗号化されているパスワードがわかっただけで、そのユーザとしてログインすることが可能になる。パスワードの暗号化は、本当のパスワードを他人に見られないようにするためだけのものである(他のアプリケーションで似たパスワードを使用する場合に備えて)。

  • -pyour_pass オプションまたは --password=your_pass オプションをコマンドラインで使用する。これは便利だが安全ではない。他のユーザがコマンドラインを表示するため起動する ps などのシステムステータスプログラムにはパスワードが見えてしまう(MySQL クライアントは通常、初期化シーケンスにおいてコマンドライン引数をゼロで上書きするが、短いインターバルがあってその間は見えてしまう)。

  • -p オプションまたは --password オプションを使用する(your_pass 値を指定しない)。この場合、クライアントプログラムは端末からのパスワード入力を求める。

    shell> mysql -u user_name -p
    Enter password: ********
    

    *’ 文字はパスワードを表す。

    この方法だと他のユーザには見えないため、コマンドラインでパスワードを指定するよりも安全である。ただし、このパスワード入力方法は、対話式で実行するプログラムにのみ適している。非対話式で実行するスクリプトからクライアントを起動する場合、端末からパスワードを入力する機会がない。システムによっては、スクリプトの最初の行を間違ってパスワードと解釈してしまうものもある。

  • 設定ファイルにパスワードを保存する。たとえば、自分のホームディレクトリにある .my.cnf ファイルの [client] セクションにパスワードを記入できる。

    [client]
    password=your_pass
    

    パスワードを .my.cnf に保存する場合、だれもそのファイルを読み書きできないようにしておくことが必要である。ファイルのアクセスモードは 400 または 600 にしておくこと。 See 項4.1.2. 「my.cnf オプション設定ファイル」

  • MYSQL_PWD 環境変数にパスワードを保存できる。しかしこの方法は非常に危険なので、使用すべきではない。 ps のバージョンによっては、実行中のプロセス環境を表示するオプションがある。MYSQL_PWD を設定していればだれにでもパスワードを見られてしまう。そのようなバージョンの ps がないシステムでも、プロセス環境を表示する他の方法がないと想定するのは危険である。 See 付録?F. 環境変数

以上のことを総括すると、最も安全な方法は、クライアントプログラムにパスワードを要求させるか、適切に保護された .my.cnf ファイルにパスワードを指定することです。

4.4.10. 安全な接続の使用

4.4.10.1. 基本概念

バージョン 4.0.0 より、MySQL は SSL 暗号化接続をサポートしています。MySQL がどのように SSL を使用するか理解するには、SSL と X509 の基本概念が欠かせません。基本概念を理解している読者は、このセクションを読み飛ばしてください。

デフォルトでは、MySQL はクライアントとサーバ間で暗号化されていない接続を使用します。つまり、他人がすべてのトラフィックおよび送受信データを盗み見ることが可能な接続です。また、クライアントとサーバ間で転送中のデータを改ざんすることも可能です。公開ネットワークでの情報のやり取りでも安全性が求められる場合があります。そのような場合、暗号化されていない接続は適しません。

SSL とは、複数の異なる暗号化アルゴリズムを使用して、公開ネットワークで受信するデータの信頼性を保証するためのプロトコルです。データの変更、消失、および再生を検知するメカニズムがあります。SSL にはまた、X509 規格を使用する ID 認証を認識および提供するためのアルゴリズムも組み込まれています。

暗号化とは、データを読み取り不可能にする技術です。実際、今日の社会では、暗号化アルゴリズムによるさらなるセキュリティが求められています。暗号化メッセージの順番を変更したり同じデータを 2 回再生するなど、さまざまな種類の攻撃に対する耐性が必要となっています。

X509 とは、インターネット上で ID 認証を可能にする規格です。これは、電子商取引アプリケーションで最も一般的に使用されています。基本的には、``認証局'' と呼ばれる会社が電子証明書を必要とする者に割り当てるという方法を取ります。証明書は、2 つの暗号化キー(公開キーと秘密キー)がある非対称暗号化アルゴリズムを使用しています。証明書の所有者は、他者に証明書を提示して自分の ID を証明します。証明書には、所有者の公開キーが含まれています。この公開キーで暗号化されたデータはすべて、対応する秘密キーがなければ解読できません。秘密キーは証明書の所有者が保持しています。

MySQL はデフォルトでは暗号化接続を使用しません。使用すると、クライアントとサーバのプロトコルがかなり遅くなるからです。どのような機能を追加した場合でもコンピュータには負荷がかかります。データの暗号化も例外ではなく、CPU を大幅に消費して時間がかかり、MySQL の主要タスクを遅らせる原因となります。そのためデフォルトでは、MySQL は速度が優先されています。

SSL、X509、および暗号化についてさらに詳細を知るには、インターネット検索エンジンを利用して必要な情報を検索してください。

4.4.10.2. 必要条件

安全な接続を MySQL で使用するには、以下を実行する必要があります。

  1. OpenSSL ライブラリをインストールする。OpenSSL 0.9.6 をインストールした MySQL はテスト済み。 http://www.openssl.org/

  2. MySQL を --with-vio --with-openssl でコンフィギャする。

  3. 古い MySQL バージョンを使用している場合、mysql.user テーブルに新しい SSL 関連カラムを追加する必要がある。 この処理は、権限テーブルが MySQL 4.0.0 より前のバージョンの場合に必要となる。手順については 項2.5.6. 「権限テーブルのアップグレード」 を参照のこと。

  4. 実行中の mysqld サーバが OpenSSL をサポートしているかチェックするには、SHOW VARIABLES LIKE 'have_openssl'YES を返すかどうかを確認する。

4.4.10.3. MySQL での SSL 証明書の設定

以下、MySQL での SSL 証明書の設定例です。

DIR=`pwd`/openssl
PRIV=$DIR/private

mkdir $DIR $PRIV $DIR/newcerts
cp /usr/share/ssl/openssl.cnf $DIR
replace ./demoCA $DIR -- $DIR/openssl.cnf

# Create necessary files: $database, $serial and $new_certs_dir 
# directory (optional)

touch $DIR/index.txt
echo "01" > $DIR/serial

#
# Generation of Certificate Authority(CA)
#

openssl req -new -x509 -keyout $PRIV/cakey.pem -out $DIR/cacert.pem \
    -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ................++++++
# .........++++++
# writing new private key to '/home/monty/openssl/private/cakey.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL admin
# Email Address []:

#
# Create server request and key
#
openssl req -new -keyout $DIR/server-key.pem -out \
    $DIR/server-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# ..++++++
# ..........++++++
# writing new private key to '/home/monty/openssl/server-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL server
# Email Address []:
# 
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove the passphrase from the key (optional)
#

openssl rsa -in $DIR/server-key.pem -out $DIR/server-key.pem

#
# Sign server cert
#
openssl ca  -policy policy_anything -out $DIR/server-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/server-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL admin'
# Certificate is to be certified until Sep 13 14:22:46 2003 GMT (365 days)
# Sign the certificate? [y/n]:y
# 
# 
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create client request and key
#
openssl req -new -keyout $DIR/client-key.pem -out \
    $DIR/client-req.pem -days 3600 -config $DIR/openssl.cnf

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Generating a 1024 bit RSA private key
# .....................................++++++
# .............................................++++++
# writing new private key to '/home/monty/openssl/client-key.pem'
# Enter PEM pass phrase:
# Verifying password - Enter PEM pass phrase:
# -----
# You are about to be asked to enter information that will be incorporated
# into your certificate request.
# What you are about to enter is what is called a Distinguished Name or a DN.
# There are quite a few fields but you can leave some blank
# For some fields there will be a default value,
# If you enter '.', the field will be left blank.
# -----
# Country Name (2 letter code) [AU]:FI
# State or Province Name (full name) [Some-State]:.
# Locality Name (eg, city) []:
# Organization Name (eg, company) [Internet Widgits Pty Ltd]:MySQL AB
# Organizational Unit Name (eg, section) []:
# Common Name (eg, YOUR name) []:MySQL user
# Email Address []:
# 
# Please enter the following 'extra' attributes
# to be sent with your certificate request
# A challenge password []:
# An optional company name []:

#
# Remove a passphrase from the key (optional)
#
openssl rsa -in $DIR/client-key.pem -out $DIR/client-key.pem

#
# Sign client cert
#

openssl ca  -policy policy_anything -out $DIR/client-cert.pem \
    -config $DIR/openssl.cnf -infiles $DIR/client-req.pem

# Sample output:
# Using configuration from /home/monty/openssl/openssl.cnf
# Enter PEM pass phrase:
# Check that the request matches the signature
# Signature ok
# The Subjects Distinguished Name is as follows
# countryName           :PRINTABLE:'FI'
# organizationName      :PRINTABLE:'MySQL AB'
# commonName            :PRINTABLE:'MySQL user'
# Certificate is to be certified until Sep 13 16:45:17 2003 GMT (365 days)
# Sign the certificate? [y/n]:y
# 
# 
# 1 out of 1 certificate requests certified, commit? [y/n]y
# Write out database with 1 new entries
# Data Base Updated

#
# Create a my.cnf file that you can use to test the certificates
#

cnf=""
cnf="$cnf [client]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/client-cert.pem"
cnf="$cnf ssl-key=$DIR/client-key.pem"
cnf="$cnf [mysqld]"
cnf="$cnf ssl-ca=$DIR/cacert.pem"
cnf="$cnf ssl-cert=$DIR/server-cert.pem"
cnf="$cnf ssl-key=$DIR/server-key.pem"
echo $cnf | replace " " '
' > $DIR/my.cnf

#
# To test MySQL

mysqld --defaults-file=$DIR/my.cnf &

mysql --defaults-file=$DIR/my.cnf

mysql-source-dist/SSL ディレクトリにあるデモ証明書を参照するように上記の my.cnf ファイルを修正することによっても、設定をテストできます。

4.4.10.4. SSL GRANT オプション

MySQL は、通常のユーザ名とパスワードのスキームに加え、X509 証明書属性をチェックすることができます。通常のオプションもすべて必要です(ユーザ名、パスワード、IP アドレスマスク、データベース/テーブル名)。

接続の制限にはいくつかのシナリオがあります。

  • SSL または X509 オプションがない場合、ユーザ名とパスワードが正しければ、暗号化および非暗号化すべての接続が許可される。

  • REQUIRE SSL オプションは、サーバが SSL 暗号化接続のみを許可するように制限する。 注意: 非 SSL 接続を許可する ACL レコードがある場合、このオプションは除外できる。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret' REQUIRE SSL;
    
  • REQUIRE X509 は、クライアントに有効な証明書が必要なことを意味するが、どの証明書、発行者、およびサブジェクトでなければいけないという指定はない。 CA 証明書の署名を確認できれば、それで十分である。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret' REQUIRE X509;
    
  • REQUIRE ISSUER 'issuer' は、接続試行に制限を加える。 クライアントは、CA 'issuer' によって発行された有効な X509 証明書を提示する必要がある。 X509 証明書を使用することは、暗号化の使用を意味しており、SSL オプションは不要である。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE ISSUER 'C=FI, ST=Some-State, L=Helsinki,
        '> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com';
    
  • REQUIRE SUBJECT 'subject' では、サブジェクト 'subject' が有効な X509 証明書がクライアントに必要となる。クライアントが有効な証明書を提示しても、'subject' が異なる場合、接続は拒否される。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE SUBJECT 'C=EE, ST=Some-State, L=Tallinn,
        '> O=MySQL demo client certificate,
        '> CN=Tonu Samuel/Email=tonu@mysql.com';
    
  • REQUIRE CIPHER 'cipher' は、強力な暗号とキー長の使用を義務付ける。短い暗号化キーの古いアルゴリズムを使用した場合、SSL 自体も強力ではなくなる。このオプションを使用することにより、接続許可の条件として特定の暗号化を指定できる。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

    SUBJECTISSUER、および CIPHER のオプションは、以下のように REQUIRE 節で組み合わせることができる。

    mysql> GRANT ALL PRIVILEGES ON test.* TO root@localhost
        -> IDENTIFIED BY 'goodsecret'
        -> REQUIRE SUBJECT 'C=EE, ST=Some-State, L=Tallinn,
        '> O=MySQL demo client certificate,
        '> CN=Tonu Samuel/Email=tonu@mysql.com'
        -> AND ISSUER 'C=FI, ST=Some-State, L=Helsinki,
        '> O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com'
        -> AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
    

    MySQL 4.0.4 以降、REQUIRE オプション間の AND キーワードは任意になっている。

    オプションはどんな順序でも指定できるが、同じオプションを 2 回指定することはできない。

4.4.10.5. SSL コマンドラインオプション

以下の表は、SSL、証明書ファイル、およびキーファイルの使用を指定するためのオプションをまとめたものです。 これらのオプションは MySQL 4.0 から導入されたものです。これらのオプションは、コマンドラインでもオプション設定ファイルでも使用できます。

  • --ssl

    サーバに対しては、サーバが SSL 接続を許可するように指定する。 クライアントプログラムに対しては、SSL を使用してサーバに接続することを許可する。 このオプションだけでは SSL 接続の使用は保証されない。 --ssl-ca--ssl-cert、および --ssl-key オプションも指定する必要がある。

    注意: このオプションでは、SSL 接続が必須とならない。 たとえば、サーバまたはクライアントが SSL サポートなしでコンパイルされている場合、通常の暗号化されていない接続が使用される。

    SSL 接続だけの使用を確実に保証するには、まず、GRANT ステートメントで REQUIRE SSL 節を含むアカウントをサーバに作成することが必要。 そしてこのアカウントを使用してサーバに接続する。このとき、サーバとクライアントの両方で SSL サポートが有効になっていることが必要である。

    このオプションを使用して、接続に SSL を使用しないように指定することができる。 この場合、オプションを --skip-ssl または --ssl=0 として指定する。

  • --ssl-ca=file_name

    信頼された SSL 認証局の一覧が含まれるファイルのパス。

  • --ssl-capath=directory_name

    PEM 形式の信頼された CA 証明書が保存されているディレクトリのパス。

  • --ssl-cert=file_name

    安全な接続を確立するために使用する SSL 証明書ファイルの名前。

  • --ssl-cipher=cipher_list

    SSL 暗号化に使用できる暗号の一覧。 cipher_list は、openssl ciphers コマンドと同じ形式である。

    例: --ssl-cipher=ALL:-AES:-EXP

  • --ssl-key=file_name

    安全な接続を確立するために使用する SSL キーファイルの名前。

4.5. 障害の予防とリカバリ

4.5.1. データベースのバックアップ

MySQL テーブルはファイルとして保存されるため、バックアップが簡単です。一貫したバックアップを行うには、そのテーブルに対して LOCK TABLES を実行してから、FLUSH TABLES を実行します。 See 項6.7.5. 「LOCK TABLES および UNLOCK TABLES 構文」。 See 項4.6.4. 「FLUSH 構文」。 読み取りロックだけが必要なので、データベースディレクトリのファイルをコピーしている間も、他のスレッドはテーブルに対してクエリを続行できます。FLUSH TABLE は、バックアップを開始する前に、キャッシュされているページをすべてディスクに書き込むために必要です。

3.23.56 から 4.0.12 では、セキュリティ上のリスクがあるため、BACKUP TABLE で既存ファイルの上書きはできないようになっています。

テーブルを SQL レベルでバックアップするには、SELECT INTO OUTFILE または BACKUP TABLE を使用します。 See 項6.4.1. 「SELECT 構文」。 See 項4.5.2. 「BACKUP TABLE 構文」

データベースのバックアップには、mysqldump プログラムまたは mysqlhotcopy script を使用することもできます。 See 項4.9.7. 「mysqldump(テーブル構造とデータのダンプ)」。 See 項4.9.8. 「mysqlhotcopy(MySQL のデータベースとテーブルのコピー)」

  1. データベースをフルバックアップする。

    shell> mysqldump --tab=/path/to/some/dir --opt db_name
    
    または
    
    shell> mysqlhotcopy db_name /path/to/some/dir
    

    サーバが何かを更新中でなければ、すべてのファイル(*.frm*.MYD、および *.MYI)を単にコピーすることもできる。 スクリプト mysqlhotcopy はこの方法を使用している。 注意: データベースに InnoDB テーブルが含まれている場合、InnoDB はテーブルコンテンツをデータベースディレクトリに保存しないため、この方法は使用できない。mysqlhotcopyMyISAM テーブルと ISAM テーブルにのみ有効。

  2. mysqld が実行中であればいったん停止し、--log-bin[=file_name] オプションで再起動する。See 項4.10.4. 「バイナリログ」mysqldump 実行後に行われたデータの変更をレプリケートするための情報が、バイナリログファイルにより提供される。

MySQL サーバがスレーブの場合、どのバックアップ方法を選択しても、スレーブのデータをバックアップするとき、master.info ファイルと relay-log.info ファイルもバックアップしてください。これらのファイルは、スレーブのデータをリストア後、レプリケーションを再開するときに必要です。スレーブが、レプリケーションを行う LOAD DATA INFILE コマンドの対象となっていた場合、SQL_LOAD-* ファイルもバックアップしてください。このファイルは、--slave-load-tmpdir オプションによって指定されているディレクトリにあります(このファイルの場所が指定されていない場合、デフォルトで、この場所は tmpdir 変数の値になります)。中断されていた LOAD DATA INFILE 処理のレプリケーションを再開するためにスレーブはこれらのファイルを必要とします。

何かをリストアする必要がある場合、最初に REPAIR TABLE または myisamchk -r を使用してテーブルのリカバリを試みてください。ほとんどの場合、これで成功するはずです。myisamchk でリカバリできなかった場合、以下を実行します。これは、--log-bin で MySQL を起動している場合にのみ可能な方法です。項4.10.4. 「バイナリログ」 を参照してください。

  1. オリジナルの mysqldump バックアップ、またはバイナリバックアップをリストアする。

  2. 以下のコマンドを実行して、バイナリログ内の更新を再実行する。

    shell> mysqlbinlog hostname-bin.[0-9]* | mysql
    

    場合に応じて、特定の位置から後のバイナリログだけを再実行する(通常は、リストアしたバックアップの日付以降の、不正なクエリ以外のすべてのバイナリログを再実行する)。 mysqlbinlog ユーティリティおよびその使用法の詳細については、項4.9.5. 「mysqlbinlog(バイナリログからクエリを実行する)」 を参照のこと。

    更新ログ(MySQL 5.0 で廃止)を使用している場合、更新ログの内容を以下のように実行できる。

    shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
    

    ls は、すべての更新ログファイルを正しい順序で取得するために使用します。

SELECT * INTO OUTFILE 'file_name' FROM tbl_name で選択的バックアップを行い、LOAD DATA INFILE 'file_name' REPLACE ... でリストアすることもできます。重複テーブルを避けるため、テーブルに PRIMARY KEY または UNIQUE キーが必要です。REPLACE キーワードを使用すると、ユニークキーが新規レコードと旧レコードで重複していた場合に、旧レコードが新規レコードで置き換えられます。

バックアップに伴いパフォーマンス上の問題が発生する場合、レプリケーションをセットアップして、マスタではなくスレーブ上でバックアップを実行することによりこの問題を解決できる。 See 項4.11.1. 「はじめに」

Veritas ファイルシステムを使用している場合、以下を実行できます。

  1. クライアント(または Perl)から、FLUSH TABLES WITH READ LOCK を実行する。

  2. 別のシェルから、mount vxfs snapshot を実行する。

  3. 最初のクライアントから、UNLOCK TABLES を実行する。

  4. スナップショットからファイルをコピーする。

  5. スナップショットのマウントを解除する。

4.5.2. BACKUP TABLE 構文

BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'

ディスクにバッファされている変更をフラッシュした後で、テーブルをリストアするのに最低限必要な数のテーブルファイルをバックアップディレクトリにコピーします。現在のところ、このコマンドは MyISAM テーブルにのみ有効です。 MyISAM テーブルに対して、.frm 定義ファイルと .MYD データファイルをコピーします。これら 2 つのファイルからインデックスファイルを再度ビルドできます。

このコマンドを使用する前に、項4.5.1. 「データベースのバックアップ」 を参照してください。

バックアップ中、各テーブルが処理されている間そのテーブルにのみ読み取りロックがかかります。複数のテーブルを 1 回のスナップショットでバックアップする場合は、まず LOCK TABLES を実行して、そのグループ内の各テーブルに対して読み取りロックをかけておく必要があります。

このコマンドは、以下のカラムで構成されるテーブルを返します。

カラム
Tableテーブル名
Op常に backup
Msg_typestatuserrorinfowarning のいずれか
Msg_textメッセージ

注意: BACKUP TABLE は、MySQL バージョン 3.23.25 以降でのみ使用できます。

4.5.3. RESTORE TABLE 構文

RESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory'

BACKUP TABLE で作成されたバックアップから、1 つまたは複数のテーブルをリストアします。既存テーブルには上書きされません。既存テーブルの上にリストアしようとすると、エラーになります。インデックスを再度ビルドする必要があるため、リストアはバックアップよりも時間がかかります。キーが多ければ多いほど、時間がかかります。BACKUP TABLE と同じく、RESTORE TABLE は現在のところ、MyISAM テーブルにのみ有効です。

このコマンドは、以下のカラムで構成されるテーブルを返します。

カラム
Tableテーブル名
Op常に restore
Msg_typestatuserrorinfowarning のいずれか
Msg_textメッセージ

4.5.4. CHECK TABLE 構文

CHECK TABLE tbl_name[,tbl_name...] [option [option...]]

option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED

CHECK TABLE は、MyISAM テーブルと InnoDB テーブルにのみ有効です。MyISAM テーブルの場合、このテーブルで myisamchk --medium-check table_name を実行するのと同じです。

オプションを何も指定しなければ、MEDIUM が使用されます。

1 つまたは複数のテーブルのエラーをチェックします。MyISAM テーブルでは、キー統計が更新されます。このコマンドは、以下のカラムで構成されるテーブルを返します。

カラム
Tableテーブル名
Op常に check
Msg_typestatuserrorinfowarning のいずれか
Msg_textメッセージ

注意: このステートメントは、チェックした各テーブルに関する多くの情報レコードを生成します。 正常な場合、Msg_typestatus で、Msg_text は通常 OK になります。 OK または Table is already up to date が得られなければ、テーブルの修復が必要と考えられます。See 項4.5.6. 「myisamchk を使用したテーブルの保守とクラッシュのリカバリ」Table is already up to date は、テーブルのストレージマネージャが、そのテーブルにチェックが必要ないと判断したことを意味します。

以下のチェックタイプがあります。

タイプ意味
QUICK不正リンクをチェックするためのレコードスキャンを実行しない。
FAST正しく閉じられなかったテーブルだけをチェックする。
CHANGED前回のチェック後に変更されたテーブルと、正しく閉じられなかったテーブルだけをチェックする。
MEDIUMレコードをスキャンして、削除されたリンクが問題なかったことを確認する。また、レコードのキーチェックサムを計算し、キーの計算されたチェックサムを使って確認する。
EXTENDED各レコードですべてのキーの完全キールックアップを実行する。テーブルの整合性が 100% 保証されるが、時間がかかる。

動的サイズの MyISAM テーブルでは、チェックが開始された場合、常に MEDIUM チェックが実行されます。静的サイズのレコードは破損していることが非常にまれなので、QUICK および FAST でレコードスキャンをスキップします。

チェックオプションは以下のように組み合わせることができます。以下の例では、テーブルが正しく閉じられたかどうかを確認するクイックチェックを行います。

CHECK TABLE test_table FAST QUICK;

注意: 場合によっては CHECK TABLE はテーブルを変更します。これは、テーブルに 'corrupted' または 'not closed properly' というマークがあるのに、CHECK TABLE がテーブル内に問題を発見しなかった場合に発生します。この場合、CHECK TABLE はテーブルを OK とマークします。

テーブルが破損している場合、データ部分よりもインデックスに問題のある方が可能性が高いです。上記のチェックタイプはいずれも、インデックスを完全にチェックするのでほとんどのエラーは発見できます。

問題がないと思われるテーブルをチェックする場合、チェックオプションを使用しないか、または QUICK オプションを使用します。QUICK は、急いでいるとき、およびデータファイルのエラーが見逃されるかもしれないという非常に小さな危険性を無視できる場合に使用します。ほとんどの場合、MySQL は通常どおりに使用していれば、データファイルのエラーを発見します。発見した場合、そのテーブルには 'corrupted' のマークが付き、修復するまでそのテーブルは使用できません。

FAST および CHANGED は、テーブルをときどきチェックしたい場合に、スクリプトから(たとえば cron から)実行されることを想定しています。通常は、CHANGED よりも FAST の方を使用してください(これが当てはまらないのは、MyISAM コード内にバグが疑われる場合のみです)。

EXTENDED は、通常のチェック後に、MySQL がレコードを更新したりキーでレコードを検索しようとした際に、不自然なエラーが発生する場合にのみ使用します(通常のチェックが正常に終了した後でエラーが発生するのは非常にまれなことです)。

CHECK TABLE で報告される問題の中には、自動的に修正されないものがあります。

  • Found row where the auto_increment column has the value 0

    これは、AUTO_INCREMENT インデックスカラムの値が 0 になっているレコードがテーブルにあることを意味する(UPDATE ステートメントで明示的に AUTO_INCREMENT カラム値を 0 に設定すれば、このカラムが 0 のレコードを作成することは可能である)。

    これ自体はエラーではないが、テーブルをダンプしてリストアしようとしたり、テーブルで ALTER TABLE を実行しようとすると問題が発生する。この場合、AUTO_INCREMENT カラムは AUTO_INCREMENT カラムのルールに基づいて値を変更するため、重複キーエラーなどの原因となる。

    警告を消すには、UPDATE ステートメントを実行してこのカラム値を 0 以外の値に設定する。

4.5.5. REPAIR TABLE 構文

REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM]

REPAIR TABLEMyISAM テーブルにのみ有効であり、このテーブルで myisamchk -r table_name を実行するのと同じです。

通常であれば、このコマンドを使用することはありませんが、障害が発生した場合、REPAIR TABLE を使用すれば、ほとんどの場合、MyISAM テーブルのすべてのデータを取り戻せます。テーブルが頻繁に破損するようであれば、その原因を突き止めて、REPAIR TABLE を使用する必要がなくなるようにしてください。 See 項A.4.1. 「MySQL が何度もクラッシュする場合に行うこと」。 See 項7.1.3. 「MyISAM テーブルの問題」

REPAIR TABLE は、破損した可能性のあるテーブルを修復します。このコマンドは、以下のカラムで構成されるテーブルを返します。

カラム
Tableテーブル名
Op常に repair
Msg_typestatuserrorinfowarning のいずれか
Msg_textメッセージ

注意: このステートメントは、修復した各テーブルに関する多くの情報レコードを生成します。 正常な場合、Msg_typestatus で、Msg_text は通常 OK になります。OK を得られない場合は、myisamchk --safe-recover でテーブルの修復を試みてください。REPAIR TABLE ではまだ myisamchk のすべてのオプションをカバーしていません。将来は、このコマンドをより柔軟性の高いものにする予定です。

QUICK を指定した場合、REPAIR TABLE はインデックスツリーだけを修復しようとします。

EXTENDED を使用すると、MySQL はソートごとにインデックスを生成するのではなく、レコードごとにインデックスを生成します。確実に圧縮される長い CHAR キーを使用している場合など、固定長キーをソートするよりこの方法の方が適しています。このタイプの修復は、myisamchk --safe-recover で実行される修復とほぼ同じです。

MySQL 4.0.2 から、REPAIRUSE_FRM モードが導入されています。 .MYI ファイルがない、またはそのヘッダが破損している場合にこのモードを使用します。 このモードでは、.frm ファイルの情報を使用してテーブルが再度作成されます。このような修復は、myisamchk ではできません。

警告: REPAIR TABLE を実行中に mysqld が終了してしまった場合、他のコマンドを実行する前にもう 1 回 REPAIR を必ず実行してください(もちろん、常にバックアップから開始することを推奨します)。最悪の場合、データファイルに関する情報がない新規のクリーンなインデックスファイルができることがあり、次のコマンドでデータファイルが上書きされてしまう可能性があります。これはあまりないことではありますが、可能性としてはあり得るので、注意が必要です。

MySQL 4.1.1 より前では、REPAIR コマンドはバイナリログに書き込まれません。MySQL 4.1.1 以降、任意の NO_WRITE_TO_BINLOG キーワード(またはそのエイリアスの LOCAL)を使用しない限り、このコマンドはバイナリログに書き込まれます。

4.5.6. myisamchk を使用したテーブルの保守とクラッシュのリカバリ

MySQL バージョン 3.23.13 以降、CHECK TABLE コマンドを使用して MyISAM テーブルをチェックできるようになりました。See 項4.5.4. 「CHECK TABLE 構文」。 テーブルの修復には REPAIR TABLE コマンドを使用できます。 See 項4.5.5. 「REPAIR TABLE 構文」

MyISAM テーブル(.MYI および .MYD)のチェックおよび修復には myisamchk ユーティリティを使用してください。ISAM テーブル(.ISM および .ISD)のチェックおよび修復には isamchk ユーティリティを使用します。 See 章?7. MySQL のテーブル型

以下の説明は myisamchk についてですが、旧 isamchk にもすべて当てはまります。

myisamchk ユーティリティを使用して、データベーステーブルの情報を取得したり、テーブルのチェック、修復、および最適化を実行できます。以下のセクションでは、myisamchk の起動方法(オプションの説明も含む)、テーブル保守のスケジュール、およびさまざまな myisamchk 機能について説明します。

多くの場合、OPTIMIZE TABLES コマンドを使用してテーブルの最適化と修復を行うこともできますが、myisamchk に比べると時間がかかり、重大エラーの場合は信頼性も高くありません。その反面、OPTIMIZE TABLE は使用が簡単で、テーブルのフラッシュを心配する必要がありません。 See 項4.6.1. 「OPTIMIZE TABLE 構文」

myisamchk による修復は信頼性に優れていますが、修復を実行する(つまりテーブルに多くの変更を加える)前に、バックアップを作成しておくことが必要です。

4.5.6.1. myisamchk 起動構文

myisamchk は以下のように起動します。

shell> myisamchk [options] tbl_name

options は、myisamchk が実行することを指定します。それらについてはここで説明します(myisamchk --help を実行すると、オプションの一覧を取得できます)。オプションを指定しなければ、myisamchk はテーブルのチェックだけを行います。詳細情報を取得したり、myisamchk に修正を実行させるには、ここで説明するオプションを指定することが必要です。

tbl_name は、チェックおよび修復対象となるデータベーステーブル名です。データベースディレクトリ以外の場所で myisamchk を実行する場合、myisamchk に対してファイルのパスを指定する必要があります。実際、myisamchk は処理対象のファイルがデータベースディレクトリにあるかどうかを問題にしません。データベーステーブルのファイルを他の場所にコピーし、そこでリカバリ操作を実行することもできます。

myisamchk コマンドラインに複数のテーブル名を指定することもできます。また、インデックスファイル名(.MYI サフィックス付き)を指定することもできます。*.MYI パターンを使用すれば 1 つのディレクトリ内のすべてのテーブルを指定することができます。 たとえば、カレントディレクトリがデータベースディレクトリである場合、以下のようにすればディレクトリ内の全テーブルをチェックできます。

shell> myisamchk *.MYI

カレントディレクトリがデータベースディレクトリでない場合、以下のようにディレクトリのパスを指定することにより、その全テーブルをチェックできます。

shell> myisamchk /path/to/database_dir/*.MYI

MySQL データディレクトリのパスにワイルドカードを使用することにより、全データベースのすべてのテーブルをチェックすることもできます。

shell> myisamchk /path/to/datadir/*/*.MYI

すべてのテーブルに対して簡単にチェックを行う場合、以下の方法を推奨します。

myisamchk --silent --fast /path/to/datadir/*/*.MYI
isamchk --silent /path/to/datadir/*/*.ISM

すべてのテーブルをチェックし、破損していたテーブルをすべて修復するには、以下を実行します。

myisamchk --silent --force --fast --update-state -O key_buffer=64M \
          -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M \
          /path/to/datadir/*/*.MYI
isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M \
        -O read_buffer=1M -O write_buffer=1M /path/to/datadir/*/*.ISM

この例では、64 メガバイト以上の空き容量があることを前提にしています。

注意: 以下のエラーが発生する場合があります。

myisamchk: warning: 1 clients is using or hasn't closed the table properly

これは、他のプログラム(mysqld サーバなど)によって更新されてまだ閉じられていないファイル、または正しく閉じられていないファイルのテーブルをチェックしようとしているということです。

mysqld を実行中であれば、FLUSH TABLES ですべてのテーブルの同期とクローズを強制的に実行し、myisamchk を実行する間は他のだれにもテーブルを使用させないようにしてください。MySQL バージョン 3.23 で、この問題を回避する最も簡単な方法は、myisamchk の代わりに CHECK TABLE を使用してテーブルをチェックすることです。

4.5.6.2. myisamchk の一般的なオプション

myisamchk は、以下のオプションをサポートします。

  • -# または --debug=debug_options

    デバッグログを出力する。debug_options 文字列には、'd:t:o,filename' がよく使用される。

  • -? または --help

    ヘルプメッセージを表示して終了する。

  • -O name=value, --set-variable=name=value

    変数の値を指定する。 注意: --set-variable=name=value および -O name=value 構文は MySQL 4.0 で廃止。代わりに --name=value を使用すること。 myisamchk で使用できる変数とそのデフォルト値は、myisamchk --help で確認できる。

    変数
    key_buffer_size523264
    read_buffer_size262136
    write_buffer_size262136
    sort_buffer_size2097144
    sort_key_blocks16
    decode_bits9

    sort_buffer_size は、キーのソートによってキーが修復された場合に使用する。これは、--recover を使用すると通常発生する状態。

    key_buffer_size は、--extended-check を使用してテーブルをチェックしている場合や、通常の挿入と同様、キーをテーブルのレコードごとに挿入することによりキーが修復される場合に使用する。以下の場合に、キーバッファによる修復が使用される。

    • --safe-recover を使用する場合。

    • キーファイルを直接作成した場合よりキーをソートした場合の方が、必要なテンポラリファイルが 2 倍以上の大きさになる場合。ソート中はキー全体を保存しておく必要があるため、CHAR キー、VARCHAR キー、または TEXT キーのサイズが大きい場合にこのケースが発生する。テンポラリ領域が豊富にあり、ソートによる修復を myisamchk に実行させることができる場合は、--sort-recover オプションを使用できる。

    キーバッファによる修復は、ソートによる修復よりディスク領域は少なくて済むが、処理速度は遅くなる。

    速い修復を望む場合は、上記の変数を利用可能メモリの 1/4 に設定する。上記バッファは 1 度に 1 つだけ使用されるため、両方の変数を大きな値に設定できる。

  • -s または --silent

    サイレントモード。エラー発生時のみ出力する。-s を 2 回指定すると(-ss)、myisamchk はさらに出力が少なくなる。

  • -v または --verbose

    冗長モード。詳細情報を出力する。-d および -e と併用できる。-v を複数回指定すると(-vv-vvv など)、より冗長になる。

  • -V または --version

    myisamchk のバージョン情報を出力して終了する。

  • -w または --wait

    テーブルがロックされている場合にエラーを出さず、テーブルのロックが解除されるまで待機する。注意: そのテーブルに対して --skip-external-locking オプション付きの mysqld が実行している場合、そのテーブルは別の myisamchk コマンドによってのみロックされる。

4.5.6.3. myisamchk のチェックオプション

  • -c または --check

    テーブルのエラーをチェックする。myisamchk に対して明示的にこのオプションを上書きするオプションを指定しなければ、これがデフォルト処理になる。

  • -e または --extend-check

    テーブルを完全にチェックする(インデックスが多い場合、処理時間がかかる)。このオプションは、極端な場合にだけ使用する。通常、myisamchk または myisamchk --medium-check でテーブルのエラーを検出できる。

    --extended-check を使用し、メモリが豊富にある場合、key_buffer_size の値を大きく設定すべきである。

  • -F または --fast

    正しく閉じられなかったテーブルだけをチェックする。

  • -C または --check-only-changed

    前回のチェック以降に変更されたテーブルだけをチェックする。

  • -f または --force

    myisamchk でテーブルにエラーが検出された場合、myisamchk-r(修復)で再起動する。

  • -i または --information

    チェックしたテーブルの統計を出力する。

  • -m または --medium-check

    extended-check よりも速いが、すべてのエラーは見つけられない。 しかし、ほとんどの場合はこれで十分である。

  • -U または --update-state

    テーブルをいつチェックしたか、その際テーブルが破損していたかどうかを .MYI ファイルに記録する。このオプションは、--check-only-changed オプションを最大限有効に活用するために使用する。ただし、mysqld サーバがそのテーブルを使用しており、mysqld--skip-external-locking で実行している場合は、このオプションを使用してはいけない。

  • -T または --read-only

    テーブルにチェック済みのマーキングをしない。mysqld --skip-external-locking などのような、ロックを使用しない他のアプリケーションによって使用されているテーブルを、myisamchk を使用してチェックする場合、このオプションが便利である。

4.5.6.4. myisamchk の修復オプション

以下のオプションは、myisamchk-r または -o で起動した場合に使用できます。

  • -B または --backup

    .MYD ファイルのバックアップを filename-time.BAK として作成する。

  • --correct-checksum

    テーブルのチェックサム情報を修正する。

  • -D # または --data-file-length=#

    データファイルの最大長(データファイルが 'full' で再生成されるとき)。

  • -e または --extend-check

    データファイルから可能なすべてのレコードのリカバリを試みる。 通常、このオプションではガーベジレコードも多く見つかる。他に手がないとき以外は、このオプションは使用しないようにする。

  • -f または --force

    停止しないで、古いテンポラリファイル(table_name.TMD)を上書きする。

  • -k # または --keys-used=#

    ISAM を使用している場合、ISAM ストレージエンジンが最初の # インデックスだけを更新するように指定する。MyISAM を使用している場合は、各バイナリビットが 1 つのキーに対応しているので、どのキーを使用するかはビット計算をして指定する。 このオプションを使用して、挿入を高速化できる。無効化されたインデックスを再び有効にするには、myisamchk -r を使用する。

  • -l または --no-symlinks

    シンボリックリンクを使用しない。通常、myisamchk はシンボリックリンクが指すテーブルを修復する。このオプションは MySQL 4.0 にはない。MySQL 4.0 では修復中にシンボリックリンクが削除されないためである。

  • -p または --parallel-recover

    -r および -n と同じテクニックを使用するが、すべてのキーを複数のスレッドで並列処理する。 このオプションは MySQL 4.0.2 で導入。 これは、アルファコードである。使用にはリスクが伴う。

  • -r または --recover

    ほとんどのエラーを修復できる。ただし、ユニークキーが一意でないエラーの場合には対応できない(ISAM テーブルまたは MyISAM テーブルでは非常に珍しいエラーである)。 テーブルをリカバリする場合は、まずこのオプションを試す。-r ではテーブルをリカバリできないと myisamchk により報告された場合のみ、-o を実行する。注意: めったにないことではあるが -r が失敗した場合でも、データファイルは損傷を受けない。 メモリが豊富にある場合は、sort_buffer_size のサイズを大きくすべきである。

  • -o または --safe-recover

    古いリカバリ方式を使用する(すべてのレコードを順番どおりに読み取り、検出されたレコードに基づいてすべてのインデックスツリーを更新する)。これは -r よりもかなり遅いが、-r で処理できない場合にも対応する。このリカバリ方式は、-r よりもディスク容量の使用が少なくて済む。通常は最初に -r で修復を試みて、それに失敗した場合のみ -o を使用する。

    メモリが豊富にある場合は、key_buffer_size のサイズを大きくすべきである。

  • -n または --sort-recover

    テンポラリファイルが非常に大きい場合でも、キー解決のために myisamchk にソートを強制する。

  • --character-sets-dir=...

    キャラクタセットが格納されているディレクトリ。

  • --set-character-set=name

    インデックスによって使用されるキャラクタセットを変更する。

  • -t または --tmpdir=path

    テンポラリファイルを保存するパス。これを設定しない場合、myisamchk はこれに環境変数 TMPDIR を使用する。 MySQL 4.1 以降、tmpdir で、複数のパスをコロン : で区切って設定できるようになっている(Windows ではセミコロン ;)。これは、ラウンドロビン方式で使用される。

  • -q または --quick

    データファイルを修正しないことにより、修復を速く行う。-q を 2 回指定すると、重複キーの場合に、myisamchk にオリジナルのデータファイルの修正を強制する。

  • -u または --unpack

    myisampack でパックされたファイルをアンパックする。

4.5.6.5. myisamchk のその他のオプション

以下は、myisamchk で実行できる、テーブルの修復およびチェック以外の操作です。

  • -a または --analyze

    キーの分布を分析する。このオプションを使用することにより、結合オプティマイザが、テーブルの結合順序や使用すべきキーをより的確に判断できるようになるため、結合パフォーマンスが向上する。 myisamchk --describe --verbose table_name' または MySQL で SHOW KEYS を使用することにより、キーの分布を確認できる。

  • -d または --description

    テーブルに関する情報を出力する。

  • -A または --set-auto-increment[=value]

    指定の値以上で AUTO_INCREMENT を開始する。ここで値を指定しなければ、次の AUTO_INCREMENT 値は、オートキーに使用された最高値に 1 を加えた値になる。

  • -S または --sort-index

    インデックスツリーブロックを降順にソートする。 検索が最適化され、キーによるテーブルスキャンが速くなる。

  • -R または --sort-records=#

    インデックスに従ってレコードをソートする。このソートにより、データが整理され、このインデックスでの SELECTORDER BY の処理速度が速くなる(最初のソートは非常に遅くなる)。 テーブルのインデックス番号を調べるには SHOW INDEX を使用する。テーブルのインデックスが myisamchk が検出する順序で表示される。インデックス番号は 1 から始まる。

4.5.6.6. myisamchk のメモリ使用

myisamchk を実行する場合、メモリの配分が重要な問題になります。 myisamchk は、-O オプションで指定したサイズ以上のメモリは使用しません。非常に大きなファイルに対して myisamchk を使用する場合、メモリの使用量を最初に決めておいてください。修復処理に使用するメモリのデフォルト値は約 3 メガバイトです。大きな値を使用すれば、myisamchk の処理を高速化できます。たとえば、32 メガバイト以上の RAM がある場合、以下のようにオプションを指定できます(必要に応じて他のオプションも追加します)。

shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

ほとんどの場合、-O sort=16M で十分です。

myisamchk は、TMPDIR のテンポラリファイルを使用することに注意してください。TMPDIR がメモリファイルシステムをポイントしていれば、すぐにメモリ不足エラーになります。このエラーが発生する場合には、TMPDIR を、容量の大きいディレクトリを指すように設定し、myisamchk を再起動します。

修復時も、myisamchk は大きなディスク容量を必要とします。

  • レコードファイルサイズの 2 倍(オリジナルとコピーの分)。--quick で修復を実行する場合、インデックスファイルだけが再生成されるため、この容量は不要である。オリジナルのレコードファイルと同じディスク上にこの容量が必要である。

  • 古いインデックスファイルと置き換えられる新しいインデックスファイルの容量。古いインデックスファイルは最初に切り捨てられるため、通常、この容量は無視される。 オリジナルのインデックスファイルと同じディスク上にこの容量が必要である。

  • --recover または --sort-recover を使用する場合(--safe-recover を使用する場合は含まれない)、ソートバッファ用の容量として (largest_key + row_pointer_length)*number_of_rows * 2 が必要である。 キーの長さおよびレコードポインタの長さを確認するには、myisamchk -dv table を使用する。 この容量は、テンポラリディスクに割り当てられる(TMPDIR または --tmpdir=# で指定)。

修復中にディスク容量に関する問題が発生した場合は、--recover の代わりに --safe-recover を使用できます。

4.5.6.7. myisamchk を使用したクラッシュのリカバリ

mysqld--skip-external-locking で実行している場合(Linux などのシステムではデフォルト)、mysqld が使用している同じテーブルを myisamchk でチェックしても信頼できません。myisamchk の実行中、mysqld からテーブルにアクセスするユーザが確実にない場合のみ、mysqladmin flush-tables を実行してからテーブルをチェックします。テーブルにアクセスするユーザがいるかどうか確信できない場合には、テーブルをチェックする間、mysqld を停止する必要があります。mysqld がテーブルを更新しているときに myisamchk を実行すると、テーブルが破損していない場合でも破損の警告が出る可能性があります。

--skip-external-locking を使用していなければ、いつでも myisamchk を使用してテーブルをチェックできます。この間、テーブルを更新しようとするクライアントはすべて、myisamchk の準備が整うのを待ってから実行します。

myisamchk を使用してテーブルを修復または最適化する場合、必ずmysqld サーバがそのテーブルを使用していないことを確認してください(--skip-external-locking を使用している場合も同様です)。 mysqld を停止しない場合は、少なくとも mysqladmin flush-tablesmyisamchk の前に実行してください。 サーバと myisamchk が同時にテーブルにアクセスすると、テーブルが破損するおそれがあります

この章では、MySQL データベースのデータ破損のチェック方法およびその対処方法について説明します。テーブルが頻繁に破損する場合は、原因を突き止める必要があります。 See 項A.4.1. 「MySQL が何度もクラッシュする場合に行うこと」

MyISAM テーブルのセクションで、テーブルが破損する原因を示しています。 See 項7.1.3. 「MyISAM テーブルの問題」

クラッシュをリカバリする際には、データベース内のテーブル tbl_name のそれぞれがデータベースディレクトリ内の次の 3 つのファイルに対応していることを理解しておく必要があります。

ファイル用途
tbl_name.frmテーブル定義ファイル
tbl_name.MYDデータファイル
tbl_name.MYIインデックスファイル

これら 3 つのファイルタイプはいずれもさまざまな形で破損する可能性がありますが、特にデータファイルとインデックスファイルに問題がよく発生します。

myisamchk は、.MYD(データ)ファイルのコピーをレコードごとに生成します。修復の最終段階で古い .MYD ファイルを削除し、新規ファイルをオリジナルの名前に変更します。--quick を使用している場合、myisamchk はテンポラリ .MYD ファイルを生成しませんが、代わりに .MYD ファイルが正常であるとみなし、.MYD ファイルに手を加えずに新規インデックスファイルだけを生成します。.MYD ファイルに問題があった場合は myisamchk が自動的に検知して修復を中止するため、この方法も安全です。2 つの --quick オプションを myisamchk に設定することもできます。この場合、myisamchk はいくつかのエラー(重複キーなど)でも中止せず、.MYD ファイルを修正して解決しようとします。通常の修復処理にディスクの空き容量では足りない場合にのみ、2 つの --quick オプション指定が役立ちます。この場合、少なくとも myisamchk を実行する前にバックアップを作成しておいてください。

4.5.6.8. テーブルのエラーチェック方法

MyISAM テーブルをチェックするには、以下のコマンドを使用します。

  • myisamchk tbl_name

    これで、エラーのほとんどは発見できる。これで発見できないエラーは、データファイルだけに関連する破損である(これは非常にまれ)。テーブルをチェックする場合、通常、myisamchk をオプションなしか、-s または --silent のオプションで実行する。

  • myisamchk -m tbl_name

    これで、エラーのほとんどは発見できる。このコマンドを実行すると、最初にすべてのインデックスエントリのエラーがチェックされ、次にすべてのレコードが読み込まれる。レコードのすべてのキーのチェックサムが計算され、その結果がインデックスツリーのキーのチェックサムと一致するかどうか確認される。

  • myisamchk -e tbl_name

    このコマンドを実行すると、すべてのデータの完全なチェックが行われる(-e は ``extended check'' のこと)。各レコードのすべてのキーが読み取られ、チェックされ、正しいレコードが指されているか確認される。この操作は、多くのキーがある大きなテーブルでは時間がかかる。myisamchk は通常、最初のエラーが見つかった時点で停止する。詳細情報を得るには、--verbose-v)オプションを追加する。これにより、myisamchk は最大 20 のエラーが検出されるまで処理を続行する。 通常は、テーブル名以外の引数を指定しない myisamchk だけで十分である。

  • myisamchk -e -i tbl_name

    前のコマンドと似ているが、-i オプションによって myisamchk が統計情報も出力する。

4.5.6.9. テーブルの修復方法

このセクションでは、MyISAM テーブル(.MYI および .MYD の拡張子)に対して myisamchk を使用する方法について説明します。ISAM テーブル(.ISM および .ISD の拡張子)に対しては、isamchk を使用してください。

MySQL バージョン 3.23.14 以降、REPAIR TABLE コマンドで MyISAM テーブルを修復できるようになっています。 See 項4.5.5. 「REPAIR TABLE 構文」

テーブル破損の症状としては、クエリが予期せず中断したり、以下のようなエラーが発生します。

  • tbl_name.frm is locked against change

  • Can't find file tbl_name.MYI (Errcode: ###)

  • Unexpected end of file

  • Record file is crashed

  • Got error ### from table handler

    perror ### を実行すると、エラーの詳細情報を取得できる。以下は、テーブルに問題があることを示す一般的なエラーである。

    shell> perror 126 127 132 134 135 136 141 144 145
    126 = Index file is crashed / Wrong file format
    127 = Record-file is crashed
    132 = Old database file
    134 = Record was already deleted (or record file crashed)
    135 = No more room in record file
    136 = No more room in index file
    141 = Duplicate unique key or constraint on write or update
    144 = Table is crashed and last repair failed
    145 = Table was marked as crashed and should be repaired
    

    注意: エラー 135(no more room in record file)は、単純な修復で直せるエラーではない。この場合、以下のコマンドを実行することが必要。

    mysql> ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
    

    この手法は、エラー 136(no more room in index file)に対しても使用できる。

他の場合についてはテーブルを修復する必要があります。通常は、myisamchk でほとんどのエラーを検出して修復できます。

修復プロセスは、以下説明するように 4 段階で構成されます。開始する前に、データベースディレクトリに移動(cd)してテーブルファイルのアクセス権を確認してください。mysqld を実行する Unix ユーザに読み取り権限があることを確認します(この確認を行うユーザにもこれらのファイルへのアクセス権が必要)。ファイルを修正する必要がある場合は、書き込み権限も必要です。

MySQL バージョン 3.23.16 以降を使用している場合は、CHECK コマンドと REPAIR コマンドを使用して MyISAM テーブルのチェックおよび修復を実行できます(できるだけ、これらのコマンドを使用してください)。 See 項4.5.4. 「CHECK TABLE 構文」。 See 項4.5.5. 「REPAIR TABLE 構文」

テーブル保守に関するセクションで、isamchk および myisamchk のオプションを説明しています。 See 項4.5.6. 「myisamchk を使用したテーブルの保守とクラッシュのリカバリ」

これらのコマンドで失敗した場合、または isamchk および myisamchk の拡張機能を使用する場合につき、以下の説明を参考にして修復作業を行ってください。

コマンドラインを使用してテーブルを修復する場合、まず、mysqld サーバをシャットダウンする必要があります。注意: mysqladmin shutdown をリモートサーバから実行した場合、mysqladmin が戻ってもしばらくの間、mysqld サーバはシャットダウンしません。すべてのクエリが停止してすべてのキーがディスクにフラッシュされた時点でシャットダウンします。

段階 1: テーブルのチェック

myisamchk *.MYI または時間に余裕があれば myisamchk -e *.MYI を実行します。-s(サイレント)オプションを使用すると、不要な情報は出力されません。

mysqld サーバが終了している場合、--update オプションを使用して myisamchk がテーブルに 'checked' のマークを付けるようにします。

myisamchk がエラーを返したテーブルだけ、修復する必要があります。そのようなテーブルについては、段階 2 へ進みます。

チェック時に複雑なエラー(out of memory エラーなど)が発生した場合、あるいは myisamchk がクラッシュした場合は段階 3 に進みます。

段階 2: 簡単で安全な修復

注意: 修復を速く行うには、-O sort_buffer=# -O key_buffer=#(# は利用可能メモリの約 4 分の 1)をすべての isamchk/myisamchk コマンドに追加します。

最初に myisamchk -r -q tbl_name-r -q は ``クイックリカバリモード'' の意)を実行します。これにより、データファイルを変更せずにインデックスファイルの修復だけが行われます。データファイルにあるべきものがすべてあり、削除リンクがデータファイル内の正しい場所を指していれば、テーブルは正常に修復されます。成功したら、次のテーブルの修復を開始します。失敗した場合は以下の手順を実行します。

  1. まず、データファイルのバックアップを作成する。

  2. myisamchk -r tbl_name-r は ``リカバリモード'' の意)を使用する。これにより、不正なレコードと削除されたレコードがデータファイルから削除され、インデックスファイルが再構築される。

  3. 前のステップが失敗した場合、myisamchk --safe-recover tbl_name を使用する。 セーフリカバリモードにより、古いリカバリ形式が使用され、通常のリカバリモードでは処理できない修復が行われる。ただし、時間がかかる。

修復時に複雑なエラー(out of memory エラーなど)が発生した場合、あるいは myisamchk がクラッシュした場合は段階 3 に進みます。

段階 3:困難な修復

インデックスファイルの最初の 16K ブロックが破損または不正な情報を含む場合、あるいはインデックスファイルがない場合だけ、この段階に進みます。この段階では、新しいインデックスファイルを作成する必要があります。以下を実行してください。

  1. データファイルを安全な場所に移動する。

  2. テーブル記述ファイルを使用して、新しい(空白の)データとインデックスファイルを作成する。

    shell> mysql db_name
    mysql> SET AUTOCOMMIT=1;
    mysql> TRUNCATE TABLE table_name;
    mysql> quit
    

    使用している SQL バージョンに TRUNCATE TABLE がない場合は、代わりに DELETE FROM table_name を使用する。

  3. 古いデータファイルを、新しく作成したデータファイルにコピーする (単に古いファイルを新しいファイルに移動するのではなく、万一に備えて元の場所にも残しておく)。

段階 2 に戻ります。これで、myisamchk -r -q が機能するはずです(無限ループにならないはずです)。

MySQL 4.0.2 より、この手順全体を自動で実行する REPAIR ... USE_FRM も使用できるようになりました。

段階 4: 非常に困難な修復

記述ファイルもクラッシュしている場合にのみこの段階に進みます。ただし、テーブル作成後に記述ファイルが変更されることはないので、通常は発生しない状況です。

  1. バックアップから記述ファイルをリストアし、段階 3 に戻る。インデックスファイルをリストアして段階 2 に戻ることもできる。後者の場合、myisamchk -r を実行する。

  2. バックアップがない場合でも、テーブルがどのように作成されたか正確にわかっていれば、別のデータベースにテーブルのコピーを作成する。テーブルのコピーを作成したデータベースから、新しいデータファイルを削除し、記述ファイルとインデックスファイルを、クラッシュしたデータベースに移動する。これで新しい記述ファイルとインデックスファイルができ、データファイルは前のものがそのまま残る。段階 2 に戻り、インデックスファイルを再構築する。

4.5.6.10. テーブルの最適化

断片化したレコードを結合したり、レコードの削除または更新によって発生した無駄なスペースを除去するには、myisamchk をリカバリモードで実行します。

shell> myisamchk -r tbl_name

同様に、SQL の OPTIMIZE TABLE ステートメントを使用して、テーブルを最適化することもできます。OPTIMIZE TABLE はテーブルの修復とキー分析を行い、さらにインデックスツリーをソートして、キー走査の処理速度を上げます。 また、OPTIMIZE TABLE を使用した場合、サーバ側ですべての処理が行われるため、ユーティリティとサーバ間で不要なやり取りが発生しません。 See 項4.6.1. 「OPTIMIZE TABLE 構文」

myisamchk には、テーブルのパフォーマンスを向上させるためのオプションが数多く用意されています。

  • -S, --sort-index

  • -R index_num, --sort-records=index_num

  • -a, --analyze

オプションの詳細な説明については、See 項4.5.6.1. 「myisamchk 起動構文」 を参照してください。

4.5.7. テーブル保守計画

MySQL バージョン 3.23.13 以降、CHECK TABLE コマンドを使用して MyISAM テーブルをチェックできるようになりました。See 項4.5.4. 「CHECK TABLE 構文」。 テーブルの修復は REPAIR TABLE コマンドで行えます。 See 項4.5.5. 「REPAIR TABLE 構文」

問題が発生するのを待つより、定期的にテーブルチェックを行うことを推奨します。保守目的では、myisamchk -s を使用してテーブルをチェックできます。-s オプション(--silent の短縮形)を使用すると、サイレントモードで myisamchk が実行され、エラー発生時のみメッセージが出力されます。

また、サーバが起動するたびにテーブルをチェックするという方法もあります。 たとえば、更新の途中でマシンがリブートされた場合、影響を受けた可能性のあるテーブルをすべてチェックする必要があります(つまり、``破損の可能性があるテーブル'' をチェックします)。リブート後に古い .pid(プロセス ID)ファイルが残っていた場合、mysqld_safe にテストを追加して、直前の 24 時間以内に変更されたテーブルのチェックを myisamchk で実行することができます。.pid ファイルは mysqld 起動時に作成され、正常終了時に削除されます。システム起動時に .pid ファイルが存在していれば、mysqld が異常終了したことになります。

より完全なテストを行うには、.pid ファイルの作成後に変更されたすべてのテーブルをチェックするという方法もあります。

通常のシステム運用中にも定期的にテーブルをチェックしてください。MySQL AB では、週に一度 cron ジョブを実行して重要なテーブルをチェックしています。crontab ファイルは以下のようになります。

35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

これで、クラッシュしたテーブルに関する情報が出力されるので、必要に応じて検査および修復を行えます。

ここ数年、予想外のテーブル破損(ハードウェアトラブル以外による破損)は発生していないので、当社では週に一度のチェックで十分としています。

最初のうちは、myisamchk -s を毎晩実行して、直前の 24 時間以内に更新されたすべてのテーブルをチェックするようにします。しばらくすると、MySQL の信頼性の高さを実感できるはずです。

通常、MySQL テーブルの保守はそれほど頻繁に行う必要はありません。動的サイズのレコード(VARCHAR カラム、BLOB カラム、または TEXT カラム)があるテーブルを変更したり、多くのレコードが削除されたテーブルがある場合には、月に一度程度、最適化を行ってテーブルの領域を解放することを推奨します。

これを行うには、目的のテーブルで OPTIMIZE TABLE を実行するか、mysqld サーバを停止して以下を実行します。

isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
myisamchk -r --silent --sort-index  -O sort_buffer_size=16M */*.MYI

4.5.8. テーブル情報の取得

テーブルに関する情報またはその統計を取得するには、以下のコマンドを実行します。これらの情報については後で詳しく説明します。

  • myisamchk -d tbl_name myisamchk を ``describe モード'' で実行し、テーブル情報を生成する。--skip-external-locking オプションを使用して MySQL サーバを起動した場合、myisamchk は、実行中に更新されたテーブルに対してエラーを報告する場合がある。しかし、myisamchk は describe モードではテーブルを変更しないため、データ破壊の危険性はない。

  • myisamchk -d -v tbl_name myisamchk の実行中の処理に関する詳細な情報を取得するには、-v を追加して冗長モードで実行する。

  • myisamchk -eis tbl_name テーブルの最重要情報のみ表示する。テーブル全体を読み取ることになるので、時間がかかる。

  • myisamchk -eiv tbl_name -eis とほぼ同じであるが、このオプションを使用すると、進行中の処理も表示される。

myisamchk -d による出力例

MyISAM file:     company.MYI
Record format:   Fixed length
Data records:    1403698  Deleted blocks:         0
Recordlength:    226

table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text

myisamchk -d -v による出力例

MyISAM file:         company
Record format:       Fixed length
File-version:        1
Creation time:       1999-10-30 12:12:51
Recover time:        1999-10-31 19:13:01
Status:              checked
Data records:           1403698  Deleted blocks:              0
Datafile parts:         1403698  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length: 3791650815  Max keyfile length: 4294967294
Recordlength:               226

table description:
Key Start Len Index   Type                  Rec/key     Root Blocksize
1   2     8   unique  double                      1 15845376      1024
2   15    10  multip. text packed stripped        2 25062400      1024
3   219   8   multip. double                     73 40907776      1024
4   63    10  multip. text packed stripped        5 48097280      1024
5   167   2   multip. unsigned short           4840 55200768      1024
6   177   4   multip. unsigned long            1346 65145856      1024
7   155   4   multip. text                     4995 75090944      1024
8   138   4   multip. unsigned long              87 85036032      1024
9   177   4   multip. unsigned long             178 96481280      1024
    193   1           text

myisamchk -eis による出力例

Checking MyISAM file: company
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%

Records:          1403698    M.recordlength:     226
Packed:             0%
Recordspace used:     100%   Empty space:          0%
Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966

myisamchk -eiv による出力例

Checking MyISAM file: company
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%

- check records and index references
[LOTS OF ROW NUMBERS DELETED]

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798

上記の例で使用されたテーブルのデータファイルおよびインデックスファイルのサイズは以下のとおりです。

-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 company.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 company.MYI

以下、myisamchk が生成する情報のタイプについて説明します。``キーファイル'' とはインデックスファイルのことです。``レコード'' と ``ロー'' はシノニムです。

  • ISAM file ISAM(インデックス)ファイルの名前。

  • Isam-version ISAM 形式のバージョン。現在は常に 2。

  • Creation time データファイルの作成日時。

  • Recover time インデックスまたはデータファイルが前回再構築された日時。

  • Data records テーブル内のレコード数。

  • Deleted blocks 予約済み領域をまだ占有している削除済みのブロック数。 テーブルを最適化して、この領域を最小にできる。 See 項4.5.6.10. 「テーブルの最適化」

  • Data file:Parts 動的なレコード形式に対しては、存在するデータブロック数。断片化されたレコードのない最適化されたテーブルに対しては、Data records と同じ。

  • Deleted data 領域が解放されていない削除済みデータのバイト数。 テーブルを最適化して、この領域を最小にできる。 See 項4.5.6.10. 「テーブルの最適化」

  • Data file pointer データファイルポインタのサイズ(バイト単位)。通常は 2、3、4、または 5 バイト。ほとんどのテーブルは 2 バイトで足りるが、現在のところ、MySQL で制御することはできない。固定テーブルでは、これはレコードアドレス。動的テーブルでは、バイトアドレス。

  • Keyfile pointer インデックスファイルポインタのサイズ(バイト単位)。通常は 1、2、または 3 バイト。ほとんどのテーブルは 2 バイトで足りるが、MySQL によって自動的に計算される。常にブロックアドレスである。

  • Max datafile length テーブルのデータファイル(.MYD ファイル)の最大長(バイト単位)。

  • Max keyfile length テーブルのキーファイル(.MYI ファイル)の最大長(バイト単位)。

  • Recordlength 各レコードが使用する領域サイズ(バイト単位)。

  • Record format テーブルレコードの格納形式。 上記の例では Fixed length を使用。 他に、Compressed および Packed がある。

  • table description テーブル内のすべてのキーの一覧。各キーについて、以下の低レベル情報が表示される。

    • Key キー番号。

    • Start インデックス部が始まるレコード内の位置。

    • Len インデックス部の長さ。パックされた数値の場合、これは常にそのカラムの全長となる。文字列の場合、文字列カラムのプリフィックスをインデックスにできるため、インデックス化されたカラムの全長よりも短くなる場合がある。

    • Index unique または multip.(複数)。このインデックスに値の重複が認められているかどうかを示す。

    • Type インデックス部のデータ型。packedstripped、または empty のいずれかの ISAM データ型。

    • Root ルートインデックスブロックのアドレス。

    • Blocksize 各インデックスブロックのサイズ。デフォルトでは 1024 であるが、コンパイル時に変更可能。

    • Rec/key オプティマイザによって使用される統計値。このキーの値ごとのレコード数を示す。ユニークキーの値は常に 1。これは、myisamchk -a でテーブルがロード(または大きく変更)されると更新される。まったく更新されない場合は、デフォルト値の 30 となる。

  • 上の最初の例の 9 番目のキーは 2 つのパートを持つマルチパートキー。

  • Keyblocks used 使用されたキーブロックのパーセント。例で使用されたテーブルは myisamchk で再構成されたばかりなので、値は非常に高い(理論的な最大値に非常に近い)。

  • Packed MySQL は共通のサフィックスでキーのパックを試みる。これは、CHARVARCHARDECIMAL の各キーにのみ使用できる。名前のような長い文字列では、パックにより使用領域を大きく減らすことができる。上の 3 番目の例では、4 番目のキーが 10 文字長で、領域が 60 パーセント減少している。

  • Max levels このキーの B-tree の深さ。長いキーのある大きなテーブルでは、値が高くなる。

  • Records テーブル内のレコード数。

  • M.recordlength レコードの平均の長さ。固定長レコードのテーブルでは、これは実際のレコード長となる。

  • Packed MySQL は、文字列の最後からスペースを削除する。Packed 値は、これによって節約されたパーセントを示す。

  • Recordspace used 使用されているデータファイルのパーセント。

  • Empty space 使用されていないデータファイルのパーセント。

  • Blocks/Record レコードごとの平均ブロック数(断片化レコードを構成するリンク数)。これは、固定形式テーブルでは常に 1.0。この値は可能な限り、1.0 に近くしておく。大きくなりすぎた場合は、myisamchk で再編成できる。 See 項4.5.6.10. 「テーブルの最適化」

  • Recordblocks 使用されているブロック(リンク)数。固定形式では、レコード数と同じになる。

  • Deleteblocks 削除されたブロック(リンク)数。

  • Recorddata 使用されているデータファイルのバイト数。

  • Deleted data 削除された(使用されていない)データファイルのバイト数。

  • Lost space レコードの長さを短くして更新した場合、領域がいくらか失われる。その失われた領域の合計バイト数。

  • Linkdata 動的テーブル形式では、レコードの断片がポインタでリンクされている(それぞれ 4 ? 7 バイト)。Linkdata は、そのようなポインタすべてに使用されているストレージ量の合計を示す。

テーブルが myisampack で圧縮されている場合、myisamchk -d を実行すると、各テーブルカラムに関する追加情報が出力されます。これらの情報およびその意味については、項4.8.4. 「myisampack(MySQL 圧縮読み取り専用テーブルジェネレータ)」 を参照してください。

4.6. データベース管理言語リファレンス

4.6.1. OPTIMIZE TABLE 構文

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name]...

OPTIMIZE TABLE は、テーブルの大部分を削除したり、可変長レコードを持つテーブル(VARCHAR カラム、BLOB カラム、または TEXT カラムを持つテーブル)に多くの変更を加えた場合に使用します。 削除されたレコードはリンクされたリストに保持され、元のレコード位置は、後続の INSERT 操作により再利用されます。OPTIMIZE TABLE を使用して未使用領域を解放し、データファイルを最適化することができます。

ほとんどの場合、OPTIMIZE TABLE を実行する必要はありません。可変長レコードに更新を多く行う場合でも、週または月に一度、特定のテーブルだけに実行するだけで十分です。

現在のところ、OPTIMIZE TABLEMyISAM テーブル、 BDB およびInnoDBテーブルにのみ有効です。BDB テーブルでは、OPTIMIZE TABLE は現在 ANALYZE TABLE にマップされます。 See 項4.6.2. 「ANALYZE TABLE 構文」

mysqld--skip-new または --safe-mode で起動することにより、OPTIMIZE TABLE を他のテーブルタイプにでも使用できるようになります。しかしこの場合、OPTIMIZE TABLEALTER TABLE にマップされます。

OPTIMIZE TABLE は以下のように動作します。

  • テーブルに削除されたレコードまたは分割されたレコードがある場合、テーブルを修復する。

  • インデックスページがソートされていない場合、ソートする。

  • 統計が最新でなければ(およびインデックスのソートによる修復ができなかった場合)統計を更新する。

注意: OPTIMIZE TABLE の実行中、テーブルはロックされます。

MySQL 4.1.1 より前のバージョンを使用している場合、OPTIMIZE コマンドはバイナリログに記録されません。MySQL 4.1.1 以降を使用している場合は、オプションの NO_WRITE_TO_BINLOG キーワード(またはそのエイリアスの LOCAL)を使用していない限り、バイナリログに記録されます。

4.6.2. ANALYZE TABLE 構文

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name[,tbl_name...]

テーブルのキー分布を分析して保存します。分析中、テーブルは読み取りロックされます。このコマンドは、MyISAM テーブルと BDB テーブルに対して使用できます。

これは、テーブルに対して myisamchk -a を実行するのと同じです。

定数を条件としない結合を実行する場合、MySQL は保存されたキー分布を使用して、テーブルの結合順序を決定します。

このコマンドは、以下のカラムで構成されるテーブルを返します。

カラム
Tableテーブル名
Op常に analyze
Msg_typestatuserrorinfowarning のいずれか
Msg_textメッセージ

保存されたキー分布をチェックするには、SHOW INDEX コマンドを使用します。 See 項4.6.8.1. 「データベース、テーブル、カラム、およびインデックスに関する情報の取得」

前回の ANALYZE TABLE コマンドを実行した後でテーブルが変更されていない場合、テーブルに対して再度分析は実行されません。

MySQL 4.1.1 より前のバージョンを使用している場合、ANALYZE コマンドはバイナリログに記録されません。MySQL 4.1.1 以降を使用している場合は、オプションの NO_WRITE_TO_BINLOG キーワード(またはそのエイリアスの LOCAL)を使用していない限り、バイナリログに記録されます。

4.6.3. CHECKSUM TABLE 構文

CHECKSUM TABLE tbl_name[,tbl_name ...] [ QUICK | EXTENDED ]

テーブルのチェックサムを報告します。QUICK を指定した場合、現時点のテーブルのチェックサムが報告されます。または、テーブルがチェックサムをサポートしていない場合は NULL が返されます。この処理時間は非常に短くて済みます。EXTENDED モードでは、テーブル全体がレコードごとに読み取られ、チェックサムが計算されます。大きなテーブルの場合は時間がかかります。デフォルトでは(QUICK でも EXTENDED でもない場合)、テーブルがチェックサムをサポートしていれば、現時点のチェックサムが返され、サポートしていなければ、テーブルがスキャンされます。

このコマンドは、MySQL 4.1.1 で導入されました。

4.6.4. FLUSH 構文

FLUSH [LOCAL | NO_WRITE_TO_BINLOG] flush_option [,flush_option] ...

MySQL が使用している内部キャッシュを消去するには、FLUSH コマンドを使用します。FLUSH を実行するには、RELOAD 権限が必要です。

flush_option には、以下のいずれかを指定できます。

オプション説明
HOSTSホストキャッシュテーブルを空にする。ホストが IP アドレスを変更した場合や、エラーメッセージ Host ... is blocked が表示される場合には、ホストテーブルをフラッシュすることが必要である。MySQL サーバとの接続中に、特定のホストの 1 つのレコードで max_connect_errors を超えるエラーが発生した場合、MySQL は問題があると判断し、以後、ホストからの接続要求をブロックする。 ホストテーブルをフラッシュすると、ホストが再び接続可能になる。See 項A.2.5. 「Host '...' is blocked エラー」mysqld-O max_connect_errors=999999999 で起動すると、このエラーを回避できる。
DES_KEY_FILEサーバ起動時に --des-key-file オプションで指定されたファイルから、DES キーを再度読み込む。
LOGSすべてのログファイルを閉じて、再び開く。 更新ログファイルまたはバイナリログファイルを拡張子なしで指定している場合、ログファイルの拡張子番号は前のファイルに 1 を加算した数になる。ファイル名に拡張子を使用している場合、MySQL は更新ログファイルを閉じて、再び開く。 See 項4.10.3. 「更新ログ」。 これは、SIGHUP シグナルを mysqld サーバに送信するのと同じである。
PRIVILEGESmysql データベースの権限テーブルから権限を再読み込みする。
QUERY CACHEクエリキャッシュを最適化し、メモリの使用効率を高める。このコマンドは RESET QUERY CACHE とは異なり、キャッシュからクエリを削除しない。
TABLES開いているテーブルをすべて閉じる。使用中のテーブルも強制的に閉じる。これにより、クエリキャッシュもフラッシュされる。
[TABLE | TABLES] tbl_name [,tbl_name...]指定したテーブルだけをフラッシュする。
TABLES WITH READ LOCK開いているテーブルをすべて閉じ、すべてのデータベースの全テーブルを読み取りロックする。このロックは UNLOCK TABLES を実行するまで解除されない。適宜スナップショットを取ることができる Veritas などのファイルシステムを使用している場合には、このコマンドがバックアップの作成に非常に便利である。
STATUSほとんどのステータス変数を 0 にリセットする。これは、クエリをデバッグするときにのみ使用する。
USER_RESOURCESすべてのユーザリソースを 0 にリセットする。これにより、ブロックされていたユーザも再度ログイン可能になる。 See 項4.4.7. 「ユーザリソースの制限」

MySQL 4.1.1 より前のバージョンを使用している場合、FLUSH コマンドはバイナリログに記録されません。MySQL 4.1.1 以降のバージョンを使用している場合には、オプションの NO_WRITE_TO_BINLOG キーワード(またはそのエイリアスの LOCAL)を使用していない限り、バイナリログに記録されます。また、このコマンドに LOGSMASTERSLAVETABLES WITH READ LOCK のいずれかの引数が含まれる場合も、バイナリログに記録されません。これらの引数はスレーブにレプリケートされると問題が発生する可能性があります。

上記コマンドのうちのいくつかには、mysqladmin ユーティリティで flush-hostsflush-logsflush-privilegesflush-statusflush-tables の各コマンドを使用してアクセスすることもできます。

レプリケーションで使用する RESET コマンドも参照してください。 See 項4.6.5. 「RESET 構文」

4.6.5. RESET 構文

RESET reset_option [,reset_option] ...

RESET コマンドは設定をリセットします。FLUSH コマンドのより強力なバージョンとしても機能します。 See 項4.6.4. 「FLUSH 構文」

RESET を実行するには、RELOAD 権限が必要です。

オプション説明
MASTERインデックスファイル内のすべてのバイナリログを削除し、バイナリログインデックスファイルを空白にリセットする。これは、以前の FLUSH MASTER。 See 項4.11.7. 「マスタサーバを制御する SQL ステートメント」
SLAVEスレーブから、マスタバイナリログ内の自分のレプリケーション位置を消去する。これは、以前の FLUSH SLAVE。 See 項4.11.8. 「スレーブサーバを制御する SQL ステートメント」
QUERY CACHEクエリキャッシュからすべてのクエリ結果を削除する。

4.6.6. PURGE MASTER LOGS 構文

PURGE {MASTER|BINARY} LOGS TO binlog_name
PURGE {MASTER|BINARY} LOGS BEFORE date

このコマンドは、指定したバイナリログまたは指定日より前のバイナリログをすべて削除する場合に使用します。 See 項4.11.7. 「マスタサーバを制御する SQL ステートメント」

PURGE MASTER LOGS のシノニムとして PURGE BINARY LOGS が MySQL 4.1.1 から利用可能になっています。

4.6.7. KILL 構文

KILL thread_id

mysqld の各接続はスレッドごとに行われます。SHOW PROCESSLIST コマンドで、どのスレッドが使用されているか知ることができます。また、KILL thread_id コマンドで、スレッドを強制終了できます。

PROCESS 権限があれば、すべてのスレッドを照会することができます。 SUPER 権限があれば、すべてのスレッドを強制終了できます。 上記の権限がない場合は、自分のスレッドだけ照会および強制終了できます。

mysqladmin processlist コマンドおよび mysqladmin kill コマンドでも、スレッドを確認および強制終了できます。

注意: 現在のところ、組み込み MySQL サーバライブラリでは KILL を使用できません。組み込みサーバは、ホストアプリケーションのスレッド内部で実行するだけで、独自の接続スレッドは作成しません。

KILL を実行すると、スレッド固有の kill flag がスレッドに設定されます。

キルフラグは一定間隔でチェックされるため、多くの場合、スレッドが終了するまでにしばらく時間がかかります。

  • SELECTORDER BYGROUP BY の各ループでは、レコードのブロックが 1 つ読み取られるたびにフラグがチェックされます。キルフラグが設定されていれば、ステートメントは停止します。

  • ALTER TABLE を実行した場合、オリジナルのテーブルからレコードの各ブロックが読み取られる前に、キルフラグがチェックされます。キルフラグが設定されていればコマンドは停止し、テンポラリテーブルは削除されます。

  • UPDATE または DELETE を実行した場合、各ブロックが読み取られた後、および更新レコードまたは削除レコードの後で、キルフラグがチェックされます。キルフラグが設定されていれば、ステートメントは停止します。注意: トランザクションを使用していない場合、変更はロールバックされません。

  • GET_LOCK()NULL で停止します。

  • INSERT DELAYED スレッドは、そのメモリにあるすべてのレコードをすばやくフラッシュし、終了します。

  • スレッドがテーブルロックハンドラ内にある場合(Locked 状態)、テーブルロックがすばやく解除されます。

  • スレッドが write コールで空きディスク容量を待っている場合、disk full のエラーメッセージで書き込みが停止します。

4.6.8. SHOW 構文

   SHOW DATABASES [LIKE wild]
か SHOW [OPEN] TABLES [FROM db_name] [LIKE wild]
か SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
か SHOW INDEX FROM tbl_name [FROM db_name]
か SHOW TABLE STATUS [FROM db_name] [LIKE wild]
か SHOW STATUS [LIKE wild]
か SHOW VARIABLES [LIKE wild]
か SHOW [BDB] LOGS
か SHOW [FULL] PROCESSLIST
か SHOW GRANTS FOR user
か SHOW CREATE TABLE table_name
か SHOW MASTER STATUS
か SHOW MASTER LOGS
か SHOW SLAVE STATUS
か SHOW WARNINGS [LIMIT row_count]
か SHOW ERRORS [LIMIT row_count]
か SHOW TABLE TYPES

SHOW を実行すると、データベース情報、テーブル情報、カラム情報、またはサーバのステータス情報が提供されます。LIKE wild を使用した場合、wild 文字列内に SQL の ‘%’ および ‘_’ のワイルドカード文字を使用できます。

4.6.8.1. データベース、テーブル、カラム、およびインデックスに関する情報の取得

tbl_name FROM db_name 構文の代わりに db_name.tbl_name を使用することもできます。以下の 2 つのステートメントは同じです。

mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;

SHOW DATABASES は、MySQL サーバホスト上のデータベースを一覧表示します。 mysqlshow コマンドラインツールを使用しても、この一覧を取得できます。 バージョン 4.0.2 では、ユーザにグローバル SHOW DATABASES 権限がない場合、そのユーザが何らかの権限を持つデータベースのみ表示されます。

SHOW TABLES は、指定したデータベースのテーブルを一覧表示します。mysqlshow db_name コマンドを使用しても、この一覧を取得できます。

注意: ユーザにテーブルに対する権限が何もない場合、SHOW TABLES および mysqlshow db_name の出力にそのテーブルは含まれません。

SHOW OPEN TABLES は、テーブルキャッシュで現在開いているテーブルを一覧表示します。See 項5.4.7. 「MySQL でのテーブルのオープンとクローズの方法」Comment フィールドは、テーブルが何回キャッシャされ使用されたかを示します。

SHOW COLUMNS は、指定したテーブルのカラムを一覧表示します。FULL オプションを指定した場合、ユーザが各カラムに持つ権限も表示されます。カラム情報で示されるカラムの型は、CREATE TABLE ステートメントで指定したものと異なっている場合があります。これは、カラムの型が MySQL によって自動的に変更されることがあるためです。 See 項6.5.3.1. 「カラムの暗黙的な変更」。 MySQL 4.1 から、FULL キーワードにより、カラム別コメントも表示されるようになりました。

DESCRIBE ステートメントでも SHOW COLUMNS と同様の情報が出力されます。 See 項6.6.2. 「DESCRIBE 構文(カラムに関する情報の取得)」

SHOW FIELDSSHOW COLUMNS のシノニムで、SHOW KEYSSHOW INDEX のシノニムです。mysqlshow db_name tbl_name および mysqlshow -k db_name tbl_name でも、テーブルのカラムまたはインデックスを一覧表示できます。

SHOW INDEX は、ODBC での SQLStatistics 呼び出しとよく似た形式でインデックス情報を返します。以下のカラムが返されます。

カラム意味
Tableテーブル名。
Non_uniqueインデックスに重複が許されない場合は 0、許される場合には 1。
Key_nameインデックス名。
Seq_in_indexインデックスのカラムシーケンス番号。1 から始まる。
Column_nameカラム名。
Collationインデックスでのカラムのソート方法。 MySQL ではこれは ‘A’(昇順)または NULL(ソートしない)になる。
Cardinalityインデックス内のユニークな値の数。 これは、isamchk -a の実行によって更新される。
Sub_partカラムが部分的にインデックスになっている場合は、インデックスになっている文字数。 キー全体がインデックスになっている場合は NULL
Nullカラムに NULL を含めることができれば 'YES'。
Index_type使用されるインデックス方式。
Commentさまざまなコメント。現在のところ、MySQL 4.0.2 より前のバージョンでは、インデックスが FULLTEXT か否かを表示。

注意: Cardinality は整数で保存された統計情報に基づいてカウントされるため、小さなテーブルについては正確であると限りません。

Null カラムおよび Index_type カラムは MySQL 4.0.2 で追加されました。

4.6.8.2. SHOW TABLE STATUS

SHOW TABLE STATUS [FROM db_name] [LIKE wild]

SHOW TABLE STATUS(バージョン 3.23 で導入)は SHOW STATUS と似た働きをしますが、各テーブルに関する多くの情報を提供します。mysqlshow --status db_name コマンドを使用しても、この一覧を取得することができます。 以下のカラムが返されます。

カラム意味
Nameテーブル名。
Typeテーブル型。 See 章?7. MySQL のテーブル型
Row_formatレコードの保存形式(Fixed、Dynamic、または Compressed)。
Rowsレコードの数。
Avg_row_lengthレコードの平均長。
Data_lengthデータファイルの長さ。
Max_data_lengthデータファイルの最大長。 固定レコード形式では、テーブルのレコードの最大数になる。 動的レコード形式では、テーブルに保存できるデータバイト数の合計(データポインタサイズの使用が前提)。
Index_lengthインデックスファイルの大きさ。
Data_free割り当てられているが未使用のバイト数。
Auto_increment次の自動インクリメント値。
Create_timeテーブル作成時刻。
Update_time前回のデータファイル更新時刻。
Check_time前回のテーブルチェック時刻。
Collationテーブルのキャラクタセットと照合順序(4.1.1 で導入)。
Checksumチェックサム値(ある場合)(4.1.1 で導入)。
Create_optionsCREATE TABLE で使用される拡張オプション。
Commentテーブル作成時のコメント(または MySQL がテーブル情報にアクセスできない理由)。

InnoDB テーブルでは、テーブルコメントにテーブルの空き領域が報告されます。

4.6.8.3. SHOW STATUS

SHOW STATUS は、サーバのステータス情報を提供します(mysqladmin extended-status と同様)。出力は以下のようになります(形式と数値は場合によって異なります)。

+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
| Delayed_insert_threads   | 0          |
| Delayed_writes           | 0          |
| Delayed_errors           | 0          |
| Flush_commands           | 1          |
| Handler_delete           | 462604     |
| Handler_read_first       | 105881     |
| Handler_read_key         | 27820558   |
| Handler_read_next        | 390681754  |
| Handler_read_prev        | 6022500    |
| Handler_read_rnd         | 30546748   |
| Handler_read_rnd_next    | 246216530  |
| Handler_update           | 16945404   |
| Handler_write            | 60356676   |
| Key_blocks_used          | 14955      |
| Key_read_requests        | 96854827   |
| Key_reads                | 162040     |
| Key_write_requests       | 7589728    |
| Key_writes               | 3813196    |
| Max_used_connections     | 0          |
| Not_flushed_key_blocks   | 0          |
| Not_flushed_delayed_rows | 0          |
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
| Select_full_join         | 0          |
| Select_full_range_join   | 0          |
| Select_range             | 99646      |
| Select_range_check       | 0          |
| Select_scan              | 30802      |
| Slave_running            | OFF        |
| Slave_open_temp_tables   | 0          |
| Slow_launch_threads      | 0          |
| Slow_queries             | 0          |
| Sort_merge_passes        | 30         |
| Sort_range               | 500        |
| Sort_rows                | 30296250   |
| Sort_scan                | 4650       |
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+

上記のステータス変数にはそれぞれ以下のような意味があります。

変数意味
Aborted_clients接続を閉じる前にクライアントが終了してしまったために中断された接続数。 See 項A.2.10. 「通信エラー/Aborted connection」
Aborted_connectsMySQL サーバへの接続試行失敗回数。 See 項A.2.10. 「通信エラー/Aborted connection」
Bytes_receivedすべてのクライアントから受信したバイト数。
Bytes_sentすべてのクライアントに送信されたバイト数。
Com_xxx各 xxx コマンドの実行回数。
ConnectionsMySQL サーバへの接続試行回数。
Created_tmp_disk_tablesステートメント実行中に、ディスク上に作成された暗黙的テンポラリテーブルの数。
Created_tmp_tablesステートメント実行中に、メモリ上に作成された暗黙的テンポラリテーブルの数。
Created_tmp_filesmysqld が作成したテンポラリファイルの数。
Delayed_insert_threadsINSERT DELAYED ハンドラスレッドの数。
Delayed_writesINSERT DELAYED で書き込まれたレコードの数。
Delayed_errorsエラー発生(重複キーの可能性が高い)により、INSERT DELAYED で書き込まれたレコードの数。
Flush_commandsFLUSH コマンドの実行回数。
Handler_commit内部 COMMIT コマンド数。
Handler_deleteテーブルからレコードが削除された回数。
Handler_read_first最初のエントリがインデックスから読み取られた回数。 この値が大きい場合、サーバが何回もフルインデックススキャンを実行していると考えられる。たとえば、SELECT col1 FROM foo を実行したときに col1 がインデックスになっているとそうなる。
Handler_read_keyキーに基づくレコード読み取り要求の回数。この値が大きい場合、クエリおよびテーブルが適切にインデックス化されていると考えられる。
Handler_read_nextキー順序での次のレコードの読み取り要求の回数。範囲指定をしてインデックスカラムに対してクエリを実行すると、これがインクリメントされる。インデックススキャンを実行してもインクリメントされる。
Handler_read_prevキー順序での前のレコードの読み取り要求の回数。これは主に、ORDER BY ... DESC を最適化するのに使用される。
Handler_read_rnd固定位置に基づくレコード読み取り要求の回数。 結果のソートを必要とするクエリを多く実行すると、この値が大きくなる。
Handler_read_rnd_nextデータファイルでの次のレコードの読み取り要求の回数。 テーブルスキャンが多く実行されると、この値が大きくなる。この場合、一般的に、テーブルが適切にインデックス化されていないか、クエリがインデックスを有効に利用していないかを意味する。
Handler_rollback内部 ROLLBACK コマンド数。
Handler_updateテーブル内のレコードの更新要求回数。
Handler_writeテーブルへのレコードの挿入要求回数。
Key_blocks_usedキーキャッシュの使用ブロック数。
Key_read_requestsキャッシュからのキーブロック読み取り要求回数。
Key_readsディスクからのキーブロックの物理的読み取り回数。
Key_write_requestsキャッシュへのキーブロックの書き込み要求回数。
Key_writesディスクへのキーブロックの物理的書き込み回数。
Max_used_connections同時使用可能な最大接続数。
Not_flushed_key_blocks変更されたが、ディスクへのフラッシュはまだされていないキーキャッシュのキーブロック。
Not_flushed_delayed_rowsINSERT DELAY キューで書き込みを待っているレコードの数。
Open_tables開いているテーブルの数。
Open_files開いているファイルの数。
Open_streams開いているストリームの数(主にログ用に使用)。
Opened_tables開かれたテーブルの数。
Rpl_statusフェールセーフなレプリケーションのステータス(まだ使用されていない)。
Select_full_joinキーを使用しない結合の数(この値が 0 でない場合、テーブルのインデックスをチェックする必要がある)。
Select_full_range_join参照テーブルで範囲指定の検索を使用した結合の数。
Select_range最初のテーブルの範囲指定された部分のみを使用した結合の数(通常、この値が大きくても問題にはならない)。
Select_scan最初のテーブルでフルスキャンを行った結合の数。
Select_range_check各レコードの後でキー使用をチェックする、キーを使用しない結合の数(この値が 0 でない場合、テーブルのインデックスをチェックする必要がある)。
Questionsサーバに送信されたクエリの数。
Slave_open_temp_tablesスレーブスレッドによって現在開かれているテンポラリテーブルの数。
Slave_runningマスタに接続されているスレーブの場合は ON
Slow_launch_threads生成に slow_launch_time より時間がかかったスレッドの数。
Slow_querieslong_query_time 秒より時間がかかったクエリの数。 See 項4.10.5. 「スロークエリログ」
Sort_merge_passesソートアルゴリズムで必要だったマージパスの回数。この値が大きければ、sort_buffer の値を大きくすることを考慮すべきである。
Sort_range範囲指定で行われたソートの回数。
Sort_rowsソートされたレコードの数。
Sort_scanテーブルのスキャンによって実行されたソートの回数。
ssl_xxxSSL によって使用される変数(まだ導入されていない)。
Table_locks_immediateテーブルロックがすぐに実行された回数。3.23.33 で導入。
Table_locks_waitedテーブルロックがすぐには実行されず、待機が必要だった回数。この値が大きい場合、パフォーマンス上の問題がある。まずクエリを最適化し、次にテーブルを分割するかレプリケーションを使用すべきである。3.23.33 で導入。
Threads_cachedスレッドキャッシュ内のスレッド数。
Threads_connected現在開いている接続の数。
Threads_created接続を処理するために作成されたスレッドの数。
Threads_runningスリープ状態になっていないスレッドの数。
Uptimeサーバの稼動秒数。

補足コメント

  • Opened_tables 値が大きい場合、table_cache 変数が小さすぎると考えられる。

  • Key_reads 値が大きい場合、key_buffer_size 変数が小さすぎると考えられる。キャッシュミスレートは、Key_reads/Key_read_requests で計算される。

  • Handler_read_rnd 値が大きい場合、MySQL がテーブル全体をスキャンする必要のあるクエリが多すぎるか、キーを適切に使用しない結合があると考えられる。

  • Threads_created 値が大きい場合、thread_cache_size 変数を大きくすることを考慮すべきである。キャッシュヒットレートは、Threads_created/Connections で計算される。

  • Created_tmp_disk_tables 値が大きい場合、tmp_table_size 変数を大きくして、ディスクベースではなくメモリベースでテンポラリテーブルを取得できるようにする。

4.6.8.4. SHOW VARIABLES

SHOW [GLOBAL | SESSION] VARIABLES [LIKE wild]

SHOW VARIABLES は、MySQL システム変数の値を表示します。 GLOBAL オプションおよび SESSION オプションは MySQL 4.0.3 で追加されました。 GLOBAL では、MySQL の新規接続に使用される変数を得ることができます。SESSION では、現在の接続に有効な値を得ることができます。オプションを特に指定しなければ、SESSION が使用されます。

デフォルト値が適当ではない場合には、mysqld 起動時にコマンドラインオプションを使用して、これらの変数のほとんどを変更できます。 See 項4.1.1. 「mysqld コマンドラインオプション」SET ステートメントからでも、ほとんどの変数を変更できます。 See 項5.5.6. 「SET 構文」

SHOW VARIABLES の出力は以下のようになります(形式と数値は場合によって異なります)。 mysqladmin variables コマンドを使用しても同じ情報を取得できます。

+---------------------------------+------------------------------+
| Variable_name                   | Value                        |
+---------------------------------+------------------------------|
| back_log                        | 50                           |
| basedir                         | /usr/local/mysql             |
| bdb_cache_size                  | 8388572                      |
| bdb_log_buffer_size             | 32768                        |
| bdb_home                        | /usr/local/mysql             |
| bdb_max_lock                    | 10000                        |
| bdb_logdir                      |                              |
| bdb_shared_data                 | OFF                          |
| bdb_tmpdir                      | /tmp/                        |
| bdb_version                     | Sleepycat Software: ...      |
| binlog_cache_size               | 32768                        |
| bulk_insert_buffer_size         | 8388608                      |
| character_set                   | latin1                       |
| character_sets                  | latin1 big5 czech euc_kr     |
| concurrent_insert               | ON                           |
| connect_timeout                 | 5                            |
| convert_character_set           |                              |
| datadir                         | /usr/local/mysql/data/       |
| delay_key_write                 | ON                           |
| delayed_insert_limit            | 100                          |
| delayed_insert_timeout          | 300                          |
| delayed_queue_size              | 1000                         |
| flush                           | OFF                          |
| flush_time                      | 0                            |
| ft_boolean_syntax               | + -><()~*:""&|               |
| ft_min_word_len                 | 4                            |
| ft_max_word_len                 | 84                           |
| ft_query_expansion_limit        | 20                           |
| ft_stopword_file                | (built-in)                   |
| have_bdb                        | YES                          |
| have_innodb                     | YES                          |
| have_isam                       | YES                          |
| have_raid                       | NO                           |
| have_symlink                    | DISABLED                     |
| have_openssl                    | YES                          |
| have_query_cache                | YES                          |
| init_file                       |                              |
| innodb_additional_mem_pool_size | 1048576                      |
| innodb_buffer_pool_size         | 8388608                      |
| innodb_data_file_path           | ibdata1:10M:autoextend       |
| innodb_data_home_dir            |                              |
| innodb_file_io_threads          | 4                            |
| innodb_force_recovery           | 0                            |
| innodb_thread_concurrency       | 8                            |
| innodb_flush_log_at_trx_commit  | 1                            |
| innodb_fast_shutdown            | ON                           |
| innodb_flush_method             |                              |
| innodb_lock_wait_timeout        | 50                           |
| innodb_log_arch_dir             |                              |
| innodb_log_archive              | OFF                          |
| innodb_log_buffer_size          | 1048576                      |
| innodb_log_file_size            | 5242880                      |
| innodb_log_files_in_group       | 2                            |
| innodb_log_group_home_dir       | ./                           |
| innodb_mirrored_log_groups      | 1                            |
| interactive_timeout             | 28800                        |
| join_buffer_size                | 131072                       |
| key_buffer_size                 | 16773120                     |
| language                        | /usr/local/mysql/share/...   |
| large_files_support             | ON                           |
| local_infile                    | ON                           |
| locked_in_memory                | OFF                          |
| log                             | OFF                          |
| log_update                      | OFF                          |
| log_bin                         | OFF                          |
| log_slave_updates               | OFF                          |
| log_slow_queries                | OFF                          |
| log_warnings                    | OFF                          |
| long_query_time                 | 10                           |
| low_priority_updates            | OFF                          |
| lower_case_table_names          | OFF                          |
| max_allowed_packet              | 1047552                      |
| max_binlog_cache_size           | 4294967295                   |
| max_binlog_size                 | 1073741824                   |
| max_connections                 | 100                          |
| max_connect_errors              | 10                           |
| max_delayed_threads             | 20                           |
| max_heap_table_size             | 16777216                     |
| max_join_size                   | 4294967295                   |
| max_relay_log_size              | 0                            |
| max_sort_length                 | 1024                         |
| max_user_connections            | 0                            |
| max_tmp_tables                  | 32                           |
| max_write_lock_count            | 4294967295                   |
| myisam_max_extra_sort_file_size | 268435456                    |
| myisam_repair_threads           | 1                            |
| myisam_max_sort_file_size       | 2147483647                   |
| myisam_recover_options          | force                        |
| myisam_sort_buffer_size         | 8388608                      |
| net_buffer_length               | 16384                        |
| net_read_timeout                | 30                           |
| net_retry_count                 | 10                           |
| net_write_timeout               | 60                           |
| open_files_limit                | 1024                         |
| pid_file                        | /usr/local/mysql/name.pid    |
| port                            | 3306                         |
| protocol_version                | 10                           |
| query_cache_limit               | 1048576                      |
| query_cache_size                | 0                            |
| query_cache_type                | ON                           |
| read_buffer_size                | 131072                       |
| read_rnd_buffer_size            | 262144                       |
| rpl_recovery_rank               | 0                            |
| safe_show_database              | OFF                          |
| server_id                       | 0                            |
| slave_net_timeout               | 3600                         |
| skip_external_locking           | ON                           |
| skip_networking                 | OFF                          |
| skip_show_database              | OFF                          |
| slow_launch_time                | 2                            |
| socket                          | /tmp/mysql.sock              |
| sort_buffer_size                | 2097116                      |
| sql_mode                        |                              |
| table_cache                     | 64                           |
| table_type                      | MYISAM                       |
| thread_cache_size               | 3                            |
| thread_stack                    | 131072                       |
| tx_isolation                    | READ-COMMITTED               |
| timezone                        | EEST                         |
| tmp_table_size                  | 33554432                     |
| tmpdir                          | /tmp/:/mnt/hd2/tmp/          |
| version                         | 4.0.4-beta                   |
| wait_timeout                    | 28800                        |
+---------------------------------+------------------------------+

以下、各オプションについて説明します。

バッファサイズ、長さ、およびスタックサイズの値はバイト単位です。 ‘K’ または ‘M’ のサフィックスを値に付けると、それぞれキロバイト、メガバイトを示します。たとえば、16M は 16 メガバイトです。サフィックスの大文字と小文字は区別されません。16M16m は同じです。

  • ansi_modemysqld--ansi オプションで起動している場合は ON。 See 項1.8.2. 「ANSI モードでの MySQL の実行」

  • back_log MySQL で保持できる未解決の接続要求数。これは、非常に短い間にメインの MySQL スレッドに非常に多くの接続要求が集中したときに機能する。それから、メインスレッドが接続をチェックし、新規スレッドを開始するのにいくらかの時間(ほんのわずかであるが)がかかる。back_log 値は、MySQL が瞬間的に新規要求への回答を停止するまでのこの短時間に、スタック可能な要求の数を示す。短時間に多くの接続要求が予想される場合だけ、この値を大きくする必要がある。

    言い換えると、この値は、TCP/IP 接続のリッスンキューのサイズである。使用しているオペレーティングシステムそのものにも、このキューサイズの制限がある。詳細については、Unix listen(2) システムコールのマニュアルページを参照のこと。この変数の最大値について、OS のドキュメントを参照することが必要である。back_log をオペレーティングシステムの制限値より大きくしても、効果はない。

  • basedir --basedir オプションの値。

  • bdb_cache_size BDB テーブルのインデックスとレコードをキャッシュするために割り当てられたバッファ。BDB テーブルを使用しない場合、mysqld--skip-bdb オプションで起動して、このキャッシュにメモリを使用しないようにする。

  • bdb_log_buffer_size BDB テーブルのインデックスとレコードをキャッシュするために割り当てられたバッファ。BDB テーブルを使用しない場合、この値を 0 に設定するか、mysqld--skip-bdb オプションで起動して、このキャッシュにメモリを使用しないようにする。

  • bdb_home --bdb-home オプションの値。

  • bdb_max_lock BDB テーブルで有効にできるロックの最大数(デフォルトでは 10,000)。長いトランザクションを実行しているときや、mysqld が大量のレコードを使ってクエリを実行しているときに、bdb: Lock table is out of available locks または Got error 12 from ... というエラーが発生する場合には、この数値を大きくする必要がある。

  • bdb_logdir --bdb-logdir オプションの値。

  • bdb_shared_data --bdb-shared-data を使用している場合は ON

  • bdb_tmpdir --bdb-tmpdir オプションの値。

  • binlog_cache_size。 トランザクション中にバイナリログに対する SQL ステートメントを保持するキャッシュのサイズ。大きなマルチステートメントトランザクションを頻繁に使用する場合、この値を大きくすることによりパフォーマンスを向上できる。 See 項6.7.1. 「START TRANSACTIONCOMMITROLLBACK の各構文」

  • bulk_insert_buffer_size(以前は myisam_bulk_insert_tree_size) MyISAM は特殊なツリー状のキャッシュを使用して、バルク INSERT(INSERT ... SELECTINSERT ... VALUES (...), (...), ...LOAD DATA INFILE)を高速化する。この変数により、スレッドごとのキャッシュツリーのサイズが制限される(バイト単位)。この値を 0 に設定すると、最適化は無効になる。注意: このキャッシュは、空白でないテーブルに値を追加する場合にのみ使用される。デフォルト値は 8 メガバイトである。

  • character_set デフォルトのキャラクタセット。

  • character_sets サポートされるキャラクタセット。

  • concurrent_inserts ONの場合(デフォルト)、SELECT クエリを MyISAM テーブルで実行するとき、同時に INSERT も実行できる。このオプションをオフにするには、mysqld--safe または --skip-new で起動する。

  • connect_timeout mysqld サーバが、Bad handshake を返すまでに接続パケットを待つ秒数。

  • datadir --datadir オプションの値。

  • delay_key_write MyISAM テーブルのオプション。以下のいずれかの値を指定できる。

    OFFCREATE TABLE ... DELAYED_KEY_WRITE はすべて無視される。
    ON(デフォルト)CREATE TABLEDELAY_KEY_WRITE オプションが採用される。
    ALL新しく開かれるすべてのテーブルを、DELAY_KEY_WRITE オプションで作成されたように扱う。

    DELAY_KEY_WRITE が有効の場合、このオプションのテーブルのキーバッファは、インデックスの更新ごとにはフラッシュされず、テーブルを閉じるときだけフラッシュされる。これにより、キーの書き込みはかなり速くなるが、これを使用する場合には、myisamchk --fast --force によりすべてのテーブルを自動的にチェックすべきである。

  • delayed_insert_limit delayed_insert_limit レコードを挿入後、INSERT DELAYED ハンドラは、保留中の SELECT ステートメントがないかチェックする。ある場合、ハンドラは処理を続行する前に保留中のステートメントの実行を許可する。

  • delayed_insert_timeout INSERT DELAYED スレッドが INSERT ステートメントを待機する時間。

  • delayed_queue_size INSERT DELAYED を処理するために割り当てられるキューのサイズ(レコード単位)。キューがいっぱいになると、INSERT DELAYED を実行するすべてのクライアントは、キューに空きができるまで待機する。

  • flush MySQL を --flush オプションで起動した場合は ON

  • flush_time これを 0 以外の値に設定すると、flush_time 秒ごとにすべてのテーブルが閉じられる(リソースの解放と未フラッシュデータのディスクへの同期のため)。Windows 9x/Me、その他リソースが非常に少ないシステムの場合だけ、このオプションを推奨。

  • ft_boolean_syntax MATCH ... AGAINST(... IN BOOLEAN MODE) でサポートされている演算子の一覧。 See 項6.8. 「MySQL 全文検索」

  • ft_min_word_len FULLTEXT インデックス内の単語の最短長。 注意: この変数を変更後、FULLTEXT インデックスを再ビルドする必要がある。このオプションは MySQL 4.0 で導入された。

  • ft_max_word_len FULLTEXT インデックス内の単語の最大長。 注意: この変数を変更後、FULLTEXT インデックスを再ビルドする必要がある。このオプションは MySQL 4.0 で導入された。

  • ft_query_expansion_limit クエリ拡張(MATCH ... AGAINST (... WITH QUERY EXPANSION))で使用される最上位マッチ数。このオプションは MySQL 4.1.1 で導入された。

  • ft_stopword_file 全文検索のストップワードリストが含まれているファイル。ファイル内のすべてのストップワードが使用される。コメントは使用されない。デフォルトでは、ストップワードの組み込みリストが使用される(myisam/ft_static.c で定義されているリスト)。このパラメータを空白の文字列("")に設定すると、ストップワードのフィルタリングが無効になる。注意: この変数を変更後、FULLTEXT インデックスを再ビルドする必要がある。このオプションは MySQL 4.0.10 で導入された。

  • have_innodb mysqld が InnoDB テーブルをサポートする場合は YES--skip-innodb が使用されている場合は DISABLED

  • have_bdb mysqld が Berkeley DB テーブルをサポートする場合は YES--skip-bdb が使用されている場合は DISABLED

  • have_raid mysqldRAID オプションをサポートする場合は YES

  • have_openssl mysqld がクライアントとサーバ間のプロトコルに SSL(暗号化)をサポートする場合は、YES

  • init_file サーバの起動時に --init-file オプションで指定されたファイルの名前。これは、サーバの起動時に、サーバが実行する SQL ステートメントのファイルである。

  • interactive_timeout 対話式接続を終了する前に、サーバがアクティビティを待機する秒数。対話型クライアントは、mysql_real_connect()CLIENT_INTERACTIVE オプションを使用するクライアントとして定義される。wait_timeout も参照のこと。

  • join_buffer_size 完全結合(インデックスを使用しない結合)に使用されるバッファのサイズ。2 つのテーブル間の完全結合ごとにバッファが割り当てられる。インデックスを追加できない場合に、完全結合を速くする目的でこの値を大きくする(通常、結合を速くする最良の方法はインデックスの追加である)。

  • key_buffer_size インデックスブロックはバッファされ、すべてのスレッドによって共有される。key_buffer_size は、インデックスブロック用に使用されるバッファのサイズである。

    インデックス処理(すべての読み取りと複数書き込み)のパフォーマンスを向上させるため、この値は可能な限り大きくする。主に MySQL を実行する 256M マシンでは、64M が一般的である。ただし、これを大きくしすぎると(たとえば、メモリ合計の 50% 以上など)、システムがページングを開始し、処理速度が非常に遅くなる可能性がある。MySQL ではデータ読み取りをキャッシュしないため、OS ファイルシステムのキャッシュ用に領域を確保しておくことが必要である。

    キーバッファのパフォーマンスを確認するには、SHOW STATUS を実行し、Key_read_requestsKey_readsKey_write_requestsKey_writes の各変数を調べる。Key_reads/Key_read_request の比率は通常、0.01 より小さい。Key_write/Key_write_requests の比率は、操作がほとんど更新と削除だけの場合、通常は約 1 になる。しかし、同時に多くの影響がある更新を頻繁に行う場合や、DELAY_KEY_WRITE を使用する場合はかなり小さくなることもある。 See 項4.6.8. 「SHOW 構文」

    多くのレコードを同時に書き込む場合にさらに速度を上げるには、LOCK TABLES を使用する。 See 項6.7.5. 「LOCK TABLES および UNLOCK TABLES 構文」

  • language エラーメッセージに使用する言語。

  • large_file_support mysqld が、大きなファイルをサポートするオプションでコンパイルされている場合。

  • locked_in_memory mysqld が、--memlock でメモリにロックされている場合。

  • log すべてのクエリのログを有効にしている場合。

  • log_update 更新ログを有効にしている場合。

  • log_bin バイナリログを有効にしている場合。

  • log_slave_updates スレーブからの更新をログに記録する場合。

  • long_query_time クエリがこの値(秒単位)より時間がかかると、Slow_queriesカウンタがインクリメントされる。--log-slow-queries を使用している場合、クエリはスロークエリログファイルに記録される。この値は実際の時間であり、CPU 時間ではない。したがって、負荷の軽いシステムではしきい値より下のクエリも、負荷の重いシステムではしきい値より上になる場合がある。 See 項4.10.5. 「スロークエリログ」

  • lower_case_table_names 1 に設定すると、テーブル名が小文字でディスクに格納され、テーブル名の比較で大文字と小文字が区別されなくなる。バージョン 4.0.2 以降、このオプションはデータベース名にも適用されるようになった。4.1.1 からは、テーブルエイリアスにも適用されるようになった。 See 項6.1.3. 「名前におけるケース依存」

  • max_allowed_packet 1 パケットの最大サイズ。メッセージバッファは net_buffer_length バイトに初期化されるが、必要に応じて max_allowed_packet バイトまで大きくできる。このデフォルト値は、大きな(おそらく不正)パケットを受けるには小さすぎる。大きな BLOB カラムを使用している場合には、この値を大きくする必要がある。使用する最大の BLOB と同じ大きさにすべきである。max_allowed_packet のプロトコル制限は MySQL 3.23 で 16MB、MySQL 4.0 で 1GB である。

  • max_binlog_cache_size トランザクションでこれより多くのメモリが必要になると、"Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage" エラーが発生する。

  • max_binlog_size 3.23.33 で導入された。バイナリ(レプリケーション)ログファイルへの書き込みが、この値を超える場合、ログをローテートする。設定可能値は、4096 バイト(MySQL バージョン 4.0.14 より前は 1024)から 1 ギガバイト。デフォルトは 1GB。注意: トランザクションを使用している場合、トランザクションは 1 つのまとまりでバイナリログに書き込まれるため、複数のバイナリログに分割されることはない。したがって、大きなトランザクションがある場合、バイナリログが max_binlog_size より大きくなる可能性がある。max_relay_log_size(MySQL 4.0.14 で導入)が 0 の場合、max_binlog_size がリレーログにも適用される。

  • max_connections 認められる同時クライアントの数。この値を大きくすると、mysqld が必要とするファイル記述子の数が多くなる。ファイル記述子の制限については、以下を参照のこと。 See 項A.2.6. 「Too many connections エラー」

  • max_connect_errors ホストからの接続中断回数がこの値より大きくなった場合、それ以降、そのホストからの接続はブロックされる。ホストのブロックを解除するには、FLUSH HOSTS コマンドを使用する。

  • max_delayed_threads INSERT DELAYED ステートメント処理に、この数より多くのスレッドを開始しない。すべての INSERT DELAYED スレッドが使用された後にデータを新規テーブルに挿入しようとすると、そのレコードは DELAYED 属性が指定されていないものとして挿入される。これを 0 に設定すると、max_delayed スレッドは生成されない。

  • max_heap_table_size この変数は、それ以降、新しく生成される HEAP テーブルの最大サイズを設定する。この変数の値を使用して、HEAP テーブルの MAX_ROWS 値が計算される。この変数の設定は、既存の HEAP テーブルには影響しない。ただし、CREATE TABLETRUNCATE TABLE などのステートメントで再生成したり、ALTER TABLE で変更した場合は適用される。

  • max_join_size max_join_size を超えるレコードを読み取る結合ではエラーを出力する。WHERE 節なしで時間がかかる何百万ものレコードを返す結合を実行するユーザがいる場合に、この値を設定する。

  • max_relay_log_size 4.0.14 で導入。リレーログ(レプリケーションスレーブによって使用されるログ。see 項4.11.3. 「レプリケーションの実装の詳細」)への書き込みが指定値を超える場合、リレーログをローテートする。この変数により、リレーログとバイナリログに異なるサイズの制約を加えることができる。ただし、この変数を 0 に設定すると、max_binlog_size がバイナリログとリレーログの両方に適用される。max_relay_log_size には 0、または 4097 以上 1GB 未満の値を設定できる。デフォルト値は 0。

  • max_seeks_for_key キーによるレコード検索の最大回数を制限する。MySQL オプティマイザは、キースキャンでテーブルからレコードを検索するときに、キーの基数には関係なく、キー検索の回数をこの指定値までと想定する。この値を低く(100 くらいに)設定することにより、MySQL はテーブルスキャンではなくキースキャンを優先的に行うようになる。

  • max_sort_length BLOB 値または TEXT 値をソートするときに使用するバイト数(各値の最初の max_sort_length バイトのみが使用され、残りは無視される)。

  • max_user_connections 単一ユーザのアクティブ接続の最大数(0 = 制限なし)。

  • max_tmp_tables このオプションはまだ利用不可。1 つのクライアントが同時に開いておけるテンポラリテーブルの最大数。

  • max_write_lock_count この回数の書き込みロック後、間に読み取りロックを認める。

  • myisam_recover_options --myisam-recover オプションの値。

  • myisam_sort_buffer_size REPAIR を実行するとき、あるいは CREATE INDEXまたは ALTER TABLE を使用してインデックスを作成するときに、インデックスのソートに割り当てられるバッファ。

  • myisam_max_extra_sort_file_size。 インデックスの高速作成で使用されるテンポラリファイルが、キーキャッシュを使用する場合より、指定されているサイズ分大きい場合、キーキャッシュ方式が使用される。これは主に、大きなテーブルの長い文字キーに、処理速度が遅いキーキャッシュ方式を用いてインデックスを作成させる場合に使用する。注意: このパラメータの値は、4.0.3 より前のバージョンではメガバイト単位、このバージョンからはバイト単位。

  • myisam_repair_threads。 この値が 1 より大きい場合、Repair by sorting プロセス中、MyISAM テーブルインデックスが、それぞれ独自のスレッドで平行して作成される。注意: マルチスレッド修復は、現在まだ alpha 段階。

  • myisam_max_sort_file_size REPAIRALTER TABLE、または LOAD DATA INFILE を使用したインデックスの再生成時、MySQL が使用できるテンポラリファイルの最大サイズ。ファイルサイズがこれより大きい場合、インデックスはキーキャッシュによって作成される(時間がかかる)。注意: このパラメータの値は、4.0.3 より前のバージョンではメガバイト単位、このバージョンからはバイト単位。

  • net_buffer_length クエリとクエリの間、通信バッファはこのサイズにリセットされる。通常、これは変更すべきでないが、メモリが非常に小さい場合には、予測されるクエリサイズに設定できる。これは、クライアントによって送信される SQL ステートメントの予測される長さ。ステートメントがこの長さを超えた場合、バッファは自動的に max_allowed_packet バイトまで拡大される。

  • net_read_timeout 読み取りを停止する前に、接続からのデータを待機する秒数。注意: 接続からのデータが期待されない場合、タイムアウトは write_timeout によって定義される。slave_net_timeout も参照のこと。

  • net_retry_count 通信ポートの読み取りが中断した場合に、実行できる再試行回数。FreeBSD では、内部中断がすべてのスレッドに通知されるため、この値を大きくすべきである。

  • net_write_timeout 書き込みを停止する前に、ブロックが接続に書き込まれるのを待つ秒数。

  • open_files_limit システムが mysqld に開くことを許可するファイルの数。これはシステムに指定されている実際の値であり、起動時のパラメータとして mysqld に指定したものとは異なっている場合がある。MySQL がオープンファイル数を変更できないシステムでは 0 になる。

  • pid_file --pid-file オプションの値。

  • port --port オプションの値。

  • protocol_version MySQL サーバによって使用されるプロトコルバージョン。

  • range_alloc_block_size 範囲の最適化で割り当てられるブロックのサイズ。

  • read_buffer_size(以前は record_buffer) 順次スキャンを実行する各スレッドは、スキャンする各テーブルにこのサイズのバッファを割り当てる。多くの順次スキャンを実行する場合には、この値を大きくすることが必要である。

  • read_rnd_buffer_size(以前は record_rnd_buffer) ソート後、ソートされた順序でレコードを読み取る際、ディスク検索を行わないように、レコードをこのバッファから読み取る。この値を大きく設定すると、ORDER BY を大幅に向上できる。これはスレッド固有の変数であるため、これをグローバルに大きく設定すべきではないが、いくつかの特別大きなクエリを実行するときだけ変更する。

  • query_alloc_block_size クエリの解析および実行時に作成されるオブジェクトに割り当てられるメモリ割り当てブロックのサイズ。メモリの断片化に問題がある場合、これを少し大きくすると改善する可能性がある。

  • query_cache_limit これより大きい結果はキャッシュしない(デフォルトは 1M)。

  • query_cache_size 古いクエリの結果を保存するために割り当てられたメモリ。この値を 0 にすると、クエリキャッシュは無効になる(デフォルト)。

  • query_cache_type 次のいずれかの値(数値のみ)を設定できる。

    エイリアスコメント
    0OFF結果のキャッシュおよび読み込みを行わない。
    1ONSELECT SQL_NO_CACHE ... クエリを除くすべての結果をキャッシュする。
    2DEMANDSELECT SQL_CACHE ... クエリのみキャッシュする。
  • query_prealloc_size クエリの解析および実行時に使用される永続バッファのサイズ。このバッファはクエリとクエリの間でも解放されない。理論的には、この値を ``十分大きく'' 設定することにより、MySQL は malloc() 呼び出しを 1 回も実行することなくクエリを実行できる。

  • safe_show_database ユーザがデータベース権限またはテーブル権限をまったく持たないデータベースは表示しない。これは、他のユーザが権限を持つデータベースを表示することができなくなるので、セキュリティの向上に役立つ。skip_show_database も参照のこと。

  • server_id --server-id オプションの値。

  • skip_locking mysqld が外部ロックを使用する場合は OFF。

  • skip_networking ローカル(ソケット)接続のみを認める場合は ON。

  • skip_show_database ユーザに PROCESS 権限がない場合、SHOW DATABASES の実行を認めない。これは、他のユーザが権限を持つデータベースを表示できなくなるので、セキュリティの向上に役立つ。safe_show_database も参照のこと。

  • slave_net_timeout 読み取りを停止する前に、マスタ/スレーブ接続からのデータを待機する秒数。

  • slow_launch_time スレッドの作成にこの値(秒単位)より時間がかかれば、Slow_launch_threads カウンタがインクリメントされる。

  • socket サーバによって使用される Unix ソケット。

  • sort_buffer_size ソートを実行する必要のある各スレッドがこのサイズのバッファを割り当てる。ORDER BY 操作または GROUP BY 操作を速くするには、この値を大きくする。 See 項A.4.4. 「MySQL がテンポラリファイルを格納する場所」

  • table_cache すべてのスレッドでのオープンテーブル数。この値を大きくすると、mysqld が必要とするファイル記述子の数が多くなる。テーブルキャッシュを大きくする必要があるかどうかチェックするには、Opened_tables 変数を調べる。 See 項4.6.8.3. 「SHOW STATUS。 この変数が大きく、FLUSH TABLES(すべてのテーブルを閉じて再び開く)をあまり実行しないのであれば、table_cache 変数の値を大きくすることが必要である。

    テーブルキャッシュの詳細については、項5.4.7. 「MySQL でのテーブルのオープンとクローズの方法」 を参照のこと。

  • table_type デフォルトのテーブル型。

  • thread_cache_size 再利用のためにキャッシュに保持するスレッド数。クライアントが接続を切断したときに、以前のスレッド数が thread_cache_size 以下であれば、そのクライアントのスレッドはキャッシュに入る。新しいスレッドはすべてキャッシュから取り込まれ、キャッシュが空の場合のみ、新しいスレッドが作成される。新しい接続が多く発生する場合、この変数を大きくすることによりパフォーマンスを向上できる(スレッド実装が既に理想的な状態であれば、それほどパフォーマンスは向上しない)。Connections ステータス変数と Threads_created ステータス変数(詳細については、see 項4.6.8.3. 「SHOW STATUS)の差異を調べることにより、スレッドキャッシュの効率性を確認できる。

  • thread_concurrency Solaris では、mysqld はこの値で thr_setconcurrency() を呼び出す。 thr_setconcurrency() により、アプリケーションは、同時に実行する理想的なスレッド数をスレッドシステムに指定する。

  • thread_stack 各スレッドのスタックサイズ。crash-me テストによって検知される制限の多くがこの値に依存する。通常の操作ではデフォルトで十分である。 See 項5.1.4. 「MySQL ベンチマークスィート」

  • timezone サーバのタイムゾーン。

  • tmp_table_size メモリ内のテンポラリテーブルがこのサイズを超えると、MySQL は自動的にこれをディスク上の MyISAM テーブルに変換する。詳細な GROUP BY クエリを頻繁に行い、メモリに余裕がある場合は、tmp_table_size 値を大きくする。

  • tmpdir テンポラリファイルおよびテンポラリテーブル用ディレクトリ。MySQL 4.1 以降、複数のパスをコロン :(Windows ではセミコロン ;)で区切って設定できるようになっている。これは、ラウンドロビン方式で使用される。この機能は、複数の物理ディスクに負荷を分散する目的で使用できる。メモリベースのファイルシステムを指すように tmpdir を設定することは可能。ただし、MySQL サーバがスレーブの場合はできない。スレーブの場合、マシンがリブートしてもテンポラリテーブルのレプリケーションまたは LOAD DATA INFILE のレプリケーション処理を続行するためのテンポラリファイルが必要となる。そのため、マシンのリブートで消去されるメモリベースの tmpdir は適しない。ディスクベースの tmpdir が必要。

  • transaction_alloc_block_size コミットするときに、バイナリログに保存されるトランザクションの一部であるクエリを保存するために割り当てられるメモリ割り当てブロックのサイズ。

  • transaction_prealloc_block_size transaction_alloc_blocks の永続的バッファ。クエリとクエリの間でも解放されない。通常のトランザクションのすべてのクエリに対応できるように ``十分に大きく'' 設定すれば、malloc() を何度も呼び出さないで済む。

  • version サーバのバージョン番号。

  • wait_timeout 対話式ではない接続を終了する前に、サーバがアクティビティを待機する秒数。

    スレッド開始時、SESSION.WAIT_TIMEOUT は、GLOBAL.WAIT_TIMEOUT または GLOBAL.INTERACTIVE_TIMEOUT によって初期化される。どちらになるかは、クライアントのタイプ(CLIENT_INTERACTIVE 接続オプションで定義)に依存する。interactive_timeout も参照のこと。

これら変数のチューニング方法については、MySQL のチューニングに関するセクションを参照してください。 See 項5.5.2. 「サーバパラメータのチューニング」

4.6.8.5. SHOW [BDB] LOGS

SHOW LOGS は、既存のログファイルに関するステータス情報を表示します。現在は、Berkeley DB ログファイルの情報を表示するだけなので、そのエイリアスは(MySQL 4.1.1 で導入) SHOW BDB LOGS です。

  • File は、ログファイルのフルパスを示す。

  • Type は、ログファイルのタイプ(Berkeley DB ログファイルでは BDB)を示す。

  • Status は、ログファイルのステータス(ファイルを削除できる場合は FREE、ファイルがトランザクションサブシステムによって必要とされている場合は IN USE)を示す。

4.6.8.6. SHOW PROCESSLIST

SHOW [FULL] PROCESSLIST は、実行中のスレッドを表示します。 mysqladmin processlist コマンドでもこの情報を取得できます。SUPER 権限があれば、すべてのスレッドを表示できます。この権限がない場合は、自分のスレッドのみ表示できます。 See 項4.6.7. 「KILL 構文」FULL オプションを使用していない場合、各クエリの最初の 100 文字だけが表示されます。

4.0.12 以降、MySQL は TCP/IP 接続のホスト名を hostname:client_port 形式で報告するので、どのクライアントが何を行っているかわかりやすくなっています。

このコマンドは、'too many connections' エラーメッセージが表示され、原因を知りたいときに便利です。MySQL は、SUPER 権限を持つクライアントのために 1 つの特別接続枠を予約しており、いつでもシステムにログインしてチェックできるようになっています(ユーザ全員にこの権限を与えていないようにしてください)。

mysqladmin processlist で確認できる一般的な状態は以下のとおりです。

  • Checking table スレッドがテーブルの自動チェックを実行している。

  • Closing tables スレッドが、変更されたテーブルデータをディスクにフラッシュし、使用したテーブルを閉じている。これには通常それほど時間がかからない。時間がかかる場合、ディスクの使用率をチェックする必要がある。

  • Connect Out マスタに接続しているスレーブ。

  • Copying to tmp table on disk テンポラリ結果セットが tmp_table_size よりも大きく、スレッドがメモリベースのテンポラリテーブルをディスクベースに変更して、メモリの節約を図っている。

  • Creating tmp table スレッドは、クエリの結果の一部を保持するためのテンポラリテーブルを作成中。

  • deleting from main table 複数テーブルを削除する最初の段階で、最初のテーブルを削除中。

  • deleting from reference tables 複数テーブルを削除する 2 番目の段階で、他のテーブルから、一致したレコードを削除中。

  • Flushing tables スレッドが FLUSH TABLES を実行中。すべてのスレッドによりそのテーブルが閉じられるのを待っている。

  • Killed 誰かがスレッドを強制終了の命令を出したため、次回のキルフラグチェック時に強制終了される。MySQL では大きな各ループでフラグがチェックされるが、それでもスレッド終了には少し時間がかかる場合がある。スレッドが他のスレッドによってロックされている場合、そのロックが解除されたところで強制終了が実行される。

  • Sending data スレッドは SELECT ステートメントのレコードを処理中で、かつクライアントにデータを送信中。

  • Sorting for group スレッドは、GROUP BY のソートを実行中。

  • Sorting for order スレッドは、ORDER BY のソートを実行中。

  • Opening tables スレッドがテーブルを開こうとしている。これは、何かが妨害していなければすぐに終わるはずである。たとえば、ALTER TABLELOCK TABLE などにより、そのコマンドの終了時までテーブルが開かないことがある。

  • Removing duplicates クエリで SELECT DISTINCT が使用されたが、MySQL は初期段階で重複を除外する最適化を実行できなかった。このため、MySQL は結果をクライアントに送信する前に、重複レコードを削除する段階を踏む必要がある。

  • Reopen table スレッドはテーブルのロックを取得したが、ロック取得後、下のテーブル構造が変更されていることを認識した。このため、ロックを解除し、テーブルを閉じて、再び開こうとしている。

  • Repair by sorting 修復コードがソートを使用してインデックスを作成している。

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

  • Searching rows for update スレッドがレコード更新の初期段階として、更新対象の一致レコードを検索中である。レコード検索に使用するインデックスを UPDATE が変更すると、この段階が必要となる。

  • Sleeping スレッドが、クライアントから新しいコマンドが送信されるのを待っている。

  • System lock スレッドが、テーブルの外部システムロックを待っている。同じテーブルにアクセスする複数の mysqld サーバを使用していない場合、--skip-external-locking オプションでシステムロックを無効にできる。

  • Upgrading lock INSERT DELAYED ハンドラが、レコード挿入のためにテーブルをロックしようとしている。

  • Updating スレッドが更新対象レコードを検索して更新している。

  • User Lock スレッドが GET_LOCK() を待っている。

  • Waiting for tables 下のテーブル構造が変更されているため、テーブルを開き直して新しい構造を取得する必要があるという通知をスレッドが受け取った。テーブルを開き直すためには、他のすべてのスレッドがそのテーブルを閉じるのを待つ必要がある。

    この通知は、他のスレッドがそのテーブルに対して FLUSH TABLESFLUSH TABLES table_nameALTER TABLERENAME TABLEREPAIR TABLEANALYZE TABLEOPTIMIZE TABLE のいずれかを実行している場合に発生する。

  • waiting for handler insert INSERT DELAYED ハンドラがすべての挿入処理を完了し、新規の挿入を待機中である。

ほとんどの状態はすぐに終わります。何秒も同じ状態が続く場合は、問題のある可能性があるので、調査が必要です。

他にも説明していない状態がありますが、そのほとんどは mysqld のバグ発見に役立つものです。

4.6.8.7. SHOW GRANTS

SHOW GRANTS FOR user は、ユーザの権限を複製するために発行する必要がある grant コマンドを列挙します。

mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

現在のセッションの権限を列挙するには、CURRENT_USER() 関数(バージョン 4.0.6 で導入)を使用して、そのセッションで認証されているユーザを確認できます。 See 項6.3.6.2. 「その他の各種関数」

4.6.8.8. SHOW CREATE TABLE

指定したテーブルを作成する CREATE TABLE ステートメントを表示します。

mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE t (
  id INT(11) default NULL auto_increment,
  s char(60) default NULL,
  PRIMARY KEY (id)
) TYPE=MyISAM

SHOW CREATE TABLE で表示されるテーブル名とカラム名は、SQL_QUOTE_SHOW_CREATE オプションの値に従って引用符で囲まれます。 項5.5.6. 「SET 構文」

4.6.8.9. SHOW WARNINGS | ERRORS

SHOW WARNINGS [LIMIT row_count]
SHOW ERRORS [LIMIT row_count]

このコマンドは、MySQL 4.1.0 で導入されました。

これは、前回のコマンドでのエラー、警告、およびコメントを表示します。エラーおよび警告は、テーブルを使用する新規コマンドごとにリセットされます。

MySQL サーバは、前回のコマンドで発生した警告とエラーの合計数を返します。これは、mysql_warning_count() を呼び出すことによって取得できます。

max_error_count までのメッセージが保存されます(グローバルおよびスレッド固有変数)。

@error_count でエラー数を、@warning_count で警告数を取得できます。

SHOW WARNINGS では前回のコマンドで発生したエラー、警告、およびコメントがすべて表示され、SHOW ERRORS ではエラーだけが表示されます。

mysql> DROP TABLE IF EXISTS no_such_table;
mysql> SHOW WARNINGS;

+-------+------+-------------------------------+
| Level | Code | Message                       |
+-------+------+-------------------------------+
| Note  | 1051 | Unknown table 'no_such_table' |
+-------+------+-------------------------------+

注意: MySQL 4.1.0 では警告のフレームワークが追加されただけなので、MySQL コマンドの多くは警告を生成しません。4.1.1 では、LOAD DATA INFILE、および INSERTUPDATEALTER などの DML ステートメントのあらゆる種類の警告をサポートします。

以下、挿入ステートメントの変換警告を生成する簡単な例を示します。

mysql> create table t1(a tinyint NOT NULL, b char(4));
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(10,'mysql'),(NULL,'test'),(300,'open source');
Query OK, 3 rows affected, 4 warnings (0.15 sec)
Records: 3  Duplicates: 0  Warnings: 4

mysql> show warnings;
+---------+------+---------------------------------------------------------------+
| Level   | Code | Message                                                       |
+---------+------+---------------------------------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1                        |
| Warning | 1261 | Data truncated, NULL supplied to NOT NULL column 'a' at row 2 |
| Warning | 1262 | Data truncated, out of range for column 'a' at row 3          |
| Warning | 1263 | Data truncated for column 'b' at row 3                        |
+---------+------+---------------------------------------------------------------+
4 rows in set (0.00 sec)

警告の最大数は、サーバ変数 'max_error_count'SET max_error_count=[count] を使用して指定できます。デフォルトは 64 です。この変数を '0' にリセットすればこの設定を無効できます。max_error_count が 0 の場合でも、警告が何回発生したか表示されますが、メッセージは保存されません。

たとえば、上記の例での以下の ALTER テーブルステートメントの場合、max_error_count=1 に設定すると、警告が 3 回発生しても、返される警告メッセージは 1 つだけになります。

mysql> show variables like 'max_error_count';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_error_count | 64    |
+-----------------+-------+
1 row in set (0.00 sec)

mysql> set max_error_count=1;
Query OK, 0 rows affected (0.00 sec)

mysql> alter table t1 modify b char;
Query OK, 3 rows affected, 3 warnings (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 3

mysql> show warnings;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1263 | Data truncated for column 'b' at row 1 |
+---------+------+----------------------------------------+
1 row in set (0.00 sec)

mysql>

4.6.8.10. SHOW TABLE TYPES

SHOW TABLE TYPES

このコマンドは、MySQL 4.1.0 で導入されました。

SHOW TABLE TYPES は、テーブル型に関するステータス情報を表示します。このコマンドは、テーブル型がサポートされているかどうか、およびデフォルトのテーブル型を確認するのに使用されます。

mysql> SHOW TABLE TYPES;

+--------+---------+-----------------------------------------------------------+
| Type   | Support | Comment                                                   |
+--------+---------+-----------------------------------------------------------+
| MyISAM | DEFAULT | Default type from 3.23 with great performance             |
| HEAP   | YES     | Hash based, stored in memory, useful for temporary tables |
| MERGE  | YES     | Collection of identical MyISAM tables                     |
| ISAM   | YES     | Obsolete table type; Is replaced by MyISAM                |
| InnoDB | YES     | Supports transactions, row-level locking and foreign keys |
| BDB    | NO      | Supports transactions and page-level locking              |
+--------+---------+-----------------------------------------------------------+
6 rows in set (0.00 sec)

'Support' フィールドの DEFAULT は、そのテーブル型がサポートされていることと、テーブル型がデフォルトであることを示します。サーバを --default-table-type=InnoDB で起動した場合、InnoDB の 'Support' フィールド値が DEFAULT になります。

4.6.8.11. SHOW PRIVILEGES

SHOW PRIVILEGES

このコマンドは、MySQL 4.1.0 で導入されました。

SHOW PRIVILEGES は、下の MySQL サーバがサポートするシステム権限を一覧表示します。

mysql> show privileges;
+------------+--------------------------+-------------------------------------------------------+
| Privilege  | Context                  | Comment                                               |
+------------+--------------------------+-------------------------------------------------------+
| Select     | Tables                   | To retrieve rows from table                           |
| Insert     | Tables                   | To insert data into tables                            |
| Update     | Tables                   | To update existing rows                               |
| Delete     | Tables                   | To delete existing rows                               |
| Index      | Tables                   | To create or drop indexes                             |
| Alter      | Tables                   | To alter the table                                    |
| Create     | Databases,Tables,Indexes | To create new databases and tables                    |
| Drop       | Databases,Tables         | To drop databases and tables                          |
| Grant      | Databases,Tables         | To give to other users those privileges you possess   |
| References | Databases,Tables         | To have references on tables                          |
| Reload     | Server Admin             | To reload or refresh tables, logs and privileges      |
| Shutdown   | Server Admin             | To shutdown the server                                |
| Process    | Server Admin             | To view the plain text of currently executing queries |
| File       | File access on server    | To read and write files on the server                 |
+------------+--------------------------+-------------------------------------------------------+
14 rows in set (0.00 sec)

4.7. MySQL のローカライズと国際的な使用

4.7.1. データおよびソート用キャラクタセット

デフォルトでは、MySQL はスウェーデン語およびフィンランド語に従ってソートされる ISO-8859-1(Latin1)キャラクタセットを使用します。これは、米国と西ヨーロッパに適したキャラクタセットです。

標準 MySQL バイナリは、--with-extra-charsets=complex でコンパイルされます。これにより、すべての標準プログラムにコードが追加され、バイナリ内で latin1 とすべてのマルチバイトキャラクタセットを処理できるようになります。他のキャラクタセットが必要な場合は、キャラクタセット定義ファイルからロードします。

キャラクタセットにより、名前に使用できる文字と、SELECT ステートメントの ORDER BY 節および GROUP BY 節での文字列のソート方法が決定します。

サーバ起動時に --default-character-set オプションでキャラクタセットを変更できます。利用可能なキャラクタセットは、--with-charset=charset オプションと --with-extra-charsets= list-of-charset | complex | all | none オプションが configure になっているかどうか、および SHAREDIR/charsets/Index に含まれているキャラクタセット設定ファイルに依存します。 See 項2.3.3. 「一般的な configure オプション」

MySQL の実行中にキャラクタセットを変更した場合(ソート順序が変わる可能性もあります)、すべてのテーブルで myisamchk -r -q --set-character-set=charset を実行する必要があります。このことを行わない場合、インデックスが正しい順序でなくなる可能性があります。

クライアントが MySQL サーバに接続すると、サーバはデフォルトのキャラクタセットをクライアントに送ります。クライアントは、この接続用としてそのキャラクタセットに切り替えます。

SQL クエリの文字列をエスケープする場合は、mysql_real_escape_string() を使用してください。最初のパラメータとして MYSQL 接続ハンドルを使用すること以外、mysql_real_escape_string() は旧 mysql_escape_string() 関数と同じです。

サーバのインストールパス以外のパスでクライアントがコンパイルされており、MySQL をコンフィギャしたユーザがすべてのキャラクタセットを MySQL バイナリに組み込んでいない場合、サーバがクライアントとは異なるキャラクタセットで実行しているときに必要となる追加キャラクタセットの場所を、クライアントに指定する必要があります。

これは、MySQL オプション設定ファイルで指定することができます。

[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets

ここで、パスは、動的 MySQL キャラクタセットが保存されているディレクトリを指します。

以下のように、クライアントに特定のキャラクタセットの使用を強制することも可能です。

[client]
default-character-set=character-set-name

しかし、通常は必要ありません。

4.7.1.1. ドイツ語キャラクタセット

ドイツ語のソート順序が必要な場合、mysqld--default-character-set=latin1_de で起動します。これには、以下のような特徴があります。

文字列のソートおよび比較時、比較の実行前に以下の文字列のマッピングが実行される。

a  ->  ae
o  ->  oe
u  ->  ue
s  ->  ss

アクセント文字はすべて、対応するアクセントなしの大文字に変換されます。また、すべての文字が大文字に変換されます。

文字列を LIKE で比較する際には、1 文字から 2 文字へのマッピングは実行されません。すべての文字が大文字に変換されます。UuOoA、および a 以外、すべての文字からアクセントが削除されます。

4.7.2. 英語以外のエラーメッセージ

mysqld では、以下の言語でエラーメッセージを出力できます。 チョコ語、デンマーク語、オランダ語、英語(デフォルト)、エストニア語、フランス語、ドイツ語、ギリシャ語、ハンガリー語、イタリア語、日本語、韓国語、ノルウェー語、新ノルウェー語、ポーランド語、ポルトガル語、ルーマニア語、ロシア語、スロバキア語、スペイン語、およびスウェーデン語。

特定の言語で mysqld を起動するには、--language=lang または -L lang オプションを使用します。次に例を示します。

shell> mysqld --language=swedish

または

shell> mysqld --language=/usr/local/share/swedish

注意: 言語名はすべて小文字で指定します。

言語ファイルは(デフォルトで)mysql_base_dir/share/LANGUAGE/ にあります。

エラーメッセージファイルを更新するには、errmsg.txt ファイルを編集し、以下のコマンドを実行して errmsg.sys ファイルを生成します。

shell> comp_err errmsg.txt errmsg.sys

MySQL を新しいバージョンにアップグレードした場合、この変更を、新規 errmsg.txt ファイルでも同じように行ってください。

4.7.3. 新しいキャラクタセットの追加

他のキャラクタセットを MySQL に追加するには、以下の手順を実行します。

キャラクタセットがシンプルなものかコンプレックスなものかを判断します。キャラクタセットが、ソートのために特殊文字照合ルーチンを必要とせず、マルチバイト文字のサポートも必要なければ、それはシンプルです。どちらかを必要とする場合、それはコンプレックスです。

たとえば、latin1danish はシンプルなキャラクタセットで、big5czech はコンプレックスなキャラクタセットです。

以下のセクションでは、キャラクタセットを MYSET という名前にすることが前提です。

シンプルなキャラクタセットの場合、以下を実行します。

  1. MYSET を sql/share/charsets/Index ファイルの最後に追加し、これに一意の番号を割り当てる。

  2. sql/share/charsets/MYSET.conf ファイルを作成する(sql/share/charsets/latin1.conf をベースとして使用できる)。

    ファイルの構文は、以下のとおり非常にシンプルである。

    • コメントは '#' 文字で始まり、行の最後まで続く。

    • 単語は任意の数のスペースで区切る。

    • キャラクタセットを定義するとき、すべての単語は 16 進数値であることが必要。

    • ctype 配列は、最初の 257 語を占める。to_lower[]to_upper[]、および sort_order[] 配列はそれぞれその後の 256 語を占める。

    See 項4.7.4. 「キャラクタ定義配列」

  3. キャラクタセット名を、configure.inCHARSETS_AVAILABLE リストおよび COMPILED_CHARSETS リストに追加する。

  4. 再コンフィギャして再コンパイルし、テストする。

コンプレックスなキャラクタセットの場合、以下を実行します。

  1. MySQL ソースディストリビューションに strings/ctype-MYSET.c ファイルを作成する。

  2. MYSET を sql/share/charsets/Index ファイルの最後に追加する。これに一意の番号を割り当てる。

  3. strings/ctype-big5.c など、既存の ctype-*.c ファイルの 1 つを見て、何の定義が必要か調べる。注意: ファイル内の配列名は、ctype_MYSETto_lower_MYSET などであることが必要。これは、シンプルなキャラクタセットの配列に対応する。 See 項4.7.4. 「キャラクタ定義配列」

  4. ファイルの先頭付近に、以下のようなコメントを置く。

    /*
     * This comment is parsed by configure to create ctype.c,
     * so don't change it unless you know what you are doing.
     *
     * .configure. number_MYSET=MYNUMBER
     * .configure. strxfrm_multiply_MYSET=N
     * .configure. mbmaxlen_MYSET=N
     */
    

    configure プログラムはこのコメントを使用して、自動的にキャラクタセットを MySQL ライブラリに組み込む。

    strxfrm_multiply 行および mbmaxlen 行については、後続セクションで説明する。これらはそれぞれ、文字列照合関数またはマルチバイト文字セット関数が必要な場合に組み込む。

  5. 次に、以下の関数を作成する。

    • my_strncoll_MYSET()

    • my_strcoll_MYSET()

    • my_strxfrm_MYSET()

    • my_like_range_MYSET()

    See 項4.7.5. 「文字列照合サポート」

  6. キャラクタセット名を、configure.inCHARSETS_AVAILABLE リストおよび COMPILED_CHARSETS リストに追加する。

  7. 再コンフィギャして再コンパイルし、テストする。

sql/share/charsets/README ファイルに、より詳細な説明が含まれています。

MySQL ディストリビューションへのキャラクタセットの組み込みを希望する場合には、MySQL internals メーリングリストにパッチをメールしてください。 See 項1.7.1.1. 「MySQL メーリングリスト」

4.7.4. キャラクタ定義配列

to_lower[]to_upper[] は、キャラクタセットの各メンバに対応する、大文字と小文字が格納されるシンプルな配列です。次に例を示します。

to_lower['A'] は 'a' を含む
to_upper['a'] は 'A' を含む

sort_order[] は、文字をどのような順番で比較しソートするかを示すマップです。多くの場合(すべてのキャラクタセットについてではありませんが)、これは to_upper[] と同じです(ソートで大文字と小文字が区別されません)。MySQL は、sort_order[character] の値に基づいて文字をソートします。さらに複雑なソートルールに関しては、後述の文字列照合の説明を参照してください。 See 項4.7.5. 「文字列照合サポート」

ctype[] はビット値の配列で、1 文字が 1 要素です。注意: to_lower[]to_upper[]、および sort_order[] は文字値でインデックス化されますが、ctype[] は文字値 + 1 でインデックス化されます。これは、EOF を処理することが必要だったときの古いレガシです。

m_ctype.h に、以下のビットマスク定義があります。

#define _U      01      /* Uppercase */
#define _L      02      /* Lowercase */
#define _N      04      /* Numeral (digit) */
#define _S      010     /* Spacing character */
#define _P      020     /* Punctuation */
#define _C      040     /* Control character */
#define _B      0100    /* Blank */
#define _X      0200    /* heXadecimal digit */

各文字の ctype[] エントリは、文字を指定するビットマスク値の組み合わせになっている必要があります。たとえば、'A' は大文字(_U)であると同時に 16 進数(_X)でもあるので、ctype['A'+1] には以下の値が含まれます。

_U + _X = 01 + 0200 = 0201

4.7.5. 文字列照合サポート

使用する言語のソートルールが、シンプルな sort_order[] テーブルで処理するには複雑すぎる場合、文字列照合を行う必要があります。

現在のところ、これに関する最良のドキュメントは、すでに実装されているキャラクタセットです。たとえば、big5czechgbksjistis160 などのキャラクタセットを見てみてください。

ファイルの先頭の特殊コメントで、strxfrm_multiply_MYSET=N 値を指定する必要があります。N には、my_strxfrm_MYSET で文字列が大きくなれる最大比率(正の整数)を設定してください。

4.7.6. マルチバイト文字サポート

マルチバイト文字を含む新しいキャラクタセットのサポートを追加する場合、マルチバイト文字関数を使用する必要があります。

現在のところ、これに関する最良のドキュメントは、すでに実装されているキャラクタセットです。たとえば、euc_krgb2312gbksjisujis などのキャラクタセットを参照してください。これらは、strings ディレクトリの ctype-'charset'.c ファイルに実装されています。

ソースファイルの先頭の特殊コメントで mbmaxlen_MYSET=N 値を指定する必要があります。N には、キャラクタセット内の最大文字のバイト数を設定してください。

4.7.7. キャラクタセットに関する問題

使用しているバイナリにコンパイルされていないキャラクタセットを使用すると、いくつかの問題が発生する可能性があります。

  • プログラムが認識しているパスに、キャラクタセットが保存されていない(デフォルトは /usr/local/mysql/share/mysql/charsets)。これは、該当プログラムで --character-sets-dir オプションを使用することによって解決できる。

  • キャラクタセットがマルチバイトキャラクタセットであり、動的にロードできない。この場合、そのキャラクタセットをサポートするようにプログラムを再コンパイルする必要がある。

  • キャラクタセットが動的なキャラクタセットであるが、その設定ファイルがない。この場合、新しい MySQL ディストリビューションから、そのキャラクタセットの設定ファイルをインストールする必要がある。

  • Index ファイルに、キャラクタセットの名前が含まれていない。

    ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
    (Errcode: 2)
    

    この場合、新しい Index ファイルを入手するか、または手動でキャラクタセット名を追加する。

MyISAM テーブルでは、テーブルのキャラクタセットの名前と番号を myisamchk -dvv table_name で確認できます。

4.8. MySQL サーバサイドのスクリプトとユーティリティ

4.8.1. サーバサイドのスクリプトとユーティリティの概要

すべての MySQL プログラムが多くのさまざまなオプションを使用します。しかし、すべての MySQL プログラムに --help オプションが用意されており、このオプションを使用することにより、そのプログラムのすべてのオプションの説明を表示することができます。たとえば、mysql --help を試してみてください。

すべての標準プログラムのデフォルトオプションは、オプション設定ファイルで上書きできます。 項4.1.2. 「my.cnf オプション設定ファイル」

以下の一覧は、サーバサイドの MySQL プログラムを簡単に説明したものです。

  • myisamchk

    MySQL テーブルの記述、チェック、最適化、および修復を行うユーティリティ。myisamchk には多くの機能があるため、別の章で説明する。 See 章?4. データベース管理

  • make_binary_distribution

    コンパイルされた MySQL のバイナリリリースを作成する。作成したリリースは、他の MySQL ユーザが利用できるように、FTP 経由で support.mysql.com/pub/mysql/Incoming に送信することができる。

  • mysqlbug

    MySQL バグレポートスクリプト。このスクリプトは、MySQL リストにバグレポートを提出する際、必ず使用する。

  • mysqld

    SQL デーモン。常に稼動していることが必要である。

  • mysql_install_db

    MySQL 権限テーブルをデフォルト権限で作成する。これは通常、最初に MySQL をシステムにインストールするとき、1 回だけ実行する。

4.8.2. mysqld_safemysqld のラッパ)

mysqld_safe は、mysqld デーモンを Unix で起動するときの推奨される方法です。mysqld_safe により、エラー発生時にサーバを再起動したり、ランタイム情報をログファイルに記録するなどのセーフティ機能が加わります。

注意: MySQL 4.0 より前は、mysqld_safesafe_mysqld という名前でした。下位互換性を維持するため、しばらくの間、MySQL バイナリディストリビューションには mysqld_safe へのシンボリックリンクとして safe_mysqld が含められています。

--mysqld=# または --mysqld-version=# を使用しない場合、mysqld_safe は、mysqld-max という名前の実行可能ファイルがあればこれを使用します。このファイルがなければ、mysqld_safemysqld を開始します。これにより、mysqld の代わりに mysqld-max が使用されるかどうかのテストを簡単に実行できます。mysqld-maxmysqld のある場所にコピーするだけで、前者が使用されます。

通常、mysqld_safe スクリプトは編集しないでください。代わりに、my.cnf ファイルの [mysqld_safe] セクションの mysqld_safe にオプションを設定します。mysqld_safe は、オプション設定ファイルの [mysqld][server][mysqld_safe] の各セクションからすべてのオプションを読み取ります(下位互換性のため、[safe_mysqld] セクションからもオプションが読み取られます)。 See 項4.1.2. 「my.cnf オプション設定ファイル」

注意: mysqld_safe に対するコマンドラインオプションはすべて mysqld に渡されます。mysqld がサポートしていないオプションを mysqld_safe で使用するには、オプション設定ファイルでそのオプションを指定する必要があります。

mysqld_safe のオプションのほとんどは、mysqld のオプションと同じです。 See 項4.1.1. 「mysqld コマンドラインオプション」

mysqld_safe は、以下のオプションをサポートします。

  • --basedir=path , --core-file-size=#

    mysqld が作成できるコアファイルのサイズ。ulimit -c に渡される。

  • --datadir=path , --defaults-extra-file=path , --defaults-file=path , --err-log=path(4.0 で廃止。代わりに --log-error を使用すること) , --log-error=path

    上記ファイルにエラーログを書き込む。 See 項4.10.1. 「エラーログ」

  • --ledir=path

    mysqld のパス。

  • --log=path , --mysqld=mysqld-version

    ledir ディレクトリ内にある起動する mysqld バージョンの名前。

  • --mysqld-version=version

    --mysqld= と同様であるが、ここでは mysqld のサフィックスのみ指定する。 たとえば、--mysqld-version=max を使用すると、mysqld_safeledir/mysqld-max バージョンを起動する。--mysqld-version の引数が空白の場合、ledir/mysqld が使用される。

  • --nice=#(MySQL 4.0.14 で追加) , --no-defaults , --open-files-limit=#

    mysqld が開くことのできるファイルの数。ulimit -n に渡される。注意: これを正常に機能させるには、mysqld_saferoot として起動する必要がある。

  • --pid-file=path , --port=# , --socket=path , --timezone=#

    タイムゾーン(TZ)変数を、このパラメータの値に設定する。

  • --user=#

mysqld_safe スクリプトは、MySQL のソースバージョンまたはバイナリバージョンのどちらでインストールされたサーバでも起動できるように記述されています。サーバが多少異なる場所にインストールされていても問題ありません。mysqld_safe は、以下のいずれかの条件が満たされていることを必要とします。

  • mysqld_safe を起動するディレクトリとの相対関係でサーバとデータベースを検出できる。mysqld_safe は、その作業ディレクトリ以下で、bin ディレクトリと data ディレクトリ(バイナリディストリビューションの場合)、または libexec ディレクトリと var ディレクトリ(ソースディストリビューションの場合)を探す。MySQL インストールディレクトリ(たとえば、バイナリディストリビューションの場合は /usr/local/mysql)から mysqld_safe を実行する場合、この条件が満たされていることが必要である。

  • サーバおよびデータベースを作業ディレクトリとの相対関係で検出できない場合、mysqld_safe は絶対パスによって検出しようとする。通常、この場所は、/usr/local/libexec/usr/local/var になる。実際の場所は、ディストリビューションがビルドされたときに決定され、ここから mysqld_safe が起動する。MySQL が標準の場所にインストールされている場合、この絶対パスが正しいことが必要になる。

mysqld_safe はその作業ディレクトリに相対してサーバとデータベースを探すため、MySQL インストールディレクトリから mysqld_safe を開始するのであれば、MySQL のバイナリディストリビューションはどこにでもインストールできます。

shell> cd mysql_installation_directory
shell> bin/mysqld_safe &

MySQL インストールディレクトリから起動しても mysqld_safe が失敗する場合、システムにとって正しい mysqld のパスとパス名オプションが使用されるように修正します。注意: MySQL をアップグレードすると、mysqld_safe の修正バージョンは上書きされます。再インストールできるように、編集バージョンのコピーを取っておいてください。

4.8.3. mysqld_multi(複数の MySQL サーバを管理するプログラム)

mysqld_multi は、さまざまな Unix ソケットおよび TCP/IP ポートをリッスンする複数の mysqld プロセスを管理するためのプログラムです。

このプログラムは、[mysqld#] という名前のグループを my.cnf(または --config-file=... オプションで指定されたファイル)から検索します。ここで、# は 1 で始まる任意の正の数です。この番号は、以下の説明ではオプショングループ番号、または GNR と呼びます。グループ番号はオプショングループを識別し、起動したり、停止したり、またはステータス情報を取得するサーバを指定する mysqld_multi の引数として使用します。これらのグループに含まれるオプションは、mysqld の起動に使用される通常の [mysqld] グループと同じです(項2.4.3. 「MySQL を自動的に起動および停止する」 などを参照してください)。ただし、mysqld_multi では、各グループに、各 mysqld プロセスで使用されるポートやソケットなどを指定するオプションが含まれていることが必要です。

mysqld_multi は、以下の構文で起動します。

   mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
か mysqld_multi [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]

各 GNR は、オプショングループ番号を表します。任意の GNR を開始、停止、または報告でき、複数の GNR を同時に開始、停止、または報告することもできます。オプション設定ファイルの設定例を表示するには、以下のコマンドを実行します。

shell> mysqld_multi --example

リスト内の GNR の値はコンマで区切ったり、ダッシュ記号で結合できます。結合の場合、GNR1-GNR2 間のすべての GNR が対象になります。GNR 引数を指定しなかった場合、リスト内のすべてのグループが起動、停止、または報告されます。注意: GNR リストには空白スペースを使用できません。空白スペースを挿入すると、スペースの後は無視されます。

mysqld_multi は、以下のオプションをサポートします。

  • --config-file=...

    代替設定ファイル。注意: これは、このプログラムのオプション([mysqld_multi] グループ)には影響せず、[mysqld#] グループにのみ影響する。このオプションがない場合、通常の my.cnf ファイルからすべてが検索される。

  • --example

    オプション設定ファイル例を表示する。

  • --help

    ヘルプを出力して終了する。

  • --log=...

    ログファイル。ログファイルの完全パスと名前。注意: このファイルが存在していれば、すべてがログファイルに記録される。

  • --mysqladmin=...

    サーバのシャットダウンに使用する mysqladmin バイナリ。

  • --mysqld=...

    使用する mysqld バイナリ。注意: このオプションに mysqld_safe を指定することもできる。このオプションは、mysqld に渡される。環境変数 PATHmysqld を指定していることを確認するか、mysqld_safe を修正する。

  • --no-log

    ログをログファイルではなく、stdout に書き込む。デフォルトではログファイルが有効になっている。

  • --password=...

    mysqladmin のユーザのパスワード。

  • --tcp-ip

    Unix ソケットではなく、TCP/IP ポートで各 MySQL サーバに接続する。これは、サーバの停止と報告に影響する。ソケットファイルがなくてもサーバはまだ実行可能であるが、TCP/IP ポート経由のアクセスに限られる。デフォルトでは、Unix ソケットが使用される。

  • --user=...

    mysqladmin の MySQL ユーザ。

  • --version

    バージョン番号を出力して終了する。

mysqld_multi に関する補足コメント

  • mysqladmin プログラムなどを使用して mysqld サービスを停止する MySQL ユーザのパスワードとユーザ名が、アクセスされるすべてのデータディレクトリ(mysql データベースへのアクセス)用のパスワードとユーザ名と同じであることを確認すること。また、ユーザに SHUTDOWN 権限があることも確認する。多くのデータディレクトリがあり、MySQL root ユーザのパスワードが異なる多くの mysql データベースがある場合、以下のように同じパスワードを使用する共通 multi_admin ユーザを作成できる。以下、その例。

    shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
    "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY 'multipass'"
    

    See 項4.3.6. 「権限システムはどのように機能するか」。 各データディレクトリで実行する各 mysqld に対してこのコマンドを実行する必要がある(ソケット -S=... のみ変更する)。

  • pid-file は、mysqld_safe を使用して mysqld を起動する場合(たとえば、--mysqld=mysqld_safe)非常に重要である。すべての mysqld に独自の pid-file が必要である。ここで mysqld を直接使用せずに mysqld_safe を使用する利点は、kill -9 で送信されるシグナルや、その他セグメント化エラー(MySQL では発生してはいけないことだが)などによって mysqld プロセスが強制終了した場合でも、mysqld_safe がすべての mysqld プロセスを ``保護'' し、再起動することである。注意: mysqld_safe スクリプトは、特定の場所から起動することが必要な場合がある。つまり、mysqld_multi を開始する前に、特定のディレクトリに cd することが必要な場合がある。起動時に問題が発生した場合は、mysqld_safe スクリプトを確認のこと。特に以下の行をチェックする。

    --------------------------------------------------------------------------
    MY_PWD=`pwd`
    Check if we are starting this relative (for the binary release)
    if test -d /data/mysql -a -f ./share/mysql/english/errmsg.sys -a \
    -x ./bin/mysqld
    --------------------------------------------------------------------------
    

    See 項4.8.2. 「mysqld_safemysqld のラッパ)」

    上記のテストがうまくいかなければ、問題が発生する可能性がある。

  • 同じデータディレクトリで、複数の mysqld サーバを開始することには危険が伴う。完全に理解していない限り、別々のデータディレクトリを使用すべきである。

  • mysqld に対して異なるソケットファイルと TCP/IP ポートが指定されていることが必要である。

  • 1 番目と 5 番目の mysqld グループは、例から意図的に除外してある。設定ファイルには '空行' を入れておくことが可能である。これにより、柔軟性が高まる。mysqlds の開始と停止の順序は、設定ファイルでの順序に依存する。

  • このプログラムで GNR を使用して特定グループを参照するには、グループ名の最後で番号を指定する。 たとえば、[mysqld17] という名前のグループの GNR は 17 である。

  • mysqld--user オプションを使用するには、mysqld_multi スクリプトを Unix root ユーザとして実行する必要がある。設定ファイルにこのオプションがあっても問題はない。スーパーユーザでないユーザが自分の Unix アカウントで mysqld を開始している場合でも、警告が発生するだけである。重要: 特定の mysqld プロセスを開始しているその Unix ユーザが pid-file およびデータディレクトリの読み取り権限と書き込み権限を(データディレクトリの場合は実行権限も)持っていることを確認すること。完全に理解していない限り、この目的で Unix root アカウントを使用してはいけない

  • 最重要: mysqld サーバに渡されるオプションの意味、および mysqld プロセスを個別に使用する方が望ましい理由を理解しておくこと。同じデータディレクトリで複数のサーバを起動しても、スレッドシステムではパフォーマンスの向上は望めない

See 項4.2. 「同じマシン上で複数の MySQL サーバを実行する」

以下、mysqld_multi の設定が含まれる設定ファイルの例です。

# This file should probably be in your home dir (~/.my.cnf) or /etc/my.cnf
# Version 2.1 by Jani Tolonen

[mysqld_multi]
mysqld     = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = multipass

[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/var2/hostname.pid2
datadir    = /usr/local/mysql/var2
language   = /usr/local/share/mysql/english
user       = john

[mysqld3]
socket     = /tmp/mysql.sock3
port       = 3308
pid-file   = /usr/local/mysql/var3/hostname.pid3
datadir    = /usr/local/mysql/var3
language   = /usr/local/share/mysql/swedish
user       = monty

[mysqld4]
socket     = /tmp/mysql.sock4
port       = 3309
pid-file   = /usr/local/mysql/var4/hostname.pid4
datadir    = /usr/local/mysql/var4
language   = /usr/local/share/mysql/estonia
user       = tonu

[mysqld6]
socket     = /tmp/mysql.sock6
port       = 3311
pid-file   = /usr/local/mysql/var6/hostname.pid6
datadir    = /usr/local/mysql/var6
language   = /usr/local/share/mysql/japanese
user       = jani

See 項4.1.2. 「my.cnf オプション設定ファイル」

4.8.4. myisampack(MySQL 圧縮読み取り専用テーブルジェネレータ)

myisampack は MyISAM テーブルの圧縮に、pack_isam は ISAM テーブルの圧縮に使用します。ISAM テーブルは廃止されているため、ここでは myisampack に限って話を進めますが、myisampack について説明することはすべて、pack_isam にも当てはまります。

myisampack は、テーブル内の各カラムを個別に圧縮します。テーブルを開いたとき、カラムを展開するための情報がメモリに読み込まれます。これにより、個々のレコードにアクセスする際のパフォーマンスが向上します。この場合、Stacker を MS-DOS で使用するときのような大きなディスクブロックではなく、1 つのレコードだけを解凍するだけで済みます。 通常、myisampack はデータファイルを 40% ? 70% 圧縮します。

MySQL は、圧縮テーブルでメモリマッピング(mmap())を使用し、mmap() が機能しない場合は、通常のファイルの読み取り/書き込み使用法に戻ります。

以下に注意してください。

  • パック後、テーブルは読み取り専用になる。これは、CD にパックされたテーブルへのアクセスなど、読み取り専用でいいとの判断からそうしているものである。パックされたテーブルへの書き込み機能の実現も開発計画には入っているが、優先順位は高くない。

  • myisampack は、BLOB カラムまたは TEXT カラムもパックできる。 古い pack_isamISAM テーブル用)ではパックできない。

myisampack は以下のコマンドで起動します。

shell> myisampack [options] filename ...

各ファイル名は、インデックス(.MYI)ファイル名になっていることが必要です。データディレクトリがカレントディレクトリでなければ、ファイルのパスを指定してください。.MYI 拡張子は省略可能です。

myisampack は、以下のオプションをサポートします。

  • -b, --backup

    テーブルのバックアップを tbl_name.OLD として作成する。

  • -#, --debug=debug_options

    デバッグログを出力する。debug_options 文字列には、'd:t:o,filename' がよく使用される。

  • -f, --force

    テーブルが大きくなってしまう場合、テンポラリファイルが存在する場合でもテーブルのパックを強制する。myisampack は、テーブルの圧縮中、tbl_name.TMD という名前のテンポラリファイルを生成する。myisampack を強制終了した場合、.TMD ファイルが削除されない場合がある。通常、tbl_name.TMD があれば、myisampack はエラーを出力して終了する。--force を使用すると、テンポラリファイルの有無に関わらず myisampack はテーブルをパックする。

  • -?, --help

    ヘルプメッセージを表示して終了する。

  • -j big_tbl_name, --join=big_tbl_name

    コマンドラインで指定されたすべてのテーブルを結合して 1 つのテーブル big_tbl_name にする。結合するテーブルはすべて、同一(同じカラム名、同じ型、同じインデックスなど)のテーブルであることが必要である。

  • -p #, --packlength=#

    レコード長保存サイズをバイト単位で指定する。値は 1、2、または 3 であることが必要。myisampack は、すべてのレコードを 1、2、または 3 バイトの長さポインタで保存する。ほとんどの場合、myisampack はファイルをパックする前に、正しい長さを判断できるが、パック中にさらに短くてもよいことを認識する場合がある。この場合、myisampack は、次回同じファイルをパックするときに、レコード長を短くできるというメモを出力する。

  • -s, --silent

    サイレントモード。エラー発生時のみ出力する。

  • -t, --test

    実際にはテーブルをパックせず、パックテストのみ実行する。

  • -T dir_name, --tmp_dir=dir_name

    テンポラリテーブルを書き込むディレクトリを指定する。

  • -v, --verbose

    冗長モード。パックの進捗および結果に関する情報を出力する。

  • -V, --version

    バージョン情報を表示して終了する。

  • -w, --wait

    テーブルが使用中の場合、待機して再試行する。mysqld サーバが --skip-external-locking オプションで起動しいる場合、パッキングプロセス中にテーブルが更新される可能性があれば、myisampack を使用すべきではない。

以下のコマンドシーケンスは、一般的なテーブル圧縮を示しています。

shell> ls -l station.*
-rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-02-02  3:06:43
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafile pointer (bytes):     2  Keyfile pointer (bytes):     2
Max datafile length:   54657023  Max keyfile length:   33554431
Recordlength:               834
Record format: Fixed length

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long              1024       1024          1
2   32    30  multip. text                      10240       1024          1

Field Start Length Type
1     1     1
2     2     4
3     6     4
4     10    1
5     11    20
6     31    1
7     32    30
8     62    35
9     97    35
10    132   35
11    167   4
12    171   16
13    187   35
14    222   4
15    226   16
16    242   20
17    262   20
18    282   20
19    302   30
20    332   4
21    336   4
22    340   1
23    341   8
24    349   8
25    357   8
26    365   2
27    367   2
28    369   4
29    373   4
30    377   1
31    378   2
32    380   8
33    388   4
34    392   4
35    396   4
36    400   4
37    404   1
38    405   4
39    409   4
40    413   4
41    417   4
42    421   4
43    425   4
44    429   20
45    449   30
46    479   1
47    480   1
48    481   79
49    560   79
50    639   79
51    718   79
52    797   8
53    805   1
54    806   1
55    807   20
56    827   4
57    831   4

shell> myisampack station.MYI
Compressing station.MYI: (1192 records)
- Calculating statistics

normal:     20  empty-space:      16  empty-zero:        12  empty-fill:  11
pre-space:   0  end-space:        12  table-lookups:      5  zero:         7
Original trees:  57  After join: 17
- Compressing file
87.14%

shell> ls -l station.*
-rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-04-17 19:04:26
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     1
Max datafile length:   16777215  Max keyfile length:     131071
Recordlength:               834
Record format: Compressed

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long             10240       1024          1
2   32    30  multip. text                      54272       1024          1

Field Start Length Type                         Huff tree  Bits
1     1     1      constant                             1     0
2     2     4      zerofill(1)                          2     9
3     6     4      no zeros, zerofill(1)                2     9
4     10    1                                           3     9
5     11    20     table-lookup                         4     0
6     31    1                                           3     9
7     32    30     no endspace, not_always              5     9
8     62    35     no endspace, not_always, no empty    6     9
9     97    35     no empty                             7     9
10    132   35     no endspace, not_always, no empty    6     9
11    167   4      zerofill(1)                          2     9
12    171   16     no endspace, not_always, no empty    5     9
13    187   35     no endspace, not_always, no empty    6     9
14    222   4      zerofill(1)                          2     9
15    226   16     no endspace, not_always, no empty    5     9
16    242   20     no endspace, not_always              8     9
17    262   20     no endspace, no empty                8     9
18    282   20     no endspace, no empty                5     9
19    302   30     no endspace, no empty                6     9
20    332   4      always zero                          2     9
21    336   4      always zero                          2     9
22    340   1                                           3     9
23    341   8      table-lookup                         9     0
24    349   8      table-lookup                        10     0
25    357   8      always zero                          2     9
26    365   2                                           2     9
27    367   2      no zeros, zerofill(1)                2     9
28    369   4      no zeros, zerofill(1)                2     9
29    373   4      table-lookup                        11     0
30    377   1                                           3     9
31    378   2      no zeros, zerofill(1)                2     9
32    380   8      no zeros                             2     9
33    388   4      always zero                          2     9
34    392   4      table-lookup                        12     0
35    396   4      no zeros, zerofill(1)               13     9
36    400   4      no zeros, zerofill(1)                2     9
37    404   1                                           2     9
38    405   4      no zeros                             2     9
39    409   4      always zero                          2     9
40    413   4      no zeros                             2     9
41    417   4      always zero                          2     9
42    421   4      no zeros                             2     9
43    425   4      always zero                          2     9
44    429   20     no empty                             3     9
45    449   30     no empty                             3     9
46    479   1                                          14     4
47    480   1                                          14     4
48    481   79     no endspace, no empty               15     9
49    560   79     no empty                             2     9
50    639   79     no empty                             2     9
51    718   79     no endspace                         16     9
52    797   8      no empty                             2     9
53    805   1                                          17     1
54    806   1                                           3     9
55    807   20     no empty                             3     9
56    827   4      no zeros, zerofill(2)                2     9
57    831   4      no zeros, zerofill(1)                2     9

以下、myisampack によって出力される情報について説明します。

  • normal

    パックが使用されなかったカラムの数。

  • empty-space

    値が空白スペースのみのカラムの数。これらは 1 ビットになる。

  • empty-zero

    値がバイナリの 0 のみのカラムの数。これらは 1 ビットになる。

  • empty-fill

    整数カラムで、その型の全バイト範囲を占めていないカラムの数。これらは、より小さな型に変換される(たとえば、INTEGER カラムを MEDIUMINT に変更する)。

  • pre-space

    数値カラムのうち、値の先頭に空白スペースがあるカラムの数。この場合、各値には先頭スペースのカウントが含まれる。

  • end-space

    末尾に空白スペースがあるカラムの数。この場合、各値には末尾スペースのカウントが含まれる。

  • table-lookup

    カラムに複数の値が少ししかなく、ハフマン圧縮の前に ENUM に変換された。

  • zero

    すべての値がゼロであるカラムの数。

  • Original trees

    ハフマンツリーの初期番号。

  • After join

    領域を節約するためにツリーを結合した後に残った、独立したハフマンツリーの数。

テーブルが圧縮された後で myisamchk -dvv を実行すると、各フィールドについての以下の追加情報が出力されます。

  • Type

    フィールド型には以下の記述子が入る。

    • constant

      すべてのレコードが同じ値。

    • no endspace

      エンドスペースを保存しない。

    • no endspace, not_always

      エンドスペースを保存せず、すべての値でエンドスペース圧縮を実行しない。

    • no endspace, no empty

      エンドスペースを保存しない。空白値を保存しない。

    • table-lookup

      カラムが ENUM に変換された。

    • zerofill(n)

      値内の最も重要な n バイトは常に 0 なので、保存しない。

    • no zeros

      ゼロを保存しない。

    • always zero

      0 値を 1 ビットで保存する。

  • Huff tree

    フィールドに関連付けられているハフマンツリー。

  • Bits

    ハフマンツリーで使用されているビット数。

pack_isam または myisampack を実行後、isamchk または myisamchk を実行してインデックスを再生成する必要があります。このとき、MySQL オプティマイザの効率性を上げるために、インデックスブロックをソートし、統計を作成しておくこともできます。

myisamchk -rq --analyze --sort-index table_name.MYI
isamchk   -rq --analyze --sort-index table_name.ISM

パックされたテーブルを MySQL データベースディレクトリにインストールした後、mysqladmin flush-tables を実行して、mysqld が新しいテーブルを使用して起動するようにしてください。

パックされたテーブルをアンパックするには、--unpack オプションで isamchk または myisamchk を実行します。

4.8.5. mysqld-max(拡張 mysqld サーバ)

mysqld-max は、以下のオプションでコンフィギャされた MySQL サーバ(mysqld)です。

オプションコメント
--with-server-suffix=-max-max サフィックスを mysqld バージョン文字列に追加。
--with-innodbInnoDB テーブルのサポート(MySQL 3.23 のみ)。
--with-bdbBerkeley DB(BDB)テーブルのサポート。
CFLAGS=-DUSE_SYMDIRWindows でのシンボリックリンクのサポート。

InnoDB サポートを有効化するオプションは、MySQL 3.23 でのみ必要です。MySQL 4 以降では、InnoDB はデフォルトで含まれています。

MySQL-Max バイナリは http://www.mysql.com/downloads/mysql-max-4.0.html にあります。

Windows MySQL バイナリディストリビューションには、標準 mysqld.exe バイナリと mysqld-max.exe バイナリの両方が含まれています。 http://www.mysql.com/downloads/mysql-4.0.html。 See 項2.1.1. 「Windows への MySQL のインストール」

注意: BerkeleyDB(BDB)はすべてのプラットフォームで利用できるわけではなく、BDB をサポートしない Max バイナリもあります。サポートされているテーブル型を確認するには、以下のクエリを実行します。

mysql> SHOW VARIABLES LIKE "have_%";
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| have_bdb         | NO       |
| have_crypt       | YES      |
| have_innodb      | YES      |
| have_isam        | YES      |
| have_raid        | NO       |
| have_symlink     | DISABLED |
| have_openssl     | NO       |
| have_query_cache | YES      |
+------------------+----------+

2 番目のカラムの値には以下の意味があります。

意味
YESオプションは有効化されており、使用可能である。
NOMySQL は、このオプションをサポートするようにはコンパイルされていない。
DISABLEDmysqld--skip-xxxx で起動したか、このオプションを有効化するために必要なオプションが足りない状態で mysqld が起動したため、xxxx オプションが無効になっている。この場合、hostname.err ファイルに、このオプションが無効になっている理由が示される。

注意: InnoDB テーブルを MySQL バージョン 3.23 で作成できるようにするには、少なくとも innodb_data_file_path オプションを含めるようにスタートアップオプションを編集する必要があります。 See 項7.5.2. 「MySQL バージョン 3.23 での InnoDB」

BDB テーブルのパフォーマンスを向上させるには、そのための設定オプションもいくつか追加することが必要です。 See 項7.6.3. 「BDB 起動オプション」

mysqld_safe は自動的に、-max サフィックスの mysqld バイナリを開始しようとします。この機能により、既存のインストールで別の mysqld バイナリを簡単にテストすることができます。必要なオプションで configure を実行し、新規 mysqld バイナリを、古い mysqld バイナリと同じディレクトリに mysqld-max としてインストールします。 See 項4.8.2. 「mysqld_safemysqld のラッパ)」

Linux では、MySQL-Max RPM は上記の mysqld_safe 機能を使用します(これは単に mysqld-max 実行可能ファイルをインストールするだけなので、mysqld_safe の再起動時、mysqld_safe は自動的にこの実行可能ファイルを使用します)。

以下の表は、MySQL-Max バイナリにどのテーブル型が含まれているかを示したものです。

システムBDBInnoDB
Windows/NTYY
AIX 4.3NY
HP-UX 11.0NY
Linux-AlphaNY
Linux-IntelYY
Linux-IA-64NY
Solaris-IntelNY
Solaris-SPARCYY
SCO OSR5YY
UnixWareYY
Mac OS XNY

注意: MySQL 4 以降、デフォルトで InnoDB が含まれるようになったので、InnoDB 用の MySQL Max サーバは必要なくなりました。

4.9. MySQL クライアントサイドのスクリプトとユーティリティ

4.9.1. クライアントサイドのスクリプトとユーティリティの概要

mysqlclient ライブラリを使用してサーバと通信する MySQL クライアントはすべて、以下の環境変数を使用します。

名前説明
MYSQL_UNIX_PORTデフォルトソケット。localhost との接続に使用。
MYSQL_TCP_PORTデフォルトの TCP/IP ポート。
MYSQL_PWDデフォルトのパスワード。
MYSQL_DEBUGデバッグ時のデバッグトレースオプション。
TMPDIRテンポラリテーブルまたはテンポラリファイルが作成されるディレクトリ。

MYSQL_PWD を使用することは安全な方法ではありません。 See 項4.3.8. 「MySQL サーバへの接続」

Unix では、mysql クライアントは、MYSQL_HISTFILE 環境変数で指定されたファイルを使用してコマンドライン履歴を保存します。ヒストリファイルのデフォルト値は $HOME/.mysql_history です。ここで、$HOMEHOME 環境変数の値です。 See 付録?F. 環境変数

クエリ履歴が記録されたファイルを必要としない場合には、まず、.mysql_history が存在する場合はそれを削除し、次に以下のいずれかを実行します。

  • MYSQL_HISTFILE 変数を /dev/null に設定する。この設定をログインごとに有効にするには、この設定をシェルのスタートアップファイルに入力する。

  • .mysql_histfile/dev/null へのシンボリックリンクとして作成する。

    shell> ln -s /dev/null $HOME/.mysql_history
    

    これは、1 度実行するだけでよい。

すべての MySQL プログラムが多くのさまざまなオプションを使用します。しかし、すべての MySQL プログラムに --help オプションが用意されており、このオプションを使用することにより、そのプログラムのすべてのオプションの説明を表示することができます。たとえば、mysql --help を試してみてください。

すべての標準クライアントプログラムのデフォルトオプションは、オプション設定ファイルで上書きできます。 項4.1.2. 「my.cnf オプション設定ファイル」

以下の一覧は、クライアントサイドの MySQL プログラムを簡単に説明したものです。

  • msql2mysql

    mSQL プログラムを MySQL に変換するシェルスクリプト。すべてのケースに対応するわけではないが、変換時に最初に試行すべきものである。

  • mysql

    対話的にクエリを入力したり、バッチモードでファイルからクエリを実行するためのコマンドラインツール。 See 項4.9.2. 「mysql(コマンドラインツール)」

  • mysqlcc

    このプログラムは、サーバと対話するためのグラフィカルインタフェースを提供する。 See 項4.9.3. 「mysqlcc(MySQL コントロールセンタ)」

  • mysqlaccess

    ホスト、ユーザ、およびデータベースの組み合わせのアクセス権限をチェックするスクリプト。

  • mysqladmin

    データベースを作成または破棄したり、権限テーブルを再度読み込んだり、テーブルをディスクにフラッシュしたり、ログファイルを再度開くなどの管理操作を実行するユーティリティ。mysqladmin は、サーバからバージョン情報、プロセス情報、およびステータス情報を取得するためにも使用できる。 See 項4.9.4. 「mysqladmin(MySQL サーバの管理)」

  • mysqlbinlog

    バイナリログからクエリを読み取るためのユーティリティ。クラッシュ時、古いバックアップでリカバリするために使用できる。 See 項4.9.5. 「mysqlbinlog(バイナリログからクエリを実行する)」

  • mysqldump

    MySQL データベースを SQL ステートメントまたはタブ区切りのテキストファイルとして、ファイルにダンプする。Igor Romanenko 提供の拡張フリーウェア。 See 項4.9.7. 「mysqldump(テーブル構造とデータのダンプ)」

  • mysqlimport

    LOAD DATA INFILE を使用して各テーブルにテキストファイルをインポートする。 See 項4.9.9. 「mysqlimport(テキストファイルからのデータのインポート)」

  • mysqlshow

    データベース、テーブル、カラム、およびインデックスに関する情報を表示する。

  • replace

    msql2mysql によって使用されるユーティリティプログラム。ただし、それ以外にも使用範囲は広い。replace は、ファイルや標準入力内の文字列を変更する。有限ステートマシンを使用して、最初に長い文字列の突き合わせを行う。文字列の入れ替えに使用できる。たとえば以下のコマンドは、指定ファイル内の ab を入れ替える。

    shell> replace a b b a -- file1 file2 ...
    

4.9.2. mysql(コマンドラインツール)

mysql はシンプルな SQL シェルです(GNU readline 機能がある)。対話形式と非対話形式をサポートしています。対話形式で使用した場合、クエリ結果は ASCII テーブル形式で表示されます。非対話形式(フィルタなど)で使用した場合、結果はタブ区切り形式で表示されます(出力形式は、コマンドラインオプションで変更できます)。以下のように簡単ににスクリプトを実行できます。

shell> mysql database < script.sql > output.tab

クライアントでメモリ不足による問題が発生した場合、--quick オプションを使用します。これにより、mysqlmysql_store_result() ではなく、mysql_use_result() を使用して結果セットを取得します。

mysql の使用は非常に簡単です。mysql database または mysql --user=user_name --password=your_password database のように、開始します。SQL ステートメントを入力し、‘;’、'\g'、または '\G' で終了して Enter キーを押します。

mysql は、以下のオプションをサポートします。

  • -?, --help

    ヘルプを表示して終了する。

  • -A, --no-auto-rehash

    自動リハッシュを実行しない。テーブルおよびフィールドを完成させるには、'リハッシュ' を実行する必要がある。このオプションにより、mysql の起動が速くなる。

  • --prompt=...

    mysql プロンプトを指定の形式に設定する。

  • -b, --no-beep

    エラー時のビープ音をオフにする。

  • -B, --batch

    結果をタブで区切り、各レコードが 1 行になるように出力する。ヒストリファイルでは使用しないこと。

  • --character-sets-dir=...

    キャラクタセットが格納されているディレクトリ。

  • -C, --compress

    サーバ/クライアントプロトコルで圧縮を使用する。

  • -#, --debug[=...]

    デバッグログ。デフォルトは 'd:t:o,/tmp/mysql.trace'。

  • -D, --database=...

    使用するデータベース。このオプションは主に、my.cnf ファイルで使用する。

  • --default-character-set=...

    デフォルトのキャラクタセットを設定する。

  • -e, --execute=...

    コマンドを実行して終了する(--batch と同じ出力)。

  • -E, --vertical

    クエリ(レコード)を縦方向に出力する。このオプションを指定しなくても、ステートメントを \G で終了すれば、同じように出力できる。

  • -f, --force

    SQL エラーが発生しても続行する。

  • -g, --no-named-commands

    名前付きコマンドが無効になる。\* 形式のみ使用する。またはセミコロン(‘;’)で終わる行の最初でのみ名前付きコマンドを使用する。バージョン 10.9 以降、クライアントは起動時に、デフォルトでこのオプションを有効にするようになっている。ただし、-g オプションでは、ロング形式のコマンドは最初の行から機能する。

  • -G, --enable-named-commands

    名前付きコマンドが有効になる。ロング形式のコマンドもショートの \* コマンドと同様、有効になる。

  • -i, --ignore-space

    関数名の後のスペースを無視する。

  • -h, --host=...

    指定のホストに接続する。

  • -H, --html

    HTML 出力を生成する。

  • -X, --xml

    XML 出力を生成する。

  • -L, --skip-line-numbers

    エラーの行番号を書き込まない。これは、エラーメッセージが含まれる結果ファイルを比較する際に使用する。

  • --no-pager

    ページャーを無効にし、stdout に出力する。対話式ヘルプ(\h)も参照のこと。

  • --no-tee

    出力ファイルを無効にする。対話式ヘルプ(\h)も参照のこと。

  • -n, --unbuffered

    クエリごとにバッファをフラッシュする。

  • -N, --skip-column-names

    結果にカラム名を書き込まない。

  • -O, --set-variable=name=value

    変数に値を設定する。--help により、変数が一覧表示される。 注意: --set-variable=name=value および -O name=value 構文は、MySQL 4.0 で廃止されたた。代わりに --name=value を使用すること。

  • -o, --one-database

    デフォルトのデータベースだけを更新する。バイナリログ内の他のデータベースを更新しない場合に使用する。

  • --pager[=...]

    出力タイプ。デフォルトは ENV 変数の PAGER である。有効なページャーは、less、more、cat [> filename] など。対話式ヘルプ(\h)も参照のこと。このオプションはバッチモードでは無効。ページャーは Unix でのみ動作する。

  • -p[password], --password[=...]

    サーバ接続時に使用するパスワード。パスワードをコマンドラインで指定しなかった場合、プロンプトが表示される。注意: ショート形式の -p を使用する場合、オプションとパスワードの間にスペースを入れてはいけない。

  • -P port_num, --port=port_num

    接続に使用する TCP/IP ポート番号。

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    使用する接続プロトコルを指定する。MySQL 4.1 で導入。

  • -q, --quick

    結果をキャッシュせず、行ごとに出力する。出力が中断した場合、サーバが遅くなる可能性がある。ヒストリファイルは使用しない。

  • -r, --raw

    エスケープ変換なしでカラム値を書き出す。--batch とともに使用。

  • --reconnect

    接続が失われた場合、サーバへの再接続を自動的に 1 度だけ試行する。

  • -s, --silent

    サイレントモード。

  • -S --socket=...

    接続に使用するソケットファイル。

  • -t --table

    表形式で出力。これは、非バッチモードでのデフォルトである。

  • -T, --debug-info

    終了時にデバッグ情報を出力する。

  • --tee=...

    出力ファイルにすべて出力する。対話式ヘルプ(\h)も参照のこと。バッチモードでは無効。

  • -u, --user=#

    カレントユーザでない場合のログインユーザ。

  • -U, --safe-updates[=#], --i-am-a-dummy[=#]

    キーを使用する UPDATEDELETE のみ許可する。このオプションについては、詳細を後で説明する。このオプションが my.cnf ファイルに含まれている場合、--safe-updates=0 でリセットできる。

  • -v, --verbose

    冗長出力(-v -v -v で表出力形式となる)。

  • -V, --version

    バージョン情報を出力して終了する。

  • -w, --wait

    接続が切断された場合、停止せずに待機して再試行する。

-O または --set-variable には、以下の変数も設定できます。注意: --set-variable=name=value および -O name=value 構文は、MySQL 4.0 で廃止されましたた。代わりに --name=value を使用してください。

変数名デフォルト説明
connect_timeout0接続タイムアウトの秒数。
local-infile0LOAD DATA INFILELOCAL 機能の無効化(0)または有効化(1)。
max_allowed_packet16777216サーバ間での送受信可能な最大パケット長。
net_buffer_length16384TCP/IP およびソケット接続用バッファ。
select_limit1000--safe-updates 使用時の SELECT の自動制限。
max_join_size1000000--safe-updates 使用時に 1 回の結合で扱うレコードの自動制限。

mysql クライアントがサーバにクエリを送信しているときに接続が切断された場合、クライアントは自動的に再接続を試行し、クエリを再度送信します。注意: 再接続に成功した場合でも、最初の接続が終了した時点で、前回のセッションオブジェクト(テンポラリテーブル、ユーザ変数、セッション変数)はすべて失われています。したがって、上記の動作にはリスクが伴います。たとえば、以下の例の場合、ユーザが気付かない間にサーバがシャットダウンし、再起動しています。

mysql> set @a=1;
Query OK, 0 rows affected (0.05 sec)

mysql> insert into t values(@a);
ERROR 2006: MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: test

Query OK, 1 row affected (1.30 sec)

mysql> select * from t;
+------+
| a    |
+------+
| NULL |
+------+
1 row in set (0.05 sec)

この場合、@a ユーザ変数は接続の切断と同時に失われ、再接続後は未定義になっています。このリスクを回避するには、mysql クライアントを --disable-reconnect オプションで開始します。

コマンドラインで 'help' を入力すると、mysql がサポートするコマンドを出力できます。

mysql> help

MySQL commands:
help      (\h)    Display this text.
?         (\h)    Synonym for `help'.
clear     (\c)    Clear command.
connect   (\r)    Reconnect to the server.
                  Optional arguments are db and host.
delimiter (\d)    Set query delimiter.
edit      (\e)    Edit command with $EDITOR.
ego       (\G)    Send command to mysql server,
                  display result vertically.
exit      (\q)    Exit mysql. Same as quit.
go        (\g)    Send command to mysql server.
nopager   (\n)    Disable pager, print to stdout.
notee     (\t)    Don't write into outfile.
pager     (\P)    Set PAGER [to_pager].
                  Print the query results via PAGER.
print     (\p)    Print current command.
prompt    (\R)    Change your mysql prompt.
quit      (\q)    Quit mysql.
rehash    (\#)    Rebuild completion hash.
source    (\.)    Execute an SQL script file.
                  Takes a file name as an argument.
status    (\s)    Get status information from the server.
system    (\!)    Execute a system shell command.
tee       (\T)    Set outfile [to_outfile].
                  Append everything into given outfile.
use       (\u)    Use another database.
                  Takes database name as argument.

editnopagerpagersystem の各コマンドは Unix でのみ動作します。

status コマンドを実行すると、接続情報と、使用しているサーバの情報を取得できます。--safe-updates モードで status を実行すると、クエリに影響する mysql 変数値も出力されます。

初心者に便利なスタートアップオプションとして、--safe-updates(MySQL バージョン 3.23.11 で導入)があります(または、どこかで DELETE FROM table_name を実行しているが WHERE 節を忘れたユーザの場合は --i-am-a-dummy)。このオプションを使用すると、接続時、mysql は以下のコマンドを MySQL サーバに送信します。

SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
    SQL_MAX_JOIN_SIZE=#max_join_size#"

ここで #select_limit##max_join_size# は、mysql コマンドラインから設定できる変数です。 See 項5.5.6. 「SET 構文」

効果は以下のとおりです。

  • WHERE 部分にキー制約がなければ、UPDATE ステートメントまたは DELETE ステートメントを実行できない。ただし、LIMIT を使用すれば UPDATE/DELETE を強制実行できる。

    UPDATE table_name SET not_key_column=# WHERE not_key_column=# LIMIT 1;
    

  • 大きな結果はすべて、自動的に #select_limit# レコードの制限を受ける。

  • #max_join_size 以上のレコードをチェックする必要がありそうな SELECT ステートメントは停止する。

mysql クライアントに関するヒント

データによっては、横方向ではなく、縦方向に表示したほうが見やすい場合があります。たとえば改行を含む長いテキストでは、縦方向に出力した方が読みやすくなります。

mysql> SELECT * FROM mails WHERE LENGTH(txt) < 300 lIMIT 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@no.spam.com
  mail_to: "Thimble Smith" <tim@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:

Thimble> Hi.  I think this is a good idea.  Is anyone familiar with UTF-8
Thimble> or Unicode? Otherwise, I'll put this on my TODO list and see what
Thimble> happens.

Yes, please do that.

Regards,
Monty
     file: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)

ログには、tee オプションを使用できます。tee--tee=... オプションで起動できます。または、tee コマンドで対話式にコマンドラインから起動することもできます。画面に表示されるデータはすべて、指定のファイルにも記録されます。これは、デバッグ目的にも非常に役立ちます。tee は、notee でコマンドラインから無効にできます。tee を再び実行すると、ログが再開されます。パラメータなしの場合、前回のファイルが使用されます。注意: tee は、コマンドごとに(次のコマンドを待つコマンドラインが表示される直前に)、結果をファイルにフラッシュします。

Unix の less、more、その他同様のプログラムの対話式モードで結果を参照したり検索するには、--pager[=...] オプションを使用します。引数がない場合、mysql クライアントは PAGER 環境変数を探して、pager をその値に設定します。 pager は、pager コマンドで対話式コマンドラインから開始でき、nopager コマンドで無効にできます。コマンドは任意の引数を取り、pager がその値に設定されます。pager コマンドは引数なしでも呼び出せますが、--pager オプションが使用されていることが必要になります。そうしなければ、pager はデフォルトで stdout になります。pager は、Windows にはない popen() 関数を使用するため、Unix でのみ有効です。Windows では代わりに tee オプションを使用できます。ただし状況によっては、pager ほど便利ではありません。

pager に関するヒント

  • ファイルへの書き込みに使用できる。

    mysql> pager cat > /tmp/log.txt
    

    これで、結果がファイルにのみ出力される。また、使用したいプログラムの任意のオプションを pager で渡すことができる。

    mysql> pager less -n -i -S
    

  • 上記例の -S オプションに注目。これは、結果を参照する際に非常に役立つ。このオプションを横方向の表示(\g または ‘;’ でコマンドを終了)、および縦方向の表示(\G でコマンドを終了)で試してみるとわかる。非常に幅の広い結果セットは画面上で見にくい場合があり、-S オプションを less に設定することにより、対話式の less で、画面幅より長い行が次の行まで続くことなく、結果セットを左から右に表示することができる。この方法により、結果セットを非常に見やすくできる。対話式の less で、-S によりこのモードのオンオフを切り替えることができる。less に関する詳細については 'h' を参照のこと。

  • 結果の処理には、非常に複雑な方法を組み合わせることができる。以下の例では、結果を、/dr1 と /dr2 にマウントされている 2 つの異なるハードディスク上の 2 つの異なるディレクトリにある 2 つのファイルに記録し、画面上では less で表示する。

    mysql> pager cat | tee /dr1/tmp/res.txt | \
    tee /dr2/tmp/res2.txt | less -n -i -S
    

上記の 2 つの関数を組み合わせることも可能です。tee を有効にし、pager を 'less' に設定することにより、Unix 'less' で結果を参照しながら同時に 1 つのファイルにすべてを記録することができます。pager で使用される Unix の teemysql クライアントの組み込み tee がありますが、組み込み teetee が利用できない場合でも使用できます。また、組み込み tee は画面で出力されたものすべてをログファイルに記録しますが、pager で使用される Unix tee はそれほど多くのことを記録しません。最後に、対話式 tee の方がオン/オフを切り替えやすいという点があります。ファイルに何かを記録したいのだが、ときどき機能をオフにもしたいという場合に便利です。

MySQL バージョン 4.0.2 から、mysql コマンドラインクライアントでプロンプトを変更できるようになりました。

以下のプロンプトオプションを使用できます。

オプション説明
\vmysqld バージョン
\d使用中のデータベース
\h接続ホスト
\p接続ポート
\uユーザ名
\U完全ユーザ名@ホスト
\\\
\n新規改行
\tタブ
\スペース
\_スペース
\R24 時間形式(0 ? 23)
\r標準時間形式(1 ? 12)
\m
\y2 桁年
\Y4 桁年
\D完全日付形式
\s
\w3 文字形式での曜日(Mon、Tue など)
\Pam/pm
\o数字による月
\O3 文字形式での月(Jan、Feb など)
\cコマンド実行ごとにカウントするカウンタ

\’ にそれ以外の文字が続くと、単にその文字になります。

プロンプトは以下の場所で設定できます。

  • 環境変数

    MYSQL_PS1 環境変数をプロンプト文字列に設定できる。次に例を示す。

    shell> export MYSQL_PS1="(\u@\h) [\d]> "
    

  • my.cnf , .my.cnf

    MySQL 設定ファイルの mysql グループで prompt オプションを設定できる。次に例を示す。

    [mysql]
    prompt=(\u@\h) [\d]>\_
    

  • コマンドライン

    mysql のコマンドラインで --prompt オプションを設定できる。 次に例を示す。

    shell> mysql --prompt="(\u@\h) [\d]> "
    
    (user@host) [database]> 
    

  • 対話式

    prompt(または \R)を使用して対話式にプロンプトを変更することもできる。次に例を示す。

    mysql> prompt (\u@\h) [\d]>\_
    PROMPT set to '(\u@\h) [\d]>\_'
    (user@host) [database]> 
    (user@host) [database]> prompt
    Returning to default PROMPT of mysql> 
    mysql> 
    

4.9.3. mysqlcc(MySQL コントロールセンタ)

mysqlcc(MySQL コントロールセンタ)はプラットフォームに依存しないクライアントで、MySQL データベースサーバへのグラフィカルユーザインタフェース(GUI)を提供します。対話使用をサポートし、構文強調やタブ完成の機能も含まれます。データベース、テーブル、およびサーバの管理もできます。

現在、mysqlcc は Windows プラットフォームと Linux プラットフォームで動作します。

mysqlcc は MySQL ディストリビューションには含まれていませんが、http://www.mysql.com/downloads/ からダウンロードできます。

mysqlcc は、以下のオプションをサポートします。

  • -?, --help

    ヘルプを表示して終了する。

  • -b, --blocking_queries

    クエリのブロックを使用する。

  • -C, --compress

    サーバ/クライアントプロトコルで圧縮を使用する。

  • -c, --connection_name=name

    --server のシノニム。

  • -d, --database=...

    使用するデータベース。これは主に、my.cnf ファイルで使用。

  • -H, --history_size=#

    クエリウィンドウのヒストリサイズ。

  • -h, --host=...

    指定のホストに接続する。

  • -p[password], --password[=...]

    サーバ接続時に使用するパスワード。パスワードをコマンドラインで指定しなかった場合、プロンプトが表示される。注意: ショート形式の -p を使用する場合、オプションとパスワードの間にスペースを入れてはいけない。

  • -g, --plugins_path=name

    MySQL コントロールセンタのプラグインが置かれているディレクトリのパス。

  • -P port_num, --port=port_num

    接続に使用する TCP/IP ポート番号。

  • -q, --query

    起動時にクエリウィンドウを開く。

  • -r, --register

    起動時に 'Register Server' ダイアログを開く。

  • -s, --server=name

    MySQL コントロールセンタの接続名。

  • -S --socket=...

    接続に使用するソケットファイル。

  • -y, --syntax

    構文強調および完成を有効化。

  • -Y, --syntax_file=name

    完成する構文ファイル。

  • -T, --translations_path=name

    MySQL コントロールセンタ翻訳の置かれているディレクトリのパス。

  • -u, --user=#

    カレントユーザでない場合のログインユーザ。

  • -V, --version

    バージョン情報を出力して終了する。

-O または --set-variable には以下の変数も設定できます。 注意: --set-variable=name=value および -O name=value 構文は、MySQL 4.0 で廃止されました。代わりに --name=value を使用してください。

変数名デフォルト説明
connect_timeout0接続タイムアウトまでの秒数。
local-infile0LOAD DATA INFILELOCAL 機能の無効化(0)または有効化(1)。
max_allowed_packet16777216サーバ間での送受信可能な最大パケット長。
net_buffer_length16384TCP/IP およびソケット接続用バッファ。
select_limit1000--safe-updates 使用時の SELECT の自動制限。
max_join_size1000000--safe-updates 使用時に 1 回の結合で扱うレコードの自動制限。

4.9.4. mysqladmin(MySQL サーバの管理)

管理操作を実行するためのユーティリティです。構文は以下のとおりです。

shell> mysqladmin [OPTIONS] command [command-option] command ...

使用しているバージョンの mysqladmin がサポートするオプション一覧を表示するには、mysqladmin --help を実行します。

現在の mysqladmin は以下のコマンドをサポートしています。

  • create databasename

    新しいデータベースを作成する。

  • drop databasename

    データベースとそのすべてのテーブルを削除する。

  • extended-status

    サーバから拡張ステータスメッセージを取得する。

  • flush-hosts

    キャッシュされたすべてのホストをフラッシュする。

  • flush-logs

    すべてのログをフラッシュする。

  • flush-tables

    すべてのテーブルをフラッシュする。

  • flush-privileges

    権限テーブルを再読み込みする(reload と同じ)。

  • kill id,id,...

    mysql スレッドを強制終了する。

  • password

    新規パスワードを設定する。旧パスワードを新規パスワードに変更する。

  • ping

    mysqld が稼動中かどうかを確認する。

  • processlist

    サーバでアクティブなスレッドを一覧表示する。SHOW PROCESSLIST ステートメントと同じ。--verbose オプションが指定されている場合、SHOW FULL PROCESSLIST の出力に似た結果が出力される。

  • reload

    権限テーブルを再度読み込む。

  • refresh

    すべてのテーブルをフラッシュし、ログファイルを閉じてまた開く。

  • shutdown

    サーバをシャットダウンする。

  • slave-start

    スレーブレプリケーションスレッドを開始する。

  • slave-stop

    スレーブレプリケーションスレッドを停止する。

  • status

    サーバから短いステータスメッセージを取得する。

  • variables

    利用可能な変数を出力する。

  • version

    サーバからバージョン情報を取得する。

コマンドはすべて、それぞれ独自のプレフィックスで短縮可能です。次に例を示します。

shell> mysqladmin proc stat
+----+-------+-----------+----+-------------+------+-------+------+
| Id | User  | Host      | db | Command     | Time | State | Info |
+----+-------+-----------+----+-------------+------+-------+------+
| 6  | monty | localhost |    | Processlist | 0    |       |      |
+----+-------+-----------+----+-------------+------+-------+------+
Uptime: 10077  Threads: 1  Questions: 9  Slow queries: 0
Opens: 6 Flush tables: 1  Open tables: 2
Memory in use: 1092K  Max memory used: 1116K

mysqladmin status コマンドの結果には、以下のカラムが含まれます。

カラム説明
UptimeMySQL サーバか稼動している秒数。
Threadsアクティブなスレッド(クライアント)の数。
Questionsmysqld が起動してからクライアントから発行された質問の数。
Slow querieslong_query_time 秒より時間がかかったクエリ。 See 項4.10.5. 「スロークエリログ」
Opensmysqld が開いたテーブルの数。
Flush tablesflush ...refreshreload の各コマンドの回数。
Open tables現在開いているテーブルの数。
Memory in usemysqld コードによって直接割り当てられているメモリ(MySQL が --with-debug=full でコンパイルされている場合にのみ利用可能)。
Max memory usedmysqld コードによって直接割り当てられている最大メモリ(MySQL が --with-debug=full でコンパイルされている場合にのみ利用可能)。

ソケットで(つまり mysqld が実行しているコンピュータで)mysqladmin shutdown を実行すると、mysqld の正常終了を確認するため、mysqladmin は MySQL pid-file が削除されるのを待ちます。

4.9.5. mysqlbinlog(バイナリログからクエリを実行する)

mysqlbinlog ユーティリティを使用して、バイナリログファイル(see 項4.10.4. 「バイナリログ」)を調べることができます。

shell> mysqlbinlog hostname-bin.001

上記の例では、バイナリログ hostname-bin.001 に含まれるすべてのクエリが、クエリにかかった時間、クエリを発行したスレッドの ID、クエリ発行時のタイムスタンプなどの情報とともに出力されます。

mysqlbinlog の出力を mysql クライアントに送信できます。これは、古いバックアップでリカバリするときに使用します(see 項4.5.1. 「データベースのバックアップ」)。

shell> mysqlbinlog hostname-bin.001 | mysql

または

shell> mysqlbinlog hostname-bin.[0-9]* | mysql

また、mysqlbinlog の出力をテキストファイルにリダイレクトし、そのテキストファイルを編集(何らかの理由で実行したくないクエリを削除)し、テキストファイルから mysql に対してクエリを実行することもできます。

mysqlbinlog には position=# オプションがあり、バイナリログでのオフセットが # 以上のクエリだけを出力することができます。

MySQL サーバで実行するバイナリログが複数ある場合、単一の MySQL 接続で実行する方が安全です。以下は、安全でない例です。

shell> mysqlbinlog hostname-bin.001 | mysql # DANGER!!
shell> mysqlbinlog hostname-bin.002 | mysql # DANGER!!

最初のバイナリログに CREATE TEMPORARY TABLE が含まれ、2 番目のバイナリログにこのテンポラリテーブルを使用するクエリが含まれていると、問題が発生します。最初の mysql が終了すると、テンポラリテーブルが破棄されるので、2 番目の mysql は ``unknown table'' を報告することになります。これが、すべてのバイナリログを単一の接続で実行すべき理由です。テンポラリテーブルを使用する場合には特に気を付けてください。2 つの方法があります。

shell> mysqlbinlog hostname-bin.001 hostname-bin.002 | mysql
shell> mysqlbinlog hostname-bin.001 >  /tmp/queries.sql
shell> mysqlbinlog hostname-bin.002 >> /tmp/queries.sql
shell> mysql -e "source /tmp/queries.sql"

MySQL 4.0.14 以降、mysqlbinlog は、バイナリログから LOAD DATA INFILE を実行するための mysql に対する適切な入力を提供できるようになっています。ロードするデータがバイナリログに含まれるため(これは MySQL 4.0 の場合です。MySQL 3.23 ではロードされたデータがバイナリログに書き込まれないため、バイナリログの内容を実行するにはオリジナルファイルが必要でした)、mysqlbinlog はこのデータをテンポラリファイルにコピーして LOAD DATA INFILE コマンドを出力し、mysql にこのテンポラリファイルをロードさせます。テンポラリファイルが作成されるデフォルトのディレクトリはテンポラリディレクトリです。これは、mysqlbinloglocal-load オプションで変更できます。

MySQL 4.1 より前は、同じ名前のテンポラリテーブルを使用する複数の異なるスレッドのクエリがバイナリログに含まれていました。そのため、これらのクエリが混ざっている場合、mysqlbinlogmysql に対して適切な出力を提供できませんでした。これは、MySQL 4.1 で解決されています。

また、mysqlbinlog --read-from-remote-server を使用して、リモート MySQL サーバから直接バイナリログを読み取ることも可能です。ただし、より簡単に、稼動中の MySQL サーバにバイナリログを適用できるようにするため、これはいずれ廃止する予定です。

詳細については、mysqlbinlog --help を実行してください。

4.9.6. mysqlcheck を使用したテーブルの保守とクラッシュのリカバリ

MySQL バージョン 3.23.38 以降、MyISAM テーブルのチェックおよび修復のために新しいツールを利用できるようになっています。myisamchk との違いは、myisamchk が、サーバが実行していないときに使用するのに対し、mysqlcheckmysqld サーバが実行しているときに使用します。テーブルのチェックまたは修復のたびにサーバを停止する必要がなくなりました。

mysqlcheck は、MySQL サーバコマンド CHECKREPAIRANALYZE、および OPTIMIZE を利用して、便利なテーブルの保守およびクラッシュからのリカバリ方法を提供します。

mysqlcheck を開始する方法は 3 つあります。

shell> mysqlcheck [OPTIONS] database [tables]
shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...]
shell> mysqlcheck [OPTIONS] --all-databases

データベースおよびテーブルの選択に関しては、mysqldump と似た方法になります。

mysqlcheck には、他のクライアントにはない特殊機能があります。デフォルトの動作であるテーブルチェック(-c)を、バイナリの名前を変更することによって変更できます。デフォルトでテーブルを修復するツールが必要であれば、mysqlcheckmysqlrepair という新しい名前でハードドライブにコピーするか、mysqlrepair へのシンボリックリンクを作成し、そのシンボリックリンクの名前を mysqlrepair にします。mysqlrepair を起動すると、デフォルトでテーブルが修復されます。

mysqlcheck のデフォルト動作を変更するために使用できる名前は以下のとおりです。

mysqlrepair:   The default option will be -r
mysqlanalyze:  The default option will be -a
mysqloptimize: The default option will be -o

以下、mysqlcheck で使用可能なオプションの一覧です。使用しているバージョンでのサポート状態を確認するには、mysqlcheck --help を実行してください。

  • -A, --all-databases

    すべてのデータベースをチェックする。これは、すべてのデータベースを選択した状態で --databases を実行するのと同じである。

  • -1, --all-in-1

    テーブルごとにクエリを 1 つずつ作成するのではなく、データベースごとにまとめてすべてのクエリを実行する。テーブル名はカンマで区切る。

  • -a, --analyze

    指定したテーブルを分析する。

  • --auto-repair

    チェックしたテーブルが破損していた場合、自動的に修復する。破損したテーブルがあった場合、すべてのテーブルのチェックが終わってから修復が行われる。

  • -#, --debug=...

    デバッグログを出力する。これは、'd:t:o,filename' であることが多い。

  • --character-sets-dir=...

    キャラクタセットが格納されているディレクトリ。

  • -c, --check

    テーブルのエラーをチェックする。

  • -C, --check-only-changed

    前回のチェック以降に変更されたテーブルと、正しく閉じられなかったテーブルだけをチェックする。

  • --compress

    サーバ/クライアントプロトコルで圧縮を使用する。

  • -?, --help

    ヘルプメッセージを表示して終了する。

  • -B, --databases

    いくつかのデータベースをチェックする。注意: ここでは、テーブルを指定しない。名前の引数はすべて、データベース名として扱われる。

  • --default-character-set=...

    デフォルトのキャラクタセットを設定する。

  • -F, --fast

    正しく閉じられなかったテーブルだけをチェックする。

  • -f, --force

    SQL エラーが発生しても続行する。

  • -e, --extended

    このオプションを CHECK TABLE とともに使用すれば、テーブルの整合性が 100 パーセント保証されるが、時間がかかる。

    このオプションを REPAIR TABLE とともに使用した場合、テーブルの拡張修復が行われる。ただし、時間がかかるだけでなく、無駄なレコードも多く生成される可能性がある。

  • -h, --host=...

    ホストに接続する。

  • -m, --medium-check

    extended-check よりも速いが、全エラーの 99.99% しか見つけられない。しかし、ほとんどの場合これで十分である。

  • -o, --optimize

    テーブルを最適化する。

  • -p, --password[=...]

    サーバ接続時に使用するパスワード。パスワードを指定しなければ、プロンプトが表示される。

  • -P, --port=...

    TCP/IP 接続に使用するポート番号。

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    使用する接続プロトコルを指定する。MySQL 4.1 で導入。

  • -q, --quick

    このオプションを CHECK TABLE とともに使用すれば、不正リンクをチェックするレコードスキャンが行われない。これが最速のチェックである。

    このオプションを REPAIR TABLE とともに使用すると、インデックスツリーの修復だけが実行される。これが、最速のテーブルの修復である。

  • -r, --repair

    ほとんどのエラーを修復できる、ただし、ユニークキーが一意でないエラーには対応できない。

  • -s, --silent

    エラーメッセージだけを出力する。

  • -S, --socket=...

    接続に使用するソケットファイル。

  • --tables

    --databases-B)オプションを上書きする。このオプションの後ろの引数はすべて、テーブル名と見なされる。

  • -u, --user=#

    カレントユーザでない場合のログインユーザ。

  • -v, --verbose

    さまざまな段階の情報を出力する。

  • -V, --version

    バージョン情報を出力して終了する。

4.9.7. mysqldump(テーブル構造とデータのダンプ)

バックアップ用のデータベースまたはデータベースの集合をダンプしたり、他の SQL サーバ(MySQL サーバである必要はない)にデータを移動するためのユーティリティです。ダンプには、テーブル作成や入力のための SQL ステートメントが含まれます。

同じサーバ上でバックアップを行う場合には、mysqlhotcopy の方の使用を考慮してください。 See 項4.9.8. 「mysqlhotcopy(MySQL のデータベースとテーブルのコピー)」

    mysqldump [OPTIONS] database [tables]
か  mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
か  mysqldump [OPTIONS] --all-databases [OPTIONS]

テーブルを指定しなかったり、--databases オプションまたは --all-databases オプションを使用すると、データベース全体がダンプされます。

使用しているバージョンの mysqldump がサポートするオプションの一覧を照会するには、mysqldump --help を実行します。

注意: mysqldump--quick または --opt なしで実行すると、mysqldump は結果をダンプする前に、結果セット全体をメモリにロードします。これは、大きなデータベースをダンプする際、問題になる可能性があります。

注意: mysqldump プログラムの新しいコピーを使用している場合で、非常に古い MySQL サーバに読み込むダンプを行うときには、--opt オプションまたは -e オプションは使用しないでください。

mysqldump は、以下のオプションをサポートします。

  • --add-locks

    各テーブルダンプの前に LOCK TABLES を追加し、後に UNLOCK TABLE を追加する(MySQL への挿入を速くするため)。

  • --add-drop-table

    各作成ステートメントの前に drop table を追加する。

  • -A, --all-databases

    すべてのデータベースをダンプする。これは、すべてのデータベースを選択した状態で --databases を実行するのと同じである。

  • -a, --all

    MySQL 固有の作成オプションをすべて含める。

  • --allow-keywords

    キーワードであるカラム名の作成を認める。各カラム名の先頭にテーブル名を付け加えることが必要。

  • -c, --complete-insert

    完全な挿入ステートメント(カラム名も指定)を使用する。

  • -C, --compress

    クライアントとサーバの両方が圧縮をサポートする場合、クライアントとサーバ間の情報をすべて圧縮する。

  • -B, --databases

    いくつかのデータベースをダンプする。注意:ここでは、テーブル名を指定しない。名前の引数はすべて、データベース名として扱われる。 出力される各新規データベースの前に USE db_name; が追加される。

  • --delayed

    INSERT DELAYED コマンドでレコードを挿入する。

  • -e, --extended-insert

    新しい複数行 INSERT 構文を使用する(さらにコンパクトで速い挿入ステートメントを提供)。

  • -#, --debug[=option_string]

    プログラムのトレース使用(デバック目的)。

  • --help

    ヘルプメッセージを表示して終了する。

  • --fields-terminated-by=... , --fields-enclosed-by=... , --fields-optionally-enclosed-by=... , --fields-escaped-by=... , --lines-terminated-by=...

    これらのオプションは -T オプションとともに使用する。LOAD DATA INFILE の対応する節と同じ意味を持つ。 See 項6.4.8. 「LOAD DATA INFILE 構文」

  • -F, --flush-logs

    ダンプを開始する前に、MySQL サーバ内のログファイルをフラッシュする。注意: このオプションを --all-databases(または -A)オプションと組み合わせて使用した場合、ログは各データベースのダンプごとにフラッシュされる。

  • -f, --force,

    テーブルダンプ中にSQL エラーが発生しても続行する。

  • -h, --host=..

    指定したホストの MySQL サーバからデータをダンプする。デフォルトのホストは localhost

  • -l, --lock-tables.

    ダンプを開始する前にすべてのテーブルをロックする。テーブルは READ LOCAL でロックされ、MyISAM テーブルの場合は同時挿入が可能になる。

    注意: 複数のデータベースをダンプする場合、--lock-tables は各データベースを個別にロックする。したがって、このオプションを使用した場合、データベース間でのテーブルの論理整合性は保証されない。 異なるデータベースのテーブルは、完全に異なる状態でダンプされる可能性がある。

  • -K, --disable-keys

    /*!40000 ALTER TABLE tb_name DISABLE KEYS */; および /*!40000 ALTER TABLE tb_name ENABLE KEYS */; が出力に含まれる。これにより、インデックスが、すべてのデータが挿入それた後に作成されるため、MySQL 4.0 サーバへのデータのロードが速くなる。

  • -n, --no-create-db

    CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name; が出力に含まれない。--databases オプションまたは --all-databases オプションを指定した場合は、上記の行が追加される。

  • -t, --no-create-info

    テーブル作成情報(CREATE TABLE ステートメント)を書き込まない。

  • -d, --no-data

    テーブルのレコード情報を一切書き込まない。テーブルの構造だけをダンプする場合、非常に便利である。

  • --opt

    --quick --add-drop-table --add-locks --extended-insert --lock-tables と同じ。MySQL サーバに読み込むための最速ダンプを提供する。

  • -pyour_pass, --password[=your_pass]

    サーバ接続時に使用するパスワード。'=your_pass' 部分を指定しなければ、mysqldump によってパスワードのプロンプトが表示される。

  • -P, --port=...

    TCP/IP 接続に使用するポート番号。

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    使用する接続プロトコルを指定する。MySQL 4.1 で導入。

  • -q, --quick

    クエリをバッファせず、stdou に直接ダンプする。これを行うには、mysql_use_result() を使用する。大きなダンプの際に特に便利である。

  • -Q, --quote-names

    テーブル名およびカラム名を ‘`’ 文字で囲む。

  • -r, --result-file=...

    指定したファイルへの直接出力。このオプションは MSDOS で使用する。改行 '\n' が '\n\r'(改行 + 復帰)に変換されるのを防ぐためである。

  • --single-transaction

    このオプションは、サーバからデータをダンプする前に、BEGIN SQL コマンドを発行する。これは、InnoDB テーブルと READ_COMMITTED トランザクション分離レベルで特に役立つ。このモードでは、どのアプリケーションもブロックすることなく、BEGIN が発行されたときのデータベースの整合した状態をダンプできる。

    このオプションを使用する際は、トランザクションテーブルだけが整合状態でダンプされることに注意する。たとえば、このオプションでダンプされた MyISAM テーブルまたは HEAP テーブルは、変更されている可能性がある。

    --single-transaction オプションはバージョン 4.0.2 で追加された。 このオプションは --lock-tables オプションとは相互排他的である。LOCK TABLES は、前のトランザクションをすでにコミットしているためである。

  • -S /path/to/socket, --socket=/path/to/socket

    localhost(デフォルトホスト)との接続に使用するソケットファイル。

  • --tables

    --databases(-B)オプションを上書きする。

  • -T, --tab=path-to-some-directory

    各テーブルに対する SQL CREATE コマンドが含まれる table_name.sql ファイル、および各テーブルに対するデータが含まれる table_name.txt ファイルを作成する。.txt ファイルの形式は、--fields-xxx オプションおよび --lines--xxx オプションに基づく。注意: このオプションは、mysqldumpmysqld デーモンと同じマシンで実行している場合のみ有効。FILE 権限のある MySQL アカウントを使用することが必要。また、mysqld を実行しているログインユーザまたはグループ(通常はユーザ mysql、グループ mysql)に、指定した場所でのファイルの作成および書き込み権限が必要。

  • -u user_name, --user=user_name

    サーバとの接続に使用する MySQL ユーザ名。デフォルト値はユーザの Unix ログイン名。

  • -O name=value, --set-variable=name=value

    変数の値を指定する。指定可能な変数は以下に示す。注意: --set-variable=name=value および -O name=value 構文は、MySQL 4.0 で廃止。代わりに --name=value を使用すること。

  • -v, --verbose

    冗長モード。プログラムの実行内容に関する詳細情報を出力する。

  • -V, --version

    バージョン情報を出力して終了する。

  • -w, --where='where-condition'

    選択したレコードだけをダンプする。注意: 必ず引用符で囲むこと。

    "--where=user='jimf'" "-wuserid>1" "-wuserid<1"
    

  • -X, --xml

    1 つのデータベースを整形式の XML としてダンプ。

  • -x, --first-slave

    すべてのデータベースのすべてのテーブルをロック。

  • --master-data

    --first-slave とほぼ同じだが、CHANGE MASTER TO コマンドを出力する。マスタのこの SQL ダンプを使用してスレーブをセットアップしていた場合、このコマンドにより、後でマスタのバイナリログ内の正しい位置からスレーブを開始させることができる。

  • -O net_buffer_length=#, ここで # < 16M

    複数レコード挿入ステートメントを作成したときに(--extended-insert オプションまたは --opt オプションと同様)、mysqldumpnet_buffer_length までの長さのレコードを作成する。この変数を大きくする場合には、MySQL サーバの max_allowed_packet 変数が net_buffer_length よりも大きいことを確認する。

一般的に、mysqldump はデータベース全体のバックアップに使用されます。 See 項4.5.1. 「データベースのバックアップ」

shell> mysqldump --opt database > backup-file.sql

これを、以下のコマンドで MySQL に戻すことができます。

shell> mysql database < backup-file.sql

または

shell> mysql -e "source /path-to-backup/backup-file.sql" database

データベースの情報を別の MySQL サーバに移動することもできます。

shell> mysqldump --opt database | mysql ---host=remote-host -C database

1 つのコマンドで複数のデータベースをダンプすることができます。

shell> mysqldump --databases database1 [database2 ...] > my_databases.sql

すべてのデータベースを選択するには、以下のようにします。

shell> mysqldump --all-databases > all_databases.sql

4.9.8. mysqlhotcopy(MySQL のデータベースとテーブルのコピー)

mysqlhotcopy は、LOCK TABLESFLUSH TABLES、および cp(または scp)を使用して、すばやくデータベースのバックアップを行う Perl スクリプトです。これは、データベースや単一のテーブルのバックアップを行う最速の方法ですが、データベースディレクトリのある同一マシンだけでしか実行できません。 mysqlhotcopy は、Unix のみ、および MyISAM テーブルと ISAM テーブルでのみ使用できます。

mysqlhotcopy db_name [/path/to/new_directory]

mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory

mysqlhotcopy db_name./regex/

mysqlhotcopy は、以下のオプションをサポートします。

  • -?, --help

    ヘルプ画面を表示して終了する。

  • -u, --user=#

    データベースにログインするユーザ。

  • -p, --password=#

    サーバとの接続に使用するパスワード。

  • -P, --port=#

    ローカルサーバとの接続に使用するポート。

  • -S, --socket=#

    ローカルサーバとの接続に使用するソケット。

  • --allowold

    ターゲットが存在している場合も停止しない(_old を追加して名前変更)。

  • --keepold

    完了時、前の(名前を変更した)ターゲットを削除しない。

  • --noindices

    バックアップを小さくして処理速度を速くするため、コピーに完全インデックスファイルを含めない。 インデックスは後で、myisamchk -rq. で再構成できる。

  • --method=#

    コピー方法(cp または scp)。

  • -q, --quiet

    エラー以外は出力しない。

  • --debug

    デバッグを有効にする。

  • -n, --dryrun

    アクションを実行せずに報告する。

  • --regexp=#

    regexp と一致する名前のデータベースをすべてコピーする。

  • --suffix=#

    コピーされるデータベース名のサフィックス。

  • --checkpoint=#

    指定したデータベーステーブルにチェックポイントエントリを挿入する。

  • --flushlog

    すべてのテーブルがロックされた後、ログをフラッシュする。

  • --tmpdir=#

    テンポラリディレクトリ(/tmp の代わり)。

perldoc mysqlhotcopy を使用して、mysqlhotcopy のさらに詳しいドキュメントを取得できます。

mysqlhotcopy は、オプション設定ファイルから [client] グループおよび [mysqlhotcopy] グループを読み取ります。

mysqlhotcopy を実行するには、バックアップディレクトリへの書き込みアクセス権と、コピーしようとしているテーブルの SELECT 権限、および MySQL RELOAD 権限(FLUSH TABLES を実行するため)が必要です。

4.9.9. mysqlimport(テキストファイルからのデータのインポート)

mysqlimport は、LOAD DATA INFILE SQL ステートメントのコマンドラインインタフェースを提供します。mysqlimport のほとんどのオプションが、LOAD DATA INFILE のオプションに対応しています。 See 項6.4.8. 「LOAD DATA INFILE 構文」

mysqlimport は以下のようにして起動します。

shell> mysqlimport [options] database textfile1 [textfile2 ...]

コマンドラインで指定した各テキストファイルについて、mysqlimport は、ファイル名の拡張子を削除し、その結果を使用して、どのテーブルにファイルの内容をインポートするか決定します。たとえば、patient.txtpatient.text、および patient という名前のファイルは、すべて、patient という名前のテーブルにインポートされます。

mysqlimport は、以下のオプションをサポートします。

  • -c, --columns=...

    このオプションは、カンマ区切りのフィールド名一覧を引数として取る。 フィールド一覧を使用して適切な LOAD DATA INFILE コマンドを作成し、それを MySQL に渡す。 See 項6.4.8. 「LOAD DATA INFILE 構文」

  • -C, --compress

    クライアントとサーバの両方が圧縮をサポートする場合、クライアントとサーバ間の情報をすべて圧縮する。

  • -#, --debug[=option_string]

    プログラムのトレース使用(デバック目的)。

  • -d, --delete

    テキストファイルをインポートする前にテーブルを空にする。

  • --fields-terminated-by=... , --fields-enclosed-by=... , --fields-optionally-enclosed-by=... , --fields-escaped-by=... , --lines-terminated-by=...

    これらのオプションは、LOAD DATA INFILE の対応する節と同じ意味を持つ。 See 項6.4.8. 「LOAD DATA INFILE 構文」

  • -f, --force

    エラーを無視する。たとえば、テキストファイル用のテーブルが存在しない場合でも、残りのファイルの処理を続行する。--force を指定しない場合、テーブルが存在しなければ mysqlimport は終了する。

  • --help

    ヘルプメッセージを表示して終了する。

  • -h host_name, --host=host_name

    指定したホストの MySQL サーバにデータをインポートする。デフォルトのホストは localhost

  • -i, --ignore

    --replace オプションの説明を参照のこと。

  • --ignore-lines=n

    データファイルの最初の n 行を無視する。

  • -l, --lock-tables

    テキストファイルを処理する前に、すべてのテーブルへの書き込みをロックする。これにより、そのサーバ上のすべてのテーブルが同期化される。

  • -L, --local

    クライアントから入力ファイルを読み取る。デフォルトでは、localhost(デフォルトホスト)に接続した場合、テキストファイルはサーバにあると想定される。

  • -pyour_pass, --password[=your_pass]

    サーバとの接続に使用するパスワード。'=your_pass' 部分を指定しなければ、mysqlimport によってパスワードのプロンプトが表示される。

  • -P port_num, --port=port_num

    接続に使用する TCP/IP ポート番号。

  • --protocol=(TCP | SOCKET | PIPE | MEMORY)

    使用する接続プロトコルを指定する。MySQL 4.1 で導入。

  • -r, --replace

    --replace オプションおよび --ignore オプションは、既存レコードの値と重複するユニークキー値を持つ入力レコードの処理を制御する。--replace を指定した場合、新規レコードが同じユニークキー値を持つ既存レコードを上書きする。IGNORE を指定すると、ユニークキー値が既存のレコードの値と重複する入力レコードは無視される。どちらも指定しない場合、重複キー値が検出されるとエラーになり、テキストファイルの残りの部分が無視される。

  • -s, --silent

    サイレントモード。エラー発生時のみ出力する。

  • -S /path/to/socket, --socket=/path/to/socket

    localhost(デフォルトホスト)との接続に使用するソケットファイル。

  • -u user_name, --user=user_name

    サーバとの接続に使用する MySQL ユーザ名。デフォルト値はユーザの Unix ログイン名。

  • -v, --verbose

    冗長モード。プログラムの実行内容に関する詳細を出力する。

  • -V, --version

    バージョン情報を出力して終了する。

以下は、mysqlimport 使用の例です。

$ mysql --version
mysql  Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686)
$ uname -a
Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
$ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
$ ed
a
100     Max Sydow
101     Count Dracula
.
w imptest.txt
32
q
$ od -c imptest.txt
0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
0000020   1  \t   C   o   u   n   t       D   r   a   c   u   l   a  \n
0000040
$ mysqlimport --local test imptest.txt
test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
$ mysql -e 'SELECT * FROM imptest' test
+------+---------------+
| id   | n             |
+------+---------------+
|  100 | Max Sydow     |
|  101 | Count Dracula |
+------+---------------+

4.9.10. mysqlshow(データベース、テーブル、およびカラムの表示)

mysqlshow を使用すると、既存のデータベース、テーブル、およびカラムをすばやく表示できます。

mysql プログラムでは、SHOW コマンドで同じ情報を表示できます。 See 項4.6.8. 「SHOW 構文」

mysqlshow は以下のようにして起動します。

shell> mysqlshow [OPTIONS] [database [table [column]]]
  • データベースを指定しなければ、一致するすべてのデータベースが表示される。

  • テーブルを指定しなければ、データベース内で一致するすべてのデータベースが表示される。

  • カラムを指定しなければ、テーブル内で一致するカラムおよびカラム型がすべて表示される。

注意: 新しい MySQL バージョンでは、ユーザが権限を持っているデータベース、テーブル、カラムだけが表示されます。

最後の引数にシェルまたは SQL ワイルドカード(*?%、または _)が含まれる場合、ワイルドカードに一致するものだけが表示されます。データベース名にアンダースコアが含まれる場合、テーブルおよびカラムを正しく取得するために、これらをバックラッシュでエスケープ処理してください(Unix シェルによっては 2 つ必要です)。'*' は SQL '%' ワイルドカードに、'?' は SQL '_' ワイルドカードに変換されます。このことは、_ を含むあるテーブルのカラムを表示しようとしたときに、混乱が生じます。この場合、mysqlshow は、このパターンに一致するテーブル名を表示します。 これは、コマンドラインの最後に % を別の引数として追加することで、簡単に解決できます。

4.9.11. mysql_config(クライアントをコンパイルするためのコンパイルオプションの取得)

mysql_config は、MySQL クライアントをコンパイルし、そのクライアントを MySQL に接続する方法についての役立つ情報を提供します。

mysql_config は、以下のオプションをサポートします。

  • --cflags

    インクルードファイルを見つけるためのコンパイラフラグ、および重要なコンパイルフラグとコンバイラ定義。これらは libmysqlclient ライブラリをコンパイルするときに使用される。

  • --include

    MySQL インクルードファイルを見つけるためのコンパイルオプション(通常はこの代わりに --cflags を使用する)。

  • --libs

    MySQL クライアントライブラリにリンクする必要のあるライブラリとオプション。

  • --libs_r

    スレッドセーフ MySQL クライアントライブラリにリンクする必要のあるライブラリとオプション。

  • --socket

    デフォルトのソケット名。MySQL をコンフィギャするときに定義される。

  • --port

    デフォルトのポート番号。MySQL をコンフィギャするときに定義される。

  • --version

    MySQL ディストリビューションのバージョン番号とバージョン。

  • --libmysqld-libs or --embedded

    MySQL 組み込みサーバにリンクする必要のあるライブラリとオプション。

オプションを指定せずに mysql_config を実行すると、サポートするすべてのオプションとすべてのオプション値が出力されます。

shell> mysql_config
Usage: /usr/local/mysql/bin/mysql_config [OPTIONS]
Options:
        --cflags         [-I/usr/local/mysql/include/mysql -mcpu=pentiumpro]
        --include        [-I/usr/local/mysql/include/mysql]
        --libs           [-L/usr/local/mysql/lib/mysql -lmysqlclient -lz -lcrypt -lnsl -lm -L/usr/lib -lssl -lcrypto]
        --libs_r         [-L/usr/local/mysql/lib/mysql -lmysqlclient_r -lpthread -lz -lcrypt -lnsl -lm -lpthread]
        --socket         [/tmp/mysql.sock]
        --port           [3306]
        --version        [4.0.16]
        --libmysqld-libs [-L/usr/local/mysql/lib/mysql -lmysqld -lpthread -lz -lcrypt -lnsl -lm -lpthread -lrt]

このスクリプトを使用して以下のように指定することで、MySQL クライアントをコンパイルできます。

CFG=/usr/local/mysql/bin/mysql_config
sh -c "gcc -o progname `$CFG --cflags` progname.c `$CFG --libs`"

4.9.12. perror(エラーコードの説明)

MySQL は、ほとんどのシステムエラーに対して、内部のテキストメッセージに加え、message ... (errno: #) または message ... (Errcode: #) のいずれかの形式のシステムエラーコードを出力します。

エラーコードの意味を調べるには、システムのドキュメントを参照するか、perror ユーティリティを使用します。

perror は、システムエラーコード、または MyISAM/ISAM ストレージエンジン(テーブルハンドラ)エラーコードの説明を出力します。

perror は以下のようにして起動します。

shell> perror [OPTIONS] [ERRORCODE [ERRORCODE...]]

Example:

shell> perror 13 64
Error code  13:  Permission denied
Error code  64:  Machine is not on the network

注意: エラーメッセージは、ほとんどがシステム依存です。

4.9.13. テキストファイルから SQL コマンドを実行する方法

mysql クライアントは、通常、以下のように対話的に使用します。

shell> mysql database

しかし、SQL コマンドをファイルに入力して、そのファイルから mysql に読み取らせることも可能です。これを行うには、実行するコマンドを含むテキストファイル text_file を作成します。 そして、以下のように mysql を起動します。

shell> mysql database < text_file

テキストファイルを USE db_name ステートメントで開始することもできます。この場合、コマンドラインでデータベース名を指定する必要はありません。

shell> mysql < text_file

すでに mysql を実行中の場合、source コマンドを使用して SQL スクリプトを実行できます。

mysql> source filename;

バッチモードの詳細については、項3.5. 「バッチモードでの mysql の使用」 を参照してください。

4.10. MySQL ログファイル

MySQL にはいくつかの種類のログファイルがあり、mysqld 内で何が発生しているか調べることができます。

ログファイル説明
エラーログmysqld の起動、実行、および停止で発生した問題。
isam ログISAM テーブルへの変更がすべて記録。isam コードのデバッグのみに使用。
一般クエリログ接続の情報と実行されたクエリ。
更新ログ廃止。データを変更したすべてのステートメントを保存。
バイナリログ何かを変更したすべてのステートメントを保存。レプリケーションにも使用。
スローログlong_query_time 秒より時間のかかったクエリ、またはインデックスを使用しなかったクエリをすべて保存。

ログはすべて、mysqld データディレクトリにあります。mysqld でログファイルを再度開く(あるいは新しいログに切り替える)には、FLUSH LOGS を実行します。 See 項4.6.4. 「FLUSH 構文」

4.10.1. エラーログ

エラーログファイルには、mysqld の起動時刻と停止時刻、および実行中に発生したエラーに関する情報が記録されます。

mysqld が異常終了して mysqld_safemysqld を再起動する必要がある場合、mysqld_safe はこのファイルに restarted mysqld 行を書き込みます。自動チェックまたは自動修復が必要なテーブルを mysqld が見つけた場合、警告も記録されます。

一部のオペレーティングシステムでは、mysqld が異常終了した箇所のスタックトレースがエラーログに記録されます。これを使用すると、mysqld がどの時点で異常終了したかわかります。 See 項E.1.4. 「スタックトレースの使用」

MySQL 4.0.10 以降、mysqld がエラーログファイルを保存する場所を --log-error[=filename] オプションで指定できるようになっています。ファイル名を指定しなければ、mysqld は Unix では mysql-data-dir/'hostname'.err を、Windows では \mysql\data\mysql.err を使用します。 flush logs を実行すると、古いファイルには --old のプリフィックスが付き、mysqld が空の新規ログファイルを作成します。

旧 MySQL バージョンでは、エラーログ処理は mysqld_safe によって行われ、エラーファイルは 'hostname'.err にリダイレクトされます。このファイル名は、--err-log=filename オプションで変更できます。

--log-error を指定しない場合、または --console オプションを使用した場合には、エラーは stderr(端末)に書き込まれます。

Windows では、--console を指定しなければ、出力は常に .err ファイルに書き込まれます。

4.10.2. 一般クエリログ

mysqld 内で何が発生しているか確認したい場合には、--log[=file] オプションを使用して mysqld を起動します。これにより、すべての接続とクエリがログファイル(デフォルトは 'hostname'.log)に記録されます。このログは、クライアント側にエラーの原因があると考えられ、mysqld に対してクライアントが何を送信したのか調べるときに非常に役立ちます。

古いバージョン(MySQL 3.23.4 から 3.23.8)の mysql.server スクリプトは、safe_mysqld に、一般クエリログを有効化する --log オプションを渡します。実稼動環境で MySQL の起動時のパフォーマンスを向上させる必要がある場合には、--log オプションを mysql.server から削除するか、--log-bin に変更します。 See 項4.10.4. 「バイナリログ」

このログのエントリは、mysqld がクエリを受けた時点で書き込まれます。これは、ステートメントが実行された順序とは異なる場合があります。また、更新ログおよびバイナリログとも対比的です。更新ログおよびバイナリログは、クエリが実行された後、ロックが解除される前に書き込まれます。

4.10.3. 更新ログ

注意: 更新ログは廃止され、代わりにバイナリログが使用されます。See 項4.10.4. 「バイナリログ」。 バイナリログは、以前の更新ログの機能をすべて備え、加えて別の機能も追加されています。MySQL 5.0 で更新ログはなくなります

mysqld--log-update[=file_name] オプションで起動すると、データを更新するすべての SQL コマンドがログファイルに記録されます。ファイル名を指定しなければ、ホストマシンの名前がデフォルト名になります。ファイル名を指定し、パスを指定しない場合、ファイルはデータディレクトリに作成されます。file_name に拡張子がない場合、mysqldfile_name.### の形式でログファイル名を生成します。ここで ### は、mysqladmin refreshmysqladmin flush-logs、および FLUSH LOGS ステートメントが実行されるたびに、およびサーバが再起動するたびにインクリメントされる番号です。

注意: 上記スキームが有効であるために、更新ログが使用するディレクトリ内では、更新ログ + 何らかの拡張子など、番号と誤認されるようなファイル名のファイルを作成してはいけません。

--log オプションまたは -l オプションを使用した場合、mysqldhostname.log という名前の一般ログファイルを作成します。再起動やリフレッシュを行っても新規ログファイルは生成されません(いったん閉じて、再度開くだけです)。この場合、以下のようにして(Unix 上)ログファイルをコピーすることができます。

mv hostname.log hostname-old.log
mysqladmin flush-logs
cp hostname-old.log to-backup-directory
rm hostname-old.log

更新ログは、データを実際に更新したステートメントだけを記録します。UPDATE または DELETEWHERE 指定でレコードが見つからなかった場合、そのステートメントはログに書き込まれません。カラムの値を、すでにある同じ値で更新した UPDATE ステートメントもスキップされます。

更新ログの書き込みは、クエリが完了した直後でロックの解除前に、またはコミットの前に行われます。このため、ログは実行順序どおりに書き込まれます。

更新ログファイルからデータベースを更新するには、以下を実行します。ここでは、更新ログ名の形式を file_name.### と仮定しています。

shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql

ls は、すべてのログファイルを正しい順序で取得するために使用します。

これは、クラッシュ後にバックアップファイルの状態にまで戻す、あるいはバックアップ後からクラッシュまでの間の更新を繰り返す場合などに役立ちます。

4.10.4. バイナリログ

バイナリログは、以前の更新ログの代わりになるものです。更新ログは MySQL 5.0 でなくなります。バイナリログには、更新ログで利用可能だった情報がすべて、より効率的かつトランザクションセーフな方法で含まれます。

バイナリログは以前の更新ログと同様、データを実際に更新するステートメントだけを記録します。UPDATE または DELETEWHERE 指定でレコードが見つからなかった場合、そのステートメントはログに書き込まれません。カラムの値を、すでにある同じ値で更新した UPDATE ステートメントもスキップされます。

バイナリログには、バックアップ後の更新がすべて記録されます。バイナリログの主な目的は、リストア時に、データベースに対して可能な限りバックアップ後の更新を実行できるようにすることです。

バイナリログは、マスタからスレーブにレプリケーションを行うときにも使用します。 See 項4.11. 「MySQL のレプリケーション」

バイナリログには、データベースを更新した各クエリにかかった時間の情報も含まれます。データを変更しなかったクエリは含まれません。問題のあるクエリを見つけるなどの目的ですべてのクエリを記録したい場合には、一般クエリログを使用してください。 See 項4.10.2. 「一般クエリログ」

mysqld--log-bin[=file_name] オプションで起動すると、データを更新したすべての SQL コマンドがログファイルに記録されます。ファイル名を指定しなければ、ホストマシンの名前に -bin を付けたものがデフォルト名になります。ファイル名を指定し、パスを指定していない場合には、ファイルはデータディレクトリに作成されます。

--log-bin=filename.extension で拡張子を指定した場合、拡張子は削除されます。

mysqld は、バイナリログファイル名に数字の拡張子を追加します。この番号は、mysqladmin refreshmysqladmin flush-logs、および FLUSH LOGS ステートメントが実行されるたびに、またはサーバが再起動するたびにインクリメントされます。バイナリログのサイズが max_binlog_size に達すると、新しいバイナリログが自動的に作成されます。注意: トランザクションを使用している場合、トランザクションは 1 つのまとまりでバイナリログに書き込まれるため、複数のバイナリログに分割されることはありません。したがって、大きなトランザクションがある場合、バイナリログが max_binlog_size より大きくなる可能性があります。

すべてのバイナリログファイルを削除するには、RESET MASTER コマンド(see 項4.6.5. 「RESET 構文」)を使用します。一部のファイルを削除するには、PURGE MASTER LOGS(see 項4.11.7. 「マスタサーバを制御する SQL ステートメント」)を使用します。

mysqld で以下のオプションを使用し、何をバイナリログに記録するか制御できます(表の後の説明を必ず読んでください)。

オプション説明
binlog-do-db=database_nameカレントデータベース(USE によって選択されたデータベース)が 'database_name' の場合、更新をバイナリログに記録するようにマスタに指示する。それ以外の明示的に指定されていないデータベースはすべて無視する。注意: カレントデータベース内でのみ更新を行うことが確実な場合に、このオプションを使用すること(例: binlog-do-db=some_database)。 予想しづらい動作例: サーバを binlog-do-db=sales で起動し、USE prices; UPDATE sales.january SET amount=amount+1000; を実行した場合、このクエリはバイナリログには書き込まれない。
binlog-ignore-db=database_nameカレントデータベース(USE によって選択されたデータベース)が 'database_name' の場合、更新をバイナリログに記録しないようにマスタに指示する。注意: カレントデータベース内でのみ更新を行うことが確実な場合に、このオプションを使用すること(例: binlog-ignore-db=some_database)。 予想しづらい動作例: サーバを binlog-ignore-db=sales で起動し、USE prices; UPDATE sales.january SET amount=amount+1000; を実行した場合、このクエリはバイナリログに書き込まれる。

クエリをバイナリログに書き込むかどうかの評価は、以下の順序で行われます。

  1. binlog-do-db ルールまたは binlog-ignore-db ルールがあるか。

    • No: クエリをバイナリログに書き込んで終了する。

    • Yes: 次のステップに移る。

  2. ルール(binlog-do-db または binlog-ignore-db、あるいはその両方)が存在する。カレントデータベースがあるか(USE が選択しているデータベースがあるか)。

    • No: クエリを書き込まないで終了する。

    • Yes: 次のステップに移る。

  3. カレントデータベースがある。binlog-do-db ルールはあるか。

    • Yes: カレントデータベースが binlog-do-db ルールのいずれかに一致しているか。

      • Yes: クエリを書き込んで終了する。

      • No: クエリを書き込まないで終了する。

    • No: 次のステップに移る。

  4. binlog-ignore-db ルールが存在する。 カレントデータベースが binlog-ignore-db ルールのいずれかに一致しているか。

    • Yes: クエリを書き込まないで終了する。

    • No: クエリを書き込んで終了する。

したがって、たとえば binlog-do-db=sales だけで実行中のスレーブは、カレントデータベースが sales ではないクエリを一切バイナリログに書き込みません(つまり、binlog-do-db は ``他のデータベースを無視する'' ということにもなります)。

どのバイナリログファイルが使用されたかわかるように、mysqld はバイナリログインデックスファイルも作成します。このファイルに、使用されたバイナリログファイルすべての名前が含まれます。デフォルトでは、このファイルの名前はバイナリログファイル名に拡張子 '.index' を付けたものとなります。 バイナリログインデックスファイルの名前を変更するには、--log-bin-index=[filename] オプションを使用します。 mysqld の実行中は、このファイルを手動で編集しないでください。mysqld が混乱する原因となります。

レプリケーションを使用している場合、スレーブが必要としている間は、古いバイナリログファイルを削除しないでください。 たとえば、mysqladmin flush-logs を毎日実行する場合、3 日たったログをすべて削除するようにします。これらのログは手動で削除することもできますが、バイナリログインデックスファイルも安全に更新できる PURGE MASTER LOGS(see 項4.11.7. 「マスタサーバを制御する SQL ステートメント」)を使用して削除することを推奨します。このコマンドは、MySQL 4.1 から日付引数を指定できるようになっています。

SUPER 権限での接続では、SET SQL_LOG_BIN=0 を使用して、クエリのバイナリログを無効にできます。 See 項4.11.7. 「マスタサーバを制御する SQL ステートメント」

バイナリログファイルを調べるには、mysqlbinlog ユーティリティを使用します。 たとえば、以下のようにバイナリログから MySQL サーバを更新することができます。

shell> mysqlbinlog log-file | mysql -h server_name

mysqlbinlog ユーティリティおよびその使用法に関する詳細については、項4.9.5. 「mysqlbinlog(バイナリログからクエリを実行する)」 を参照してください。

BEGIN [WORK] または SET AUTOCOMMIT=0 を使用している場合は、以前の更新ログではなく MySQL バイナリログをバックアップ用に使用してください。更新ログは MySQL 5.0 でなくなります。

バイナリログの書き込みは、クエリが完了した直後でロックの解除前に、またはコミットの前に行われます。このため、ログは実行順序どおりに書き込まれます。

非トランザクションテーブルの更新は実行直後にバイナリログに保存されます。BDB テーブルや InnoDB テーブルなどのトランザクションテーブルでは、テーブルを変更するすべての更新(UPDATEDELETE、または INSERT)は、COMMIT コマンドがサーバに送信されるまでキャッシュされます。mysqld は、COMMIT が実行される前にトランザクション全体をバイナリログに書き込みます。 すべてのスレッドが、最初に、クエリをバッファする binlog_cache_size のバッファを割り当てます。クエリがこれより大きい場合、スレッドはテンポラリファイルを開いてトランザクションを保存します。スレッドが終了するとテンポラリファイルは削除されます。

max_binlog_cache_size(デフォルトは 4G)を使用して、複数クエリトランザクションのキャッシュに使用するトータルサイズを制限できます。トランザクションがこれより大きい場合、エラーとなってロールバックします。

更新ログまたはバイナリログを使用している場合に、CREATE ... SELECT または INSERT ... SELECT を使用すると、同時挿入が通常の挿入に変換されます。 これは、バックアップにログを適用したときに、テーブルの正確なコピーを作成するための措置です。

4.10.5. スロークエリログ

mysqld--log-slow-queries[=file_name] オプションで起動すると、実行に long_query_time 秒より長くかかった SQL コマンドがすべてログファイルに書き込まれます。最初のテーブルロックにかかった時間は実行時間に含まれません。

スロークエリログは、クエリ実行後、すべてのロックが解除された後に書き込まれます。これは、ステートメントが実行された順序とは異なる場合があります。

ファイル名を指定しなければ、ホストマシンの名前に -slow.log を付けたものがデフォルト名になります。ファイル名を指定し、パスを指定しない場合、ファイルはデータディレクトリに作成されます。

スロークエリログは、実行に時間がかかり、最適化の対象となるクエリを見つけるために使用できます。大きなログでは、これは難しい作業になります。mysqldumpslow コマンドを使用すれば、ログのクエリサマリを取得できます。

--log-long-format を使用すれば、インデックスを使用しなかったクエリも出力されます。 See 項4.1.1. 「mysqld コマンドラインオプション」

4.10.6. ログファイルの保守

MySQL サーバではいくつかの種類のログファイルが生成され、実行内容を簡単に確認することができます。See 項4.10. 「MySQL ログファイル」。 ただし、ログがディスク領域を占有しすぎないようにこれらのファイルを定期的にクリーンアップする必要があります。

MySQL をログファイルとともに使用する場合、定期的に古いファイルを削除またはバックアップし、新しいファイルでログを開始するようにしてください。 See 項4.5.1. 「データベースのバックアップ」

Linux(Red Hat)インストールでは、mysql-log-rotate スクリプトを使用して、古いログファイルの処理を自動的に行うことができます。RPM ディストリビューションから MySQL をインストールしていれば、このスクリプトは自動的にインストールされているはずです。注意: レプリケーション用にバイナリログを使用している場合、このスクリプトの使用には注意が必要です。

他のシステムでは、ログファイルを処理するための短いスクリプトを自分でインストールする必要があります。このスクリプトは、cron から開始します。

新しいログファイルの使用を MySQL に強制するには、mysqladmin flush-logs を使用するか、SQL コマンド FLUSH LOGS を使用します。 MySQL バージョン 3.21 を使用している場合、mysqladmin refresh を使用する必要があります。

上記コマンドは以下を実行します。

  • 一般ログ(--log)またはスロークエリログ(--log-slow-queries)が使用されている場合、ログファイル(デフォルトでは mysql.log`hostname`-slow.log)を閉じて再び開く。

  • 更新ログ(--log-update)が使用されている場合、更新ログを閉じて、1 つ番号の大きい新規ログファイルを開く。

更新ログだけを使用している場合は、ログをフラッシュして、古い更新ログファイルをバックアップに移動するだけで済みます。 通常のログを使用している場合は、以下のように行います。

shell> cd mysql-data-directory
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs

次に、バックアップを作成し、mysql.old を削除します。

4.11. MySQL のレプリケーション

1 つの MySQL サーバにあるデータベースを別のサーバに複製できるレプリケーション機能は、MySQL バージョン 3.23.15 で導入されました。このセクションでは、MySQL のさまざまなレプリケーション機能について説明します。このセクションは、レプリケーションで利用可能なオプションのリファレンスとしても役立ちます。まずレプリケーションについて説明し、その実装方法を解説します。後半では、FAQ、および発生し得る問題の説明とその解決方法を記述します。

当社の Web サイト http://www.mysql.com/ を定期的にアクセスし、このセクションの最新版に目を通しておくことを推奨します。レプリケーションは常に改良されており、頻繁にマニュアルを最新の情報で更新しています。

4.11.1. はじめに

バージョン 3.23.15 から、MySQL は一方向レプリケーションを内部的にサポートしています。1 つのサーバがマスタとして機能し、別の 1 つまたは複数のサーバがスレーブとなります。マスタサーバが更新のバイナリログを保持します(see 項4.10.4. 「バイナリログ」)。 また、バイナリログのインデックスファイルも保持し、ログのローテーションを記録します。各スレーブは接続時、前回レプリケーションに成功にしている更新の位置をマスタに通知し、それ以降の更新を実行し、その後ブロックして、マスタからの新規更新の通知を待ちます。

レプリケーションサーバをチェーン状に構成すれば、スレーブは他のサーバに対するマスタとしても機能できます。

注意: レプリケーションを使用する場合、テーブルの更新はすべてマスタサーバで実行する必要があります。そうでない場合、ユーザがマスタのテーブルで行った更新とスレーブのテーブルで行った更新との間で競合が発生します。

一方向レプリケーションは、堅牢性、速度、およびシステム管理の面で優れています。

  • マスタ/スレーブセットアップにより堅牢性が向上する。 マスタで問題があった場合、バックアップとしてスレーブに切り替えることができる。

  • クライアントクエリの負荷をマスタとスレーブに分散することによって速度を向上でき、その結果クライアントの応答時間が短くなる。 SELECT クエリをスレーブに送信することにより、マスタのクエリ処理負荷を軽減できる。データを変更するクエリは、マスタとスレーブの整合性を保つため、マスタに送信する必要がある。負荷分散戦略は、更新以外のクエリが多い場合のみ効果がある。通常、この場合が多い。

  • その他にも、レプリケーションを使用すると、マスタではなくスレーブでバックアップを行えるという利点がある。 See 項4.5.1. 「データベースのバックアップ」

4.11.2. レプリケーション実装の概要

MySQL レプリケーションは、マスタサーバが、データベースに対するすべての変更(更新、削除など)をバイナリログ(see 項4.10.4. 「バイナリログ」)に記録することを基本としています。各スレーブサーバは、マスタがそのバイナリログに記録したクエリをマスタから受け取り、データのコピー上で同じクエリを実行できます。

バイナリログは、単に、ある特定の時刻(バイナリログを有効にした瞬間)からの記録であることを理解することが重要です。スレーブにはすべて、マスタでバイナリログを有効にした瞬間のマスタデータベースのコピーが必要です。バイナリログが開始されたときのマスタ上のデータとは違うデータでスレーブを開始すると、そのスレーブは失敗します。

以下の表は、MySQL の異なるバージョン間でのマスタ/スレーブレプリケーションの互換性を示したものです。

??マスタマスタマスタマスタ
??3.23.33 以降4.0.04.0.14.0.3 以降
スレーブ3.23.33 以降yesnonono
スレーブ4.0.0noyesnono
スレーブ4.0.1yesnoyesno
スレーブ4.0.3 以降yesnonoyes

レプリケーション機能は常により強力な機能へと変化しているので、最新の MySQL バージョンを常に使用することを推奨します。バージョン 4.0 については、マスタとスレーブの両方に同じバージョンの使用を推奨します。例外として、MySQL 4.0.2 はレプリケーション目的には適しません。

注意: マスタを MySQL 3.23 から MySQL 4.0(または 4.1)にアップグレードする場合、古い 3.23 バイナリログを使用してレプリケーションを再開しないでください。4.0 スレーブが混乱する原因となります。アップグレードするマスタが 3.23 で、スレーブが 4.0 の場合は以下の方法で安全にアップグレードできます。

  1. マスタでの更新をすべてブロックする(FLUSH TABLES WITH READ LOCK)。

  2. すべてのスレーブがマスタの更新に追いつくのを待つ(マスタで SHOW MASTER STATUS を使用し、スレーブで SELECT MASTER_POS_WAIT() を使用する)。そして、スレーブで STOP SLAVE を実行する。

  3. マスタの MySQL をシャットダウンし、マスタを MySQL 4.0 にアップグレードする。

  4. マスタで MySQL を再起動する。マスタの新しく作成しされたバイナリログの名前 <name> を記録する。ファイルの名前を取得するには、マスタで SHOW MASTER STATUS を実行する。各スレーブに以下のコマンドを実行する。

    mysql> CHANGE MASTER TO MASTER_LOG_FILE='<name>', MASTER_LOG_POS=4;
    mysql> START SLAVE;
    

スレーブも 3.23 から 4.0 にアップグレードする必要がある場合は、最初にスレーブをアップグレードしてください。それぞれをシャットダウンし、アップグレードしてから再起動します。 それから、上記の手順でマスタをアップグレードします。

4.0.0 以降、LOAD DATA FROM MASTER を使用してスレーブをセットアップできるようになっています。現在のところ、LOAD DATA FROM MASTER が動作するのは、マスタのテーブルがすべて MyISAM 型の場合だけです。また、このステートメントではグローバルに READ ロックが掛かるため、テーブルをマスタから転送している間は書き込みできなくなります。MySQL 5.0 でロックフリーのホットテーブルバックアップが導入されると、グローバルの READ ロックは必要なくなります。

これらの制限のため、現時点では、マスタのデータセットが比較的小さい場合、またはマスタの READ ロックが長くなってもかまわない場合だけ、LOAD DATA FROM MASTER を使用してください。LOAD DATA FROM MASTER の実際の速度はシステムによって異なりますが、だいたいの目安としては、データファイル 1 メガバイトあたり 1 秒と考えてください。これは、マスタとスレーブが同等の 700 MHz Pentium で、100 MBit/秒 ネットワークの接続を想定した基準です。あくまでおおよその目安です。

いったんスレーブを適切に設定して実行すれば、スレーブはマスタに接続して更新処理を待ちます。マスタとの接続が切れた場合、再接続できるまで定期的に接続を再試行し、接続できたら更新のリッスンを再開します。再試行の間隔は、--master-connect-retry オプションで制御します。デフォルトは 60 秒です。

各スレーブは、終了時点を記録しています。マスタサーバ側では、いくつのスレーブが存在し、どれがいつ更新されたかを記録していません。

4.11.3. レプリケーションの実装の詳細

レプリケーションには 3 つのスレッドが関連しています。1 つがマスタ、2 つがスレーブのスレッドです。 START SLAVE が発行されると、I/O スレッドがスレーブに作成されます。これはマスタに接続し、マスタのバイナリログに記録されているクエリの送信を要求します。 次に、これらのバイナリログを送信するためのスレッドがマスタに作成されます。このスレッドは、マスタの SHOW PROCESSLIST 出力で Binlog Dump として識別できます。 I/O スレッドは、マスタ Binlog Dump スレッドが送信したものを読み取り、スレーブ内のリレーログと呼ばれるデータディレクトリのローカルファイルにコピーします。 最後に、SQL スレッドがスレーブに作成されます。これはリレーログを読み取り、それに含まれるクエリを実行します。

注意: マスタには、接続しているスレーブサーバ 1 つにつき、1 つのスレッドがあります。

SHOW PROCESSLIST を使用すれば、レプリケーションに関するマスタおよびスレーブでの処理内容を確認できます。

以下の例で、3 つのスレッドが SHOW PROCESSLIST でどのように表示されるか示します。出力形式は、MySQL バージョン 4.0.15 の SHOW PROCESSLIST のものです。旧バージョンに比べて State カラムの内容が充実しています。

マスタサーバでは、以下のような出力になります。

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to be updated
   Info: NULL

スレーブサーバでは、以下のような出力になります。

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O thread to update it
   Info: NULL

ここでは、スレッド Id 2 がマスタです。スレッド Id 10 はスレーブの I/O スレッドです。スレッド Id 11 はスレーブの SQL スレッドです。Time カラムの値により、スレーブがマスタと比較してどれくらい遅れているかわかります(see 項4.11.9. 「レプリケーション FAQ」)。

以下の一覧は、マスタの Binlog Dump スレッドの State カラムに表示される一般的な状態をまとめたものです。このスレッドがマスタサーバになければ、レプリケーションは実行されていないということです。

  • Sending binlog event to slave

    バイナリログはイベントで構成される。通常、イベントとは、クエリとその他の情報が組み合わさったものである。このステータスは、スレッドが、バイナリからイベントを読み取り、それをスレーブに送信中ということである。

  • Finished reading one binlog; switching to next binlog

    スレッドは 1 つのバイナリログファイルの読み取りを完了し、スレーブに送信するために次のファイルを開いている途中である。

  • Has sent all binlog to slave; waiting for binlog to be updated

    スレッドはすべてのバイナリログファイルの読み取りを完了し、アイドル状態である。スレッドは、マスタで実行される新しい更新クエリの結果として、バイナリログに新しいイベントが書き込まれるのを待っている。

  • Waiting to finalize termination

    スレッド停止中に瞬間的に発生する状態。

以下は、スレーブサーバの I/O スレッドの State カラムに表示される一般的な状態です。MySQL 4.1.1 以降、この状態は SHOW SLAVE STATUS 出力の Slave_IO_State カラムにも表示されます。そのため、SHOW SLAVE STATUS を使用するだけで現状を把握できます。

  • Connecting to master

    スレッドは、マスタへの接続を試行中である。

  • Checking master version

    マスタへの接続が確立した直後、瞬間的に発生する状態。

  • Registering slave on master

    マスタへの接続が確立した直後、瞬間的に発生する状態。

  • Requesting binlog dump

    マスタへの接続が確立した直後、瞬間的に発生する状態。スレッドは、バイナリログの内容をマスタに要求する。バイナリログファイルの名前と場所が最初にマスタに送信される。

  • Waiting to reconnect after a failed binlog dump request

    バイナリログダンプ要求が失敗した(接続切断によって)場合、スレッドはスリープ中この状態になる。スレッドは再試行する前に、master-connect-retry 秒間スリープ状態となる。

  • Reconnecting after a failed binlog dump request

    次に、スレッドはマスタへの再接続を試行する。

  • Waiting for master to send event

    スレッドは接続を完了し、バイナリログイベントの到着を待っている。マスタがアイドル状態であれば、この状態が長く続く場合がある。待機が slave_read_timeout 秒間続くと、タイムアウトが発生する。その時点でスレッドは接続が切断したと見なし、再接続を試行する。

  • Queueing master event to the relay log

    スレッドがイベントの読み取りを完了し、SQL スレッドがそのイベントを処理できるようにリレーログにコピー中である。

  • Waiting to reconnect after a failed master event read

    読み取り中にエラーが発生した(接続切断のため)。スレッドは接続を再試行する前に、master-connect-retry 秒間スリープ状態になる。

  • Reconnecting after a failed master event read

    次に、スレッドは再接続を試行する。接続が再度確立すると、状態は Waiting for master to send event になる。

  • Waiting for the slave SQL thread to free enough relay log space

    relay_log_space_limit の値が 0 以外に設定されているが、リレーログが大きくなりすぎて、その合計サイズがこの値を超えた。SQL スレッドがリレーログの内容を処理してリレーログファイルを削除し、領域に余裕ができるのを I/O スレッドは待っている。

  • Waiting for slave mutex on exit

    スレッド停止中に瞬間的に発生する状態。

以下は、スレーブサーバの SQL スレッドの State カラムで表示される一般的な状態です。

  • Reading event from the relay log

    スレッドは、イベントを処理するため、リレーログからイベントを読み取っている。

  • Has read all relay log; waiting for the slave I/O thread to update it

    スレッドは、リレーログファイルのイベントをすべて処理し、I/O スレッドがリレーログに新しいイベントを書き込むのを待っている。

  • Waiting for slave mutex on exit

    スレッド停止中に瞬間的に発生する状態。

I/O スレッドの State カラムには、クエリ文字列が表示される場合もあります。これは、スレッドがリレーログからイベントを読み取り、クエリを抽出して、そのクエリを実行中であることを示します。

MySQL 4.0.2 より前は、スレーブの I/O スレッドと SQL スレッドは 1 つのスレッドにまとめられており、リレーログファイルは使用されていませんでした。 2 つのスレッドを使用する利点は、クエリの読み取りとクエリの実行を 2 つの独立したタスクに分けられることです。そのため、クエリ実行が遅くてもクエリ読み取りが遅くなることはありません。たとえば、スレーブサーバがしばらくの間実行していなかった場合でも、スレーブが起動すると、I/O スレッドがバイナリログのすべての内容をすばやく読み出します。SQL スレッドがかなり遅れていて、追いつくのに数時間かかるとしても影響を受けません。SQL スレッドが読み出したクエリをすべて実行する前にスレーブが停止しても、少なくとも I/O スレッドがクエリの読み出しを完了しているので、クエリのコピーはスレーブのリレーログにローカルで安全に保存されており、次回スレーブが起動したときに実行することができます。このため、マスタからはバイナリログを削除できます。スレーブがその内容を読み出するのを待つ必要はないからです。

デフォルトでは、リレーログの名前は host_name-relay-bin.nnn 形式になります。ここで、host_name はスレーブサーバのホスト名、nnn はシーケンス番号です。 連続したリレーログファイルでは、シーケンス番号は 001 から始まる連続した番号になります。 スレーブは、現在使用中のリレーログの記録をインデックスファイルに保持します。デフォルトのリレーログインデックスファイル名は host_name-relay-bin.index です。 デフォルトでは、これらのファイルはスレーブのデータディレクトリに作成されます。デフォルトのファイル名は、--relay-log および --relay-log-index の各サーバオプションで上書きできます。

リレーログはバイナリログと同じ形式なので、mysqlbinlog で読み取ることができます。リレーログは必要がなくなると(そのイベントがすべて実行されたら)、SQL スレッドによって自動的に削除されます。SQL スレッドが自動的に行うため、リレーログを削除するコマンドはありません。ただし、MySQL 4.0.14 からは FLUSH LOGS がリレーログをローテートするため、SQL が削除するタイミングに影響します。

新しいリレーログは、以下の条件で作成されます。

  • スレーブサーバの起動後、最初に I/O スレッドが開始されたとき(MySQL 5.0 では、最初の I/O スレッド開始時だけでなく、I/O スレッドが開始されるたびに新規リレーログが作成される)。

  • FLUSH LOGS ステートメントの実行時(4.0.14 以降)。

  • 現在のリレーログファイルのサイズが大きくなりすぎたとき。``大きすぎる'' かどうかは以下の変数で決定される。

    • max_relay_log_sizemax_relay_log_size > 0 の場合)

    • max_binlog_sizemax_relay_log_size = 0 または MySQL バージョンが 4.0.14 よりも古い場合)

スレーブレプリケーションサーバは、2 つの小さなファイルをデータディレクトリに作成します。これらのファイルの名前はデフォルトで、master.info および relay-log.info になります。これらのファイルには、SHOW SLAVE STATUS ステートメント(このコマンドの説明については、see 項4.11.8. 「スレーブサーバを制御する SQL ステートメント」)の出力に含まれるような情報が保存されます。ディスクファイルとして、スレーブがシャットダウンしても保持されます。次回スレーブが起動したとき、マスタからのバイナリログ読み取りとリレーログの処理がどこまで進んでいるかの情報を、スレーブはこれらのファイルから読み取ることができます。

master.info ファイルは I/O スレッドによって更新されます。このファイル内の行と SHOW SLAVE STATUS の出力結果内のカラムとの対応は以下のとおりです。

説明
1Master_Log_File
2Read_Master_Log_Pos
3Master_Host
4Master_User
5パスワード(SHOW SLAVE STATUS では表示されない)
6Master_Port
7Connect_Retry

relay-log.info ファイルは SQL スレッドによって更新されます。ファイル内の行と SHOW SLAVE STATUS の出力結果内のカラムとの対応は以下のとおりです。

説明
1Relay_Log_File
2Relay_Log_Pos
3Relay_Master_Log_File
4Exec_Master_Log_Pos

スレーブのデータをバックアップするとき、リレーログファイルとともにこれら 2 つの小さなファイルもバックアップしてください。スレーブのデータをリストア後、レプリケーションを再会するのに必要となります。リレーログを失った場合でも relay-log.info ファイルがあれば、SQL スレッドがマスタバイナリログをどこまで実行したか調べることができます。そうすれば、CHANGE MASTER TOMASTER_RELAY_LOG オプションおよび MASTER_RELAY_POS オプションとともに使用して、その箇所からバイナリログを再読み取りするようにスレーブに指示できます。これはもちろん、バイナリログがまだマスタサーバに存在することが前提となります。

スレーブが、LOAD DATA INFILE ステートメントもレプリケーションしなくてはならない場合、SQL_LOAD-* ファイルもバックアップしてください。このファイルは、この目的でスレーブが使用するディレクトリ内にあります。LOAD DATA INFILE ステートメントが中断されていた場合、レプリケーションを再開するためにスレーブはこれらのファイルを必要とします。ディレクトリの場所は、--slave-load-tmpdir オプションを使用して指定します。指定しなければ、デフォルト値は tmpdir 変数の値となります。

4.11.4. レプリケーションのセットアップ方法

以下、バージョン 4.1 の MySQL サーバに対する完全なレプリケーションのセットアップ方法について簡単に説明します。 すべてのデータベースのレプリケーションを希望し、過去にレプリケーションの設定をまったく行っていない場合を前提としています。 以下の手順を実行するには、マスタサーバをいったんシャットダウンする必要があります。

以下手順では、1 つのスレーブをセットアップしているだけですが、同様に複数のスレーブをセットアップできます。

この方法が最も簡単でわかりやすいですが、唯一の方法ではありません。たとえば、マスタのデータのスナップショットがすでにあり、マスタにサーバ ID が設定されてバイナリログが有効になっていれば、マスタをシャットダウンしたり更新をブロックしなくてもスレーブをセットアップできます。詳細については、項4.11.9. 「レプリケーション FAQ」 を参照してください。

MySQL レプリケーションのセットアップを管理する場合は、この章全体をよく読み、項4.11.7. 「マスタサーバを制御する SQL ステートメント」 および 項4.11.8. 「スレーブサーバを制御する SQL ステートメント」 で説明されているすべてのコマンドを試してみてください。また、項4.11.6. 「レプリケーションスタートアップオプション」 で説明されている my.cnf のレプリケーションスタートアップオプションにも精通してください。

注意: ここでの手順および後続セクションで説明するレプリケーション SQL ステートメントの実行には、SUPER 権限が必要です。MySQL 4.0.2 より前では、代わりに PROCESS 権限を使用します。

  1. マスタとスレーブに MySQL の最近のバージョンがインストールされていることを確認する。また、項4.11.2. 「レプリケーション実装の概要」 の表で、それらのバージョンに互換性があることを確認する。

    バグについては、その問題が最新のリリースで存在することを確認してから報告すること。

  2. スレーブサーバが接続に使用する MySQL ユーザーをマスタサーバに設定する。このユーザーには、REPLICATION SLAVE 権限を与える必要がある(MySQL バージョンが 4.0.2 より古い場合は、代わりに FILE 権限を与える)。MySQL ユーザーがレプリケーション目的のみのものであれば(推奨)、他に権限を設定する必要はない。

    スレーブのホスト名を、各スレーブサーバがそのユーザーを使用してマスタに接続できるように設定する。たとえば、どのホストからでもマスタにアクセスできる repl という名前のユーザを作成するには、以下のコマンドを使用する。

    mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    MySQL バージョンが 4.0.2 より古い場合は、代わりに以下のコマンドを使用する。

    mysql> GRANT FILE ON *.* TO repl@'%' IDENTIFIED BY '<password>';
    

    LOAD TABLE FROM MASTER ステートメントまたは LOAD DATA FROM MASTER ステートメントをスレーブホストから使用する予定であれば、この MySQL ユーザーにさらに権限を設定する必要がある。

    • MySQL ユーザーに SUPER および RELOAD の各グローバル権限を設定する。

    • ロード対象のすべてのテーブルに対する SELECT 権限を設定する。MySQL ユーザーが SELECT を実行できないマスタテーブルは、LOAD DATA FROM MASTER で無視される。

  3. MyISAM テーブルを使用する場合、FLUSH TABLES WITH READ LOCK コマンドを実行してすべてのテーブルをフラッシュし、クエリ書き込みをブロックする。

    mysql> FLUSH TABLES WITH READ LOCK;
    

    そして、マスタサーバのデータのスナップショットを撮る。

    スナップショットを作成する最も簡単な方法は、アーカイブプログラム(Unix では tar、Windows では PowerArchiverWinRARWinZip など)を使用して、マスタのデータディレクトリにデータベースのアーカイブを作成することである。 たとえば、tar を使用してすべてのデータベースを含むアーカイブを作成するには、カレントディレクトリをマスタサーバのデータディレクトリに変更して、以下のコマンドを実行する。

    shell> tar -cvf /tmp/mysql-snapshot.tar .
    

    this_db という名前のデータベースだけをアーカイブに含める場合は、以下のコマンドを使用する。

    shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db
    

    そしてアーカイブファイルを、スレーブサーバホストの /tmp ディレクトリにコピーする。そのマシンで、カレントディレクトリをスレーブのデータディレクトリに変更し、以下のコマンドを使用してアーカイブファイルをアンパックする。

    shell> tar -xvf /tmp/mysql-snapshot.tar
    

    場合によっては、mysql データベースのレプリケーションが必要でないこともある。その場合は、アーカイブからこのデータベースを除外できる。また、アーカイブに、ログファイル、つまり master.info ファイルまたは relay-log.info ファイルを含める必要はない。

    FLUSH TABLES WITH READ LOCK によって掛けられた読み取りロックが有効な間に、マスタ上の現在のバイナリログ名とオフセット値を読み取る。

    mysql > SHOW MASTER STATUS;
    +---------------+----------+--------------+------------------+
    | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +---------------+----------+--------------+------------------+
    | mysql-bin.003 | 73       | test,bar     | foo,manual,mysql |
    +---------------+----------+--------------+------------------+
    1 row in set (0.06 sec)
    

    File カラムはログの名前を、Position はオフセットを示す。上記の例では、バイナリログ値は mysql-bin.003 でオフセットは 73 である。値を記録しておく。後でスレーブをセットアップするときに、これらの値が必要となる。

    スナップショットを作成してログ名とオフセットを記録したら、マスタの書き込みを再度有効にできる。

    mysql> UNLOCK TABLES;
    

    InnoDB テーブルを使用している場合、InnoDB Hot Backup ツールを使用するのが理想的である。このツールは、MySQL コマーシャルライセンス、サポート、またはバックアップツールそのものを購入することによって使用できる。このツールは、マスタサーバを一切ロックせずに整合したスナップショットを作成し、後でスレーブで使用できるように、スナップショットに対応するログ名とオフセットを記録する。このツールの詳細については、http://www.innodb.com/order.php を参照のこと。

    Hot Backup ツールを使用しないで、InnoDB テーブルのスナップショットを作成する最も速い方法は、マスタサーバをシャットダウンし、InnoDB のデータファイルとログ、およびテーブル定義ファイル(.frm)をコピーすることである。現在のログファイルとオフセットを記録するには、サーバをシャットダウンする前に以下を実行する。

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    次に、SHOW MASTER STATUS の出力からログ名とオフセットを控えておく。ログ名とオフセットを控えたら、テーブルのロックを解除せずにサーバをシャットダウンする。ロックを解除しないのは、スナップショットが現在のログファイルとオフセットに対応している状態を維持するためである。

    shell> mysqladmin -uroot shutdown
    

    MyISAM テーブルと InnoDB テーブルの両方に適用できる代替手段として、上記のバイナリコピーの代わりに、マスタの SQL ダンプを使用できる。これを行うには、マスタで mysqldump --master-data を実行し、後でその SQL ダンプをスレーブに実行する。ただし、これはバイナリコピーよりも時間がかかる。

    マスタが、--log-bin を有効にせずに稼動していた場合、SHOW MASTER STATUS または mysqldump で表示されるログ名と位置の値は空白となる。この場合は、ログ名として空白文字列('')を、オフセット値として 4 を記録しておく。

  4. マスタホストの my.cnf ファイルの [mysqld] セクションに log-bin オプションが含まれていることを確認する。このセクションには、server-id=master_id オプションも含まれている必要がある。ここで、master_id は、1 から 2^32 - 1 までの整数値である。次に例を示す。

    [mysqld]
    log-bin
    server-id=1
    

    これらのオプションがなければ、追加してから、サーバを再起動する。

  5. スレーブサーバとして使用するサーバを停止し、その my.cnf ファイルに以下を追加する。

    [mysqld]
    server-id=slave_id
    

    slave_id 値は master_id 値と同様、1 から 2^32 - 1 までの整数値である。さらに、スレーブの ID はマスタの ID と異なっていることが非常に重要である。次に例を示す。

    [mysqld]
    server-id=2
    

    複数のスレーブをセットアップする場合、それぞれの server-id がマスタのものと異なり、またスレーブ同士でも異なるようにする。server-id の値は IP アドレスのようなものと考えてよい。これらの ID は、レプリケーションパートナのコミュニティ内で、各サーバインスタンスを一意に識別する。

    server-id 値を指定しない場合、master-host を指定していなければ 1 に設定される。それ以外は 2 に設定される。注意: server-id がなければ、マスタはすべてのスレーブからの接続を拒否し、スレーブはマスタへの接続を拒否する。したがって、server-id の省略はバイナリログによるバックアップでのみ正当化される。

  6. マスタサーバのデータのバイナリバックアップを作成した場合、スレーブを開始する前に、このバックアップをスレーブサーバのデータディレクトリにコピーする。ファイルおよびディレクトリの権限が正しいことを確認する。MySQL を実行しているユーザには、マスタと同様、それらのファイルおよびディレクトリに対する読み取りおよび書き込み権限が必要である。

    mysqldump を使用してバックアップを作成した場合、最初にスレーブを開始する(次のステップを参照)。

  7. スレーブサーバを起動する。レプリケーションを実行していた場合には、--skip-slave-start オプションでスレーブサーバを起動する。また、--log-warnings オプションを使用してスレーブサーバを起動するのもよい。そうすると、問題(ネットワークや接続関連などの問題)に関するメッセージが多く出力される。

  8. mysqldump を使用してマスタサーバのデータのバックアップを作成した場合、ダンプファイルをスレーブサーバにロードする。

    shell> mysql -u root -p < dump_file.sql
    
  9. <> 内の値を実際のシステムの値に置き換えて、スレーブで以下のコマンドを実行する。

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='<master host name>',
        ->     MASTER_USER='<replication user name>',
        ->     MASTER_PASSWORD='<replication password>',
        ->     MASTER_LOG_FILE='<recorded log file name>',
        ->     MASTER_LOG_POS=<recorded log offset>;
    

    以下の表は、これらの変数の最大文字列長である。

    MASTER_HOST60
    MASTER_USER16
    MASTER_PASSWORD32
    MASTER_LOG_FILE255
  10. スレーブスレッドを開始する。

    mysql> START SLAVE; 
    

この手順を完了すると、スレーブはマスタに接続し、スナップショット以後の更新を実行します。

マスタに server-id を設定し忘れた場合、スレーブはマスタに接続できません。

スレーブに server-id を設定し忘れた場合、エラーログに以下のエラーが出力されます。

Warning: one should set server_id to a non-0 value if master_host is set.
The server will not act as a slave.

他の理由でスレーブがレプリケーションを実行できない場合も、スレーブのエラーファイルにエラーメッセージが表示されます。

スレーブがレプリケーションを開始すると、そのデータディレクトリに master.info ファイルと relay-log.info ファイルが作成されます。スレーブはこれら 2 つのファイルを使用して、マスタのバイナリログの処理進捗を記録します。完全に理解していない限り、これらのファイルを削除したり編集しないでください。十分に理解して行う場合には、CHANGE MASTER TO コマンドの使用を推奨します。

注意: master.info の内容には、コマンドラインまたは my.cnf で指定されるオプションより優先されるものがあります。 詳細については、項4.11.6. 「レプリケーションスタートアップオプション」 を参照してください。

スナップショットを一度作成すれば、それを使用して上記手順のスレーブの部分を繰り返して、別のスレーブを設定できます。マスタのスナップショットを新たに作成する必要はありません。

4.11.5. レプリケーション機能と既知の問題

以下、サポートされていることとサポートされていないことについて説明します。

  • レプリケーションは、AUTO_INCREMENTLAST_INSERT_ID()、および TIMESTAMP の値で正しく実行される。

  • USER() 関数および LOAD_FILE() 関数は変更なしにレプリケートされるため、スレーブではうまく機能しない。これは、4.1.1 より古いバージョンのスレーブの CONNECTION_ID() にも当てはまる。 MySQL 4.1 の新しい PASSWORD() 関数は、4.1.1 以降のマスタでは正常にレプリケートできるが、スレーブが 4.1.0 以降であることが前提条件となる。スレーブが古く、PASSWORD() を 4.1.x マスタからレプリケートする必要がある場合、--old-password オプションでマスタを起動する。

  • SQL_MODEUNIQUE_CHECKSSQL_SELECT_LIMITSQL_AUTO_IS_NULLTABLE_TYPE の各変数は現在のところレプリケートされない。FOREIGN_KEY_CHECKS はバージョン 4.0.14 からレプリケートされる。

  • マスタとスレーブでは、同じキャラクタセット(--default-character-set)を使用する必要がある。そうしないと、マスタのキャラクタセットで一意と認識されるキーが、スレーブのキャラクタセットでは一意と見なされない場合があるため、スレーブで重複キーエラーが発生する可能性がある。

  • マスタでトランザクションテーブルを使用し、スレーブで非トランザクションテーブルを使用(同一テーブルで)している場合、スレーブが BEGIN/COMMIT ブロックの途中で停止すると、次回スレーブが BEGIN ブロックの始めから開始するという問題が発生する。 この問題は近い将来、解決する予定である。

  • ユーザ変数を使用する更新クエリは、3.23 および 4.0 で正常にレプリケートされない。これは 4.1 で解決されている。注意: バージョン 5.0 以降、ユーザ変数名の大文字と小文字は区別されなくなるので、5.0 とその前のバージョンとの間でレプリケーションを設定する際は注意が必要となる。

  • マスタとスレーブが両方とも 4.1.1 以降の場合、スレーブは SSL を使用してマスタに接続できる。

  • 実際に発生した例を聞いたことはないが、データの変更が非決定論的、つまりクエリオプティマイザの判断で行われるようにクエリが設計されている場合(レプリケーション外でも、通常、この方法は適切な方法でない)、論理的には、マスタとスレーブのデータが異なる可能性がある。詳細については、項1.8.6.2. 「MySQL の未解決のバグと設計上の問題」 を参照のこと。

  • MySQL 4.1.1 より前では、FLUSHANALYZEOPTIMIZEREPAIR の各コマンドはバイナリログに保存されず、したがってスレーブにレプリケートされない。これらのコマンドは何も変更しないため、通常は問題ではない。しかし、GRANT ステートメントを使用せずに MySQL 権限テーブルを直接更新し、mysql 権限テーブルをレプリケートした場合、新しい権限を有効化するには、スレーブで FLUSH PRIVILEGES を実行することが必要となる。また、MERGE テーブルに含まれる MyISAM テーブルの名前を変更するときに FLUSH TABLES を使用した場合、スレーブで FLUSH TABLES を手動で実行する必要がある。 MySQL 4.1.1 以降、NO_WRITE_TO_BINLOG(またはエイリアスの LOCAL)を指定しない限り、これらのコマンドはバイナリログに書き込まれる(FLUSH LOGSFLUSH MASTERFLUSH SLAVEFLUSH TABLES WITH READ LOCK は除く)。 構文例については、項4.6.4. 「FLUSH 構文」 を参照のこと。

  • MySQL は、1 つのマスタと複数のスレーブ構成のみサポートする。将来は、カレントマスタで問題が発生した場合にマスタを自動変更するアルゴリズムを追加する予定である。また、複数のスレーブに SELECT クエリを送信することによって負荷分散を行う ``エージェント'' 処理も導入する予定である。

  • テンポラリテーブルもレプリケートされる。ただし、スレーブスレッドだけでなくスレーブサーバもシャットダウンし、その際、まだスレーブで実行していない更新ステートメントで使用されるテンポラリテーブルをレプリケートしていた場合、そのテンポラリテーブルはレプリケートされない。スレーブをシャットダウンすると、次回、スレーブを起動したとき、更新に必要なテンポラリテーブルは利用できない。この問題を回避するには、テンポラリテーブルが開いている間、スレーブをシャットダウンしない。代わりに、以下の手順を実行する。

    1. STOP SLAVE ステートメントを実行する。

    2. SHOW STATUS を使用して、Slave_open_temp_tables 変数の値をチェックする。

    3. 値が 0 であれば、mysqladmin shutdown コマンドを実行してスレーブをシャットダウンする。

    4. 値が 0 でなければ、START SLAVE でスレーブスレッドを再開する。

    5. 次回も上記手順を繰り返す。

    この問題は、近い将来解決する予定である。

  • log-slave-updates を有効にすれば、循環的なマスタ/スレーブ関係でサーバを接続しても安全である。注意: ただし、異なるサーバ間で、違った手順で行った更新が引き起こすであろう問題を処理するように、クライアントコードを記述しておかなければ、多くのクエリはこの種のセットアップで正しく機能しない。

    つまり、以下のようなセットアップが可能である。

    A -> B -> C -> A
    

    サーバ ID は、バイナリログイベント内でエンコードされる。A は、A が作成したイベントを認識できるので、A はそのイベントを実行せず、無限ループは発生しない。しかし、この循環セットアップは、テーブル間で競合が生じない更新だけを行っている場合にしか機能しない。つまり、A と C にデータを挿入する場合、C でのレコード挿入と競合するキーのレコードを A に挿入することはできない。また、更新が適用される順序が重要な場合、2 つのサーバで同じ複数のレコードを更新することもできない。

  • スレーブでクエリにエラーが発生すると、スレーブの SQL スレッドは強制終了し、スレーブエラーログにメッセージが書き込まれる。この場合、スレーブに手動で接続し、エラーの原因(テーブルが存在しないなど)を解決し、START SLAVE を実行する。

  • マスタへの接続が失われた場合、スレーブはすぐに再接続を試行する。それが失敗した場合、スレーブは master-connect-retry 秒(デフォルトは 60)ごとに再試行する。このため、マスタをシャットダウンし、しばらく後で再起動しても安全である。スレーブはまた、ネットワーク接続停止にも対応できる。ただし、スレーブがネットワーク停止を認識するのは、マスタから slave_net_timeout 秒間、何のデータも受け取らなかった後である。そのため、ネットワーク停止の時間が短い場合は、slave_net_timeout の値を小さくすべきである。 See 項4.6.8.4. 「SHOW VARIABLES

  • スレーブのシャットダウンをクリーンに行えば、どこでレプリケーションが終了したか記録されるので、安全である。クリーンでないシャットダウンでは、システム終了前にディスクキャッシュが同期化されていない場合は特に、問題が発生する可能性がある。性能の高い無停電電源装置を用意すれば、システムの耐障害性はかなり向上する。

  • MyISAM テーブルの非トランザクション性により、テーブルの更新を一部だけ実行してエラーコードを返すクエリが現れる可能性がある。複数レコード挿入で 1 つのレコードがキー制約に違反していた場合や、長い更新クエリが一部のレコードだけを更新した後に強制終了された場合に、発生する。これがマスタで発生した場合、エラーコードが正当で、かつクエリ実行結果も同じエラーコードであったとき以外、スレーブスレッドは終了し、データベース管理者の判断を待つ。このエラーコード確認動作が望ましくない場合は、--slave-skip-errors オプションで一部(または全部)のエラーを無視できる。このオプションは、MySQL バージョン 3.23.47 より使用可能。

  • BEGIN/COMMIT セグメント内部で、非トランザクションテーブルからトランザクションテーブルを更新する場合、トランザクションがコミットする前に非トランザクションテーブルを変更するスレッドがあれば、バイナリログへの更新が非同期になる。これは、トランザクションのバイナリログへの書き込みがコミット後に行われるためである。

  • バージョン 4.0.15 より前では、非トランザクションテーブルへの更新は、更新実行後すぐにバイナリログに書き込まれ、トランザクションテーブルへの変更は、COMMIT 時に書き込まれるか、または ROLLBACK を使用した場合はまったく書き込まれない。バックアップまたはレプリケーションでバイナリログを使用する場合、同一トランザクションでトランザクションテーブルと非トランザクションテーブルの更新を行う際は、この点に注意しなければいけない。トランザクションテーブルと非トランザクションテーブルの更新が混在したトランザクションでのログ動作は、バージョン 4.0.15 で変更され、この問題は解決された(バイナリログでのクエリの書き込み順序に問題はなくなり、ROLLBACK の場合でも必要なクエリはすべてバイナリログに書き込まれるようになった)。ただし、最初の接続のトランザクションが完了していない時点で、2 番目の接続が非トランザクションテーブルを更新した場合の問題は残っている(2 番目の接続の更新は実行後すぐ書き込まれるため、順番が混乱する可能性はまだある)。

以下の表は、MySQL 3.23 で問題だったものを MySQL 4.0 で解決した事項です。

  • LOAD DATA INFILE は、更新伝達時にデータファイルがマスタサーバにあれば、正しく処理される。

  • LOAD LOCAL DATA INFILE はスキップされる。

  • 3.23 では、更新内の RAND() は正しくレプリケートされなかった。RAND() が含まれる更新をレプリケートしている場合は、RAND(some_non_rand_expr) を使用する。 たとえば、RAND() への引数に UNIX_TIMESTAMP() を使用できる。これは 4.0 で解決された。

4.11.6. レプリケーションスタートアップオプション

マスタとスレーブの両方で、server-id オプションを使用して各サーバに一意のレプリケーション ID を設定する必要があります。マスタとサーバそれぞれに、1 から 2^32 - 1 までの整数から一意の番号を割り当てます。 たとえば、server-id=3 のように設定します。

マスタサーバで使用できる、バイナリログを制御するオプションについては、項4.10.4. 「バイナリログ」 で説明しています。

以下の表は、スレーブサーバで使用できるオプションを説明したものです。 コマンドラインまたはオプション設定ファイルで指定できます。

注意: レプリケーションでは、以下のオプションを特殊な方法で処理します。

  • --master-host

  • --master-user

  • --master-password

  • --master-port

  • --master-connect-retry

スレーブサーバの起動時に master.info ファイルが存在しない場合、オプション設定ファイルまたはコマンドラインで指定した値が使用されます。これは、サーバをレプリケーションスレーブとして初めて起動した場合や、RESET SLAVE を実行してスレーブサーバをシャットダウンし、再起動した場合などに起こることです。

スレーブサーバの起動時に master.info ファイルが存在する場合は、このファイルの値が使用されます。オプション設定ファイルまたはコマンドラインの対応するオプション値は無視されます。

my.cnf ファイルで次のオプションを指定していると仮定します。

[mysqld]
master-host=this_host

サーバをレプリケーションスレーブとして初めて起動したとき、サーバは my.cnf ファイルからこのオプションを読み取って使用します。サーバは次にその値を master.info ファイルに記録します。次回サーバを起動したとき、サーバは master.info ファイルからのみマスタホスト値を読み取ります。my.cnf ファイルを変更して別のマスタホストを指定しても、反映されません。マスタホスト値を変更したい場合には、 CHANGE MASTER TO を使用する必要があります。

MySQL 4.1.1 以降、以下のオプションも特殊な方法で処理されます。

  • --master-ssl

  • --master-ssl-ca

  • --master-ssl-capath

  • --master-ssl-cert

  • --master-ssl-cipher

  • --master-ssl-key

これらのオプションに対応する値が master.info ファイルに含まれています。加えて、4.1.1 のファイル形式では、最初の行に、ファイル内の行数が示されます。古いサーバを 4.1.1 にアップグレードすると、新しいサーバの起動時に、master.info は自動的に新しい形式にアップグレードされます(4.1.1 以降のものを 4.1.1 より前のバージョンにダウングレードした場合、古いサーバを最初に起動する前に、ファイルの最初の行を手動で削除する必要があります)。

サーバは、スタートアップオプションよりも既存の master.info ファイルを優先するので、場合によっては、これらの値にはスタートアップオプションを使用せず、CHANGE MASTER TO ステートメントを使用して指定する方が適しています。項4.11.8.1. 「CHANGE MASTER TO を参照してください。

以下、スタートアップオプションを使用してスレーブサーバを設定した例です。

[mysqld]
server-id=2
master-host=db-master.mycompany.com
master-port=3306
master-user=pertinax
master-password=freitag
master-connect-retry=60
report-host=db-slave.mycompany.com

以下の一覧は、レプリケーション制御に使用できるスタートアップオプションの説明です。

  • --log-slave-updates

    スレーブの SQL スレッドで実行された更新を、スレーブのバイナリログに記録するようにスレーブに指示する。デフォルトではオフ。このオプションを有効にするには、バイナリログを有効にして(--log-bin オプションを使用して)スレーブを起動する必要がある。レプリケーションサーバをチェーン状に構成するには、--log-slave-updates を使用する。たとえば、次のようにセットアップできる。

    A -> B -> C
    

    A はスレーブ B のマスタとして機能し、B はスレーブ C のマスタとして機能する。B がマスタでもあり、スレーブでもあるこの構成では、--log-slave-updates オプションで B を起動する必要がある。A と B は両方とも、バイナリログを有効にして起動する必要がある。

  • --log-warnings

    スレーブにより詳細なメッセージを出力させる。たとえば、ネットワークまたは接続が切断された後で再接続に成功したというメッセージや、各スレーブスレッドがどのように開始したかについての情報メッセージを出力することができる。

    このオプションはレプリケーションの使用のみに限定されない。さまざまなサーバアクティビティに関する通知を出力する。

  • --master-host=host

    マスタレプリケーションサーバのホスト名または IP アドレスを指定する。このオプションを指定しなければ、スレーブスレッドは開始できない。master.info の値を読み取れる場合は、ファイルに書かれている値が優先される。このオプション名は --bootstrap-master-host などにすべきだったという意見もあるが、現在、そのまま --master-host が使用されている。

  • --master-user=username

    マスタへの接続時、スレーブスレッドが認証に使用するアカウントのユーザ名。アカウントには REPLICATION SLAVE 権限が必要(MySQL 4.0.2 より前では、FILE 権限が必要)。マスタユーザが設定されていない場合、ユーザ test と想定する。master.info の値を読み取れる場合は、この値が優先される。

  • --master-password=password

    マスタへの接続時、スレーブスレッドが認証に使用するアカウントのパスワード。設定しなければ、空白パスワードと見なされる。master.info の値を読み取れる場合は、この値が優先される。

  • --master-port=port_number

    マスタがリッスンするポート。設定しなければ、MYSQL_PORT のコンパイルされた設定が採用される。configure オプションを使用していなければ、これは 3306 となる。master.info の値を読み取れる場合、その値が優先される。

  • --master-connect-retry=seconds

    マスタがダウンした場合、または接続が失われた場合、スレーブスレッドがマスタへの接続を再試行する前に、スリープ状態で待機する秒数。デフォルトは 60 である。master.info の値を読み取れる場合は、その値が優先される。

  • --master-info-file=filename

    スレーブがマスタに関する情報を記録するためのファイル名を指定する。デフォルトでは、データディレクトリの mysql.info

  • --master-ssl , --master-ssl-ca=file_name , --master-ssl-capath=directory_name , --master-ssl-cert=file_name , --master-ssl-cipher=cipher_list , --master-ssl-key=file_name

    これらのオプションは、SSL 使用によるマスタサーバへの安全なレプリケーション接続をセットアップするために使用する。これらの意味は、項4.4.10.5. 「SSL コマンドラインオプション」 で説明した --ssl--ssl-ca--ssl-capath--ssl-cert--ssl-cipher--ssl-key の各オプションと同じである。

    これらのオプションは、MySQL 4.1.1 から使用可能である。

  • --max-relay-log-size=#

    リレーログを自動的にローテートする際に使用する。 See 項4.6.8.4. 「SHOW VARIABLES

  • --relay-log=filename

    リレーログの場所と名前を指定する。これを使用して、ホスト名に依存しないリレーログ名を指定できる。また、リレーログが大きくなる傾向があり(および max_relay_log_size の値を小さくしたくない場合で)、リレーログをデータディレクトリとは別の領域に置く必要がある場合にもこのオプションを使用できる。あるいは、複数のディスクに負荷を分散して処理速度を上げる場合にもこのオプションを使用できる。

  • --relay-log-index=filename

    リレーログインデックスファイルの場所と名前を指定する。

  • --relay-log-info-file=filename

    relay-log.info に別の名前を指定したり、このファイルをデータディレクトリとは別のディレクトリに配置する。

  • --relay-log-purge=0|1

    リレーログファイルが不要になったときの自動パージを有効または無効にする。これは、SET GLOBAL RELAY_LOG_PURGE=0|1 で動的に変更できるグローバル変数である。デフォルト値は 1。

    このオプションは MySQL 4.1.1 から利用可能。

  • --relay-log-space-limit=#

    スレーブの全リレーログの合計サイズ条件を設定する(0 は ``無制限'' という意味)。スレーブマシンのハードディスクが小さい場合に便利である。限度に達すると、SQL スレッドが、クエリを実行し終わって不要になったリレーログを削除するまで、I/O スレッドは一時停止する(マスタのバイナリログを読み取らない)。注意: この制限は絶対値ではない。SQL スレッドがリレーログを削除するためにさらにイベントを必要とする場合があり、その場合は削除が可能になるまで、I/O スレッドは制限を超えて続行する。続行しなければデッドロックが発生する(MySQL 4.0.13 より前では発生していた)。 --relay-log-space-limit は、--max-relay-log-size 値の 2 倍より小さく設定してはいけない。また、--max-relay-log-size が 0 の場合は --max-binlog-size 値の 2 倍より小さく設定してはいけない。小さく設定した場合、--relay-log-space-limit が超過しているために I/O スレッドが待機している間、SQL スレッドにはパージできるリレーログがなく、I/O スレッドは一時的に --relay-log-space-limit を無視することになる。

  • --replicate-do-table=db_name.table_name

    指定したテーブルに対するクエリのみレプリケーションを限定するようスレーブスレッドに指示する。複数のテーブルを指定するには、コマンドを複数回、各テーブルに 1 回ずつ使用する。これは、--replicate-do-db とは対照的に、データベースをまたがった更新用に使用する。この一覧の後の説明を参照のこと。

  • --replicate-ignore-table=db_name.table_name

    指定したテーブルを更新するクエリをレプリケートしないことをスレーブスレッドに指示する(そのコマンドが同時に他のテーブルを更新する場合でも)。無視するテーブルを複数指定するには、コマンドを複数回、各テーブルに 1 回ずつ使用する。これは、--replicate-ignore-db とは対照的に、データベースをまたがった更新用に使用する。この一覧の後の説明を参照のこと。

  • --replicate-wild-do-table=db_name.table_name

    指定したワイルドカードパターンに一致するテーブルに対するクエリのみを、レプリケーションすることをスレーブスレッドに指示する。複数のテーブルを指定するには、コマンドを複数回、各テーブルに 1 回ずつ使用する。これは、データベースをまたがった更新用に使用する。この一覧の後の説明を参照のこと。

    例: --replicate-wild-do-table=foo%.bar% は、foo で始まるデータベースの bar で始まるテーブルを使用する更新だけをレプリケートする。

    注意: --replicate-wild-do-table=foo%.% を使用すると、このルールは CREATE DATABASE および DROP DATABASE にも伝播し、データベース名がデータベースパターン(ここでは foo%)に一致した場合、これら 2 つののステートメントがレプリケートされる(これは、% がパターンであることによって引き起こされる)。

    ワイルドカード文字 _% のエスケープにも注意が必要である。たとえば、my_own%db データベース(データベースの正確な名前)のすべてのテーブルをレプリケートし、my1ownAABCdb データベースのテーブルはレプリケートしない場合、_ および % をエスケープする。この場合、replicate-wild-do-table=my\_own\%db のように実行する。このオプションをコマンドラインから指定した場合、システムによっては \ をエスケープする必要がある(たとえば bash シェルでは、--replicate-wild-do-table=my\\_own\\%db と入力する必要がある)。

  • --replicate-wild-ignore-table=db_name.table_name

    指定したワイルドカードパターンに一致するテーブルに対するクエリをレプリケートしないことをスレーブスレッドに指示する。無視するテーブルを複数指定するには、コマンドを複数回、各テーブルに 1 回ずつ使用する。これは、 データベースをまたがった更新用に使用する。この一覧の後の説明を参照のこと。

    例: --replicate-wild-ignore-table=foo%.bar% は、foo で始まるデータベースの bar で始まるテーブルを使用する更新をレプリケートしない。

    注意: --replicate-wild-ignore-table=foo%.% を実行すると、ルールは CREATE DATABASE および DROP DATABASE にも伝播し、データベース名がデータベースパターン(ここでは foo%)に一致するとこれら 2 つののステートメントがレプリケートされる(これは、% がパターンであることによって引き起こされる)。

    ワイルドカード文字 _% のエスケープにも注意が必要である。replicate-wild-do-table の説明を参照のこと。

  • --replicate-do-db=database_name

    カレントデータベース(USE によって選択されたデータベース)が database_name の場合に、このデータベースに対するクエリだけをレプリケーションするようスレーブに指示する。 複数のデータベースを指定するには、コマンドを複数回、各データベースに 1 回ずつ使用する。注意: UPDATE some_db.some_table SET foo='bar' など、データベースをまたがるクエリは、別のデータベースが選択されていたりデータベースが選択されていなければ、レプリケートされない。データベースをまたがる更新が必要な場合は、3.23.28 以降を使用し、--replicate-wild-do-table=db_name.% を使用する。この一覧の後の説明を参照のこと。

    予想しづらい動作例: スレーブを --replicate-do-db=sales で起動し、USE prices; UPDATE sales.january SET amount=amount+1000; を実行した場合、このクエリはレプリケートされない。

    データベースをまたがる更新が必要な場合は、代わりに --replicate-wild-do-table=db_name.% を使用する。

    この ``カレントデータベースのみチェックする'' という動作は、複数のデータベースにまたがる複数のテーブルの削除や更新の場合、コマンドからだけではクエリをレプリケートすべきかどうか判別が難しいということが主な理由になる。また、カレントデータベースのみチェックする方が速い。

  • --replicate-ignore-db=database_name

    カレントデータベース(USE によって選択されたデータベース)が database_name である場合に、このデータベースに対するクエリをレプリケートしないようスレーブに指示する。無視するデータベースを複数指定するには、コマンドを複数回、各データベースに 1 回ずつ使用する。テーブルをまたがる更新を行い、それらの更新をレプリケートしない場合には、このオプションを使用すべきではない。この一覧の後の説明を参照のこと。

    予想しづらい動作例: スレーブを --replicate-ignore-db=sales で起動し、USE prices; UPDATE sales.january SET amount=amount+1000; を実行した場合、このクエリはレプリケートされる。

    データベースをまたがる更新が必要な場合には、代わりに --replicate-wild-ignore-table=db_name.% を使用する。

  • --replicate-rewrite-db=from_name->to_name

    カレントデータベース(USE によって選択されたデータベース)がマスタの from_name である場合、to_name に変換するようスレーブに指示する。テーブルに関連するステートメントだけが影響を受け(CREATE DATABASEDROP DATABASE には影響しない)、かつ from_name がマスタのカレントデータベースである場合のみ影響がある。これは、データベースをまたがった更新には機能しない。注意: 変換は、--replicate-* ルールがテストされる前に行われる。

    例: replicate-rewrite-db=master_db_name->slave_db_name

  • --report-host=host

    スレーブの登録中にマスタに報告されるスレーブのホスト名または IP アドレス。これらは SHOW SLAVE HOSTS の出力に表示される。スレーブに自らをマスタに登録させない場合、設定しないままにしておく。注意: スレーブの接続後、マスタが TCP/IP ソケットからスレーブの IP アドレスを読み取るだけでは十分ではない。NAT および他のルーティングの事情により、この IP は、マスタまたは他のホストからスレーブに接続するのに有効ではない場合がある。

    このオプションは MySQL 4.0.0 から利用可能。

  • --report-port=port_number

    スレーブの登録中にマスタに報告するスレーブの接続ポート。スレーブがデフォルト以外のポートをリッスンする場合、または、マスタやその他のクライアントとスレーブ間に特殊なトンネルがある場合だけ、これを設定する。わからない場合は、このオプションは設定しないでおく。

    このオプションは MySQL 4.0.0 から利用可能。

  • --skip-slave-start

    サーバの起動時にスレーブスレッドを開始しないようスレーブサーバに指示する。ユーザが後で START SLAVE を使用して、スレーブスレッドを開始できる。

  • --slave_compressed_protocol=#

    スレーブとクライアントの両方が圧縮をサポートしていれば、値が 1 の場合、そのプロトコルに圧縮が使用される。

  • --slave-load-tmpdir=filename

    このオプションはデフォルトでは、tmpdir 変数の値と同じになる。スレーブ SQL スレッドが LOAD DATA INFILE コマンドをレプリケートするとき、ロードするファイルをリレーログからテンポラリファイルに抽出して、それをテーブルにロードする。マスタにロードされたファイルが非常に大きい場合、スレーブのテンポラリファイルも巨大になる。そのため、tmpdir とは別の大きなディスクにテンポラリファイルを置くことが必要になる場合に、このオプションを使用する。その場合、リレーログも大きくなるため、--relay-log オプションも使用できる。--slave-load-tmpdir は、メモリベースではなく、ディスクベースのファイルシステムをポイントすることが必要。これは、LOAD DATA INFILE のレプリケートに使用されたテンポラリファイルが、マシンをリブートしても残っていることがスレーブにとって必要なためである。

  • --slave-net-timeout=#

    接続が切断されたと判断して接続を再試行する際、そのために読み取りを中止する前に、マスタからのデータを待つ秒数。最初の再試行は、このタイムアウト直後に行われる。再試行の間隔は、--master-connect-retry オプションで制御する。

  • --slave-skip-errors= [err_code1,err_code2,... | all]

    指定したエラーをクエリが返しても、レプリケーションを続行するようスレーブ SQL スレッドに指示する。通常、エラーが発生するとレプリケーションは停止し、ユーザはデータの不整合を手動で解決できる。なぜエラー発生するのか原因を完全に理解していない場合には、このオプションを使用してはいけない。レプリケーションのセットアップに問題がなく、クライアントプログラムにもバグがなく、および MySQL 自体にもバグがなければ、エラーで中止になることはないはずである。このオプションを乱用すると、スレーブがマスタと大きく非同期となり、ユーザには問題発生の原因もわからなくなる。

    エラーコードには、スレーブエラーログのエラーメッセージおよび SHOW SLAVE STATUS の出力に示される番号を使用する必要がある。エラーメッセージの全一覧は、ソースディストリビューション内の Docs/mysqld_error.txt に記載されている。 サーバのエラーコードの一覧は、項12.1. 「返されるエラー」 にも記載されている。

    all の値を使用してすべてのエラーメッセージを無視することもできるが、これは使用すべきではない。言うまでもなく、それを使用すればデータの整合性が保証されない。使用した場合、スレーブのデータがマスタのデータと異なってしまう可能性が十分にある。

    例:

    --slave-skip-errors=1062,1053
    --slave-skip-errors=all
    

これらのオプションのうちいくつかは、すべての --replicate-* オプションのように、スレーブサーバの起動時のみ設定でき、実行中は設定できません。これは、将来解決する予定です。

以下は、スレーブがクエリを実行するか無視するかを決定するための r--eplicate-* ルールの評価順序です。

  1. --replicate-do-db ルールまたは --replicate-ignore-db ルールがあるか。

    • Yes: --binlog-do-db および --binlog-ignore-db と同じようにそれらをテストする(see 項4.10.4. 「バイナリログ」)。その結果を見る。

      • ignore the query: 無視して終了する。

      • execute the query: すぐには実行せず、決定を保留して次のステップに進む。

    • No: 次のステップに移る。

  2. --replicate-*-table ルールはあるか。

    • No: クエリを実行して終了する。

    • Yes: 次のステップに移る。更新されるテーブルのみ、ルールと比較される(INSERT INTO sales SELECT * FROM prices では、sales のみルールと比較される)。複数のテーブルが更新される(複数テーブルステートメントの)場合、最初に一致したテーブル(``do'' または ``ignore'' と一致するテーブル)が対象となる(最初のテーブルがルールと比較され、それで決定できない場合は 2 番目のテーブルがルールと比較される)。

  3. --replicate-do-table ルールはあるか。

    • Yes: テーブルがいずれかに一致するか。

      • Yes: クエリを実行して終了する。

      • No: 次のステップに移る。

    • No: 次のステップに移る。

  4. --replicate-ignore-table ルールはあるか。

    • Yes: テーブルがいずれかに一致するか

      • Yes: クエリを無視して終了する。

      • No: 次のステップに移る。

    • No: 次のステップに移る。

  5. --replicate-wild-do-table ルールはあるか。

    • Yes: テーブルがいずれかに一致するか。

      • Yes: クエリを実行して終了する。

      • No: 次のステップに移る。

    • No: 次のステップに移る。

  6. --replicate-wild-ignore-table ルールはあるか。

    • Yes: テーブルがいずれかに一致するか。

      • Yes: クエリを無視して終了する。

      • No: 次のステップに移る。

    • No: 次のステップに移る。

  7. --replicate-*-table ルールはいずれも一致しなかった。 これらのルールでテストするテーブルは他にあるか。

    • Yes: ループする。

    • No: 更新対象のすべてのテーブルをテストしたが、どのルールにも一致しなかった。 --replicate-do-table または --replicate-wild-do-table ルールがあるか。

      • Yes: クエリを無視して終了する。

      • No: クエリを実行して終了する。

4.11.7. マスタサーバを制御する SQL ステートメント

レプリケーションは SQL インタフェースで制御できます。このセクションでは、マスタレプリケーションサーバを管理するためのステートメントについて説明します。項4.11.8. 「スレーブサーバを制御する SQL ステートメント」 では、スレーブサーバを管理するためのステートメントについて説明しています。

4.11.7.1. PURGE MASTER LOGS

PURGE {MASTER|BINARY} LOGS TO 'log_name'
PURGE {MASTER|BINARY} LOGS BEFORE 'date'

指定したログまたは指定した日付より前の、ログインデックスにリストされたバイナリログをすべて削除します。ログインデックスファイル内に記録されたリストからもログが削除されるので、指定したログが最初になります。

例:

PURGE MASTER LOGS TO 'mysql-bin.010';
PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';

BEFORE 変数は MySQL 4.1 から利用可能になっています。その日付引数の形式は 'YYYY-MM-DD hh:mm:ss' です。MASTERBINARY はシノニムですが、BINARY は MySQL 4.1.1 以降でのみ使用できます。

削除しようとしているログのいずれかを、アクティブなスレーブが読み取り中であれば、このコマンドは何も実行せず、エラーとなります。ただし、スリープ状態のスレーブがあり、それが後で読み取る予定のログをパージしてしまうと、そのスレーブが活動を再開してもレプリケーションを実行できません。スレーブがレプリケーションを実行中にコマンドを実行しても安全です。中止する必要はありません。

最初に SHOW SLAVE STATUS を実行してすべてのスレーブをチェックし、どのログを読み取り中であるか調べ、SHOW MASTER LOGS を実行してマスタのログ一覧を表示します。すべてのスレーブで最初のログを見つけ(全スレーブが最新の状態に更新されていれば、これは一覧の最後のログになります)、削除しようとしているすべてのログをバックアップし(任意)、目的のログまでをパージします。

4.11.7.2. RESET MASTER

RESET MASTER

インデックスファイルにリストされたすべてのバイナリログを削除し、バイナリログインデックスファイルを空白にリセットします。

このステートメントは MySQL 3.23.26 より前は FLUSH MASTER という名前でした。

4.11.7.3. SET SQL_LOG_BIN

SET SQL_LOG_BIN = {0|1}

クライアントが SUPER 権限のアカウントを使用して接続している場合、現在の接続(SQL_LOG_BIN はセッション変数)でのバイナリログの無効/有効を切り替えます。クライアントにその権限がない場合、このステートメントは無視されます。

4.11.7.4. SHOW BINLOG EVENTS

SHOW BINLOG EVENTS [ IN 'log_name' ] [ FROM pos ] [ LIMIT [offset,] row_count ]

バイナリログ内のイベントを表示します。'log_name' を指定しなければ、最初のバイナリログが表示されます。

このステートメントは MySQL 4.0 から利用可能です。

4.11.7.5. SHOW MASTER STATUS

SHOW MASTER STATUS

マスタのバイナリログのステータス情報を提供します。

4.11.7.6. SHOW MASTER LOGS

SHOW MASTER LOGS

マスタのバイナリログを一覧表示します。このコマンドは PURGE MASTER LOGS を使用する前に実行して、どれだけ削除すべきか調べます。

4.11.7.7. SHOW SLAVE HOSTS

SHOW SLAVE HOSTS

マスタに現在登録されているスレーブの一覧を表示します。 注意: --report-host=slave_name オプションで起動していないスレーブは、この一覧には表示されません。

4.11.8. スレーブサーバを制御する SQL ステートメント

レプリケーションは SQL インタフェースで制御できます。このセクションでは、スレーブレプリケーションサーバを管理するためのステートメントについて説明します。 マスタサーバを管理するステートメントについては、項4.11.7. 「マスタサーバを制御する SQL ステートメント」 で説明しています。

4.11.8.1. CHANGE MASTER TO

CHANGE MASTER TO master_def [, master_def] ...

master_def =
      MASTER_HOST = 'host_name'
    | MASTER_USER = 'user_name'
    | MASTER_PASSWORD = 'password'
    | MASTER_PORT = port_num
    | MASTER_CONNECT_RETRY = count
    | MASTER_LOG_FILE = 'master_log_name'
    | MASTER_LOG_POS = master_log_pos
    | RELAY_LOG_FILE = 'relay_log_name'
    | RELAY_LOG_POS = relay_log_pos
    | MASTER_SSL = {0|1}
    | MASTER_SSL_CA = 'ca_file_name'
    | MASTER_SSL_CAPATH = 'ca_directory_name'
    | MASTER_SSL_CERT = 'cert_file_name'
    | MASTER_SSL_KEY = 'key_file_name'
    | MASTER_SSL_CIPHER = 'cipher_list'

スレーブサーバがマスタサーバとの接続および通信のために使用しているパラメータを変更します。 以下、可能な master_def の値を示します。

リレーログオプション(RELAY_LOG_FILERELAY_LOG_POS)は、MySQL 4.0 から利用可能です。

SSL オプション(MASTER_SSLMASTER_SSL_CAMASTER_SSL_CAPATHMASTER_SSL_CERTMASTER_SSL_KEY、および MASTER_SSL_CIPHER)は、MySQL 4.1.1 から利用可能です。これらのオプションは、SSL サポートなしでコンパイルされているスレーブでも変更できます。これは master.info ファイルに保存されますが、SSL サポートが有効になっているサーバを使用するまでは無視されます。

例:

mysql> CHANGE MASTER TO
    ->     MASTER_HOST='master2.mycompany.com',
    ->     MASTER_USER='replication',
    ->     MASTER_PASSWORD='bigs3cret',
    ->     MASTER_PORT=3306,
    ->     MASTER_LOG_FILE='master2-bin.001',
    ->     MASTER_LOG_POS=4,
    ->     MASTER_CONNECT_RETRY=10;
mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='slave-relay-bin.006',
    ->     RELAY_LOG_POS=4025;

MASTER_USERMASTER_PASSWORDMASTER_SSLMASTER_SSL_CAMASTER_SSL_CAPATHMASTER_SSL_CERTMASTER_SSL_KEY、および MASTER_SSL_CIPHER は、スレーブがマスタに接続するために必要な情報です。これらの情報を指定しなければ、以前の値がそのまま使用されます。たとえば、MySQL マスタへの接続パスワードが変更された場合は、以下を実行し、

mysql> STOP SLAVE; -- if replication was running
mysql> CHANGE MASTER TO MASTER_PASSWORD='new3cret';
mysql> START SLAVE; -- if you want to restart replication

スレーブに対して新しいパスワードを指定します。変更しない情報(ホスト、ポート、ユーザなど)については指定する必要がありません。

MASTER_HOSTMASTER_PORT は、マスタホストのホスト名または IP アドレスと、その TCP ポートです。注意: MASTER_HOSTlocalhost と同じ場合、MySQL の他の部分と同様、ポートは無視されることがあります(Unix ソケットを利用できる場合など)。

MASTER_HOST または MASTER_PORT を指定した場合、スレーブは、マスタサーバが以前とは異なると想定します(ホストまたはポートの値を以前と同じに指定した場合でも)。この場合、マスタバイナリログの名前と位置の古い値は適用不可と判断されるため、コマンドで MASTER_LOG_FILEMASTER_LOG_POS を指定しなければ、MASTER_LOG_FILE=''MASTER_LOG_POS=4 が自動的に追加されます。

MASTER_LOG_FILEMASTER_LOG_POS は、スレーブの I/O スレッドが次回開始したときにマスタから読み取りを開始する場所の座標です。これらのいずれかを指定した場合、RELAY_LOG_FILE または RELAY_LOG_POS を指定することはできません。 MASTER_LOG_FILEMASTER_LOG_POS のいずれも指定しなければ、CHANGE MASTER 発行前のスレーブ SQL スレッドの最後の座標が使用されます。これにより、スレーブ SQL スレッドがスレーブ I/O スレッドより遅い場合でも、たとえばパスワードだけを変更するときなど、レプリケーションに途切れが生じません。この安全な動作は、MySQL 4.0.17 から 4.1.1 で導入されました。これらのバージョンの前は、CHANGE MASTER 発行前のスレーブ I/O スレッドの最後の座標が使用されていました。そのため、SQL スレッドがマスタからのイベントを失い、レプリケーションが破綻することがありました。

CHANGE MASTERすべてのリレーログを削除します(新規リレーログを開始)。ただし、RELAY_LOG_FILE または RELAY_LOG_POS を指定した場合はこれを実行しません。リレーログは保持されます(MySQL 4.1.1 から、RELAY_LOG_PURGE グローバル変数はサイレントで 0 に設定されます)。CHANGE MASTER TO は、master.inforelay-log.info を更新します。

CHANGE MASTER は、マスタのスナップショットがあり、そのスナップショットが対応するマスタのログとオフセットを記録しているときのスレーブのセットアップに便利です。スナップショットのリストア後、スレーブで CHANGE MASTER TO MASTER_LOG_FILE='log_name_on_master', MASTER_LOG_POS=log_offset_on_master を実行できます。

上記の最初の例(CHANGE MASTER TO MASTER_HOST='master2.mycompany.com' etc)は、マスタとマスタのバイナリログの座標を変更します。これは、スレーブにマスタのレプリケートを実行させる場合です。 2 番目の例は、使用頻度は低いですが、何らかの理由でスレーブのリレーログを再度実行する場合です。この際、マスタに接続する必要はなく、CHANGE MASTER TO を実行して SQL スレッドを開始するだけです(START SLAVE SQL_THREAD)。 これは、レプリケーション以外で、スタンドアロンで非スレーブのサーバのクラッシュ後のリカバリにも使用できます。 サーバがクラッシュし、バックアップをリストアしたとします。 サーバのバイナリログ(リレーログではなく通常のバイナリログ)を再度実行します。このログの名前を myhost-bin.* と仮定します。万が一、以下の手順に忠実に従わず、サーバにバイナリログをパージさせてしまった事態に備えて、まず、これらのバイナリログのバックアップコピーを安全な場所に作成しておきます。 MySQL 4.1.1 以降を使用している場合、さらに安全対策として SET GLOBAL RELAY_LOG_PURGE=0 を実行します。 次に、log-bin なしで、新しい(以前とは別の)サーバ ID、relay-log=myhost-bin(サーバに、通常のバイナリログをリレーログと思い込ませるため)、および skip-slave-start でサーバを起動し、以下のステートメントを発行します。

mysql> CHANGE MASTER TO
    ->     RELAY_LOG_FILE='myhost-bin.153',
    ->     RELAY_LOG_POS=410,
    ->     MASTER_HOST='some_dummy_string';
mysql> START SLAVE SQL_THREAD;

サーバは自らのバイナリログを読み取って実行し、クラッシュリカバリを達成します。リカバリが完了したら、STOP SLAVE を実行してサーバをシャットダウンし、master.inforelay-log.info を削除して、元のオプションでサーバを再起動します。 現在のところ、サーバにスレーブであると思い込ませるために、MASTER_HOST の指定(ダミー値でも)は必須です。また、以前とは異なるサーバ ID の指定も必要です。そうしないと、サーバは自分の ID の付いたイベントを見て循環レプリケーションであると勘違いし、そのイベントをスキップしてしまいます。将来、これらに対処するオプションを追加する予定です。

4.11.8.2. LOAD DATA FROM MASTER

LOAD DATA FROM MASTER

マスタのスナップショットを撮り、スレーブにコピーします。 スレーブが正しい位置からレプリケーションを開始できるように、MASTER_LOG_FILEMASTER_LOG_POS の値を更新します。replicate-* オプションで指定したテーブルとデータベースの除外ルールも適用されます。

このステートメントの使用には以下の条件があります。

  • これは、MyISAM テーブルに対してのみ有効。

  • スナップショットの作成中、グローバル読み取りロックがかかるので、ロード中のマスタでの更新ができなくなる。

将来、このステートメントを InnoDB テーブルでも使用できるようにし、また非ブロックのオンラインバックアップ機能によってグローバル読み取りロックの必要性もなくす予定です。

大きなテーブルをロードするとき、場合によっては、マスタとスレーブの両方で net_read_timeoutnet_write_timeout の値を大きくすることが必要になります。項4.6.8.4. 「SHOW VARIABLES を参照してください。

注意: LOAD DATA FROM MASTER は、mysql データベースのテーブルをコピーしません。これは、マスタとスレーブに対して複数の異なるユーザと権限を設定しやすくするための措置です。

このステートメントでは、マスタへの接続に使用する MySQL ユーザが、マスタに対する RELOAD 権限と SUPER 権限、およびロードするすべてのマスタテーブルに対する SELECT 権限を持っていることが前提となります。ユーザに SELECT 権限のないマスタのテーブルはすべて、LOAD DATA FROM MASTER では無視されます。マスタは、それらのテーブルをそのユーザには表示しないためです。LOAD DATA FROM MASTERSHOW DATABASES を呼び出してどのマスタデータベースをロードするか調べますが、SHOW DATABASES はユーザに権限のあるデータベースだけを返します。項4.6.8.1. 「データベース、テーブル、カラム、およびインデックスに関する情報の取得」 を参照してください。 スレーブ側では、LOAD DATA FROM MASTER を発行するユーザに、該当するデータベースとテーブルを破棄および作成できる権限が必要です。

4.11.8.3. LOAD TABLE tbl_name FROM MASTER

LOAD TABLE tbl_name FROM MASTER

マスタからスレーブにテーブルのコピーをダウンロードします。このステートメントは主に LOAD DATA FROM MASTER をデバッグするために導入されました。 マスタサーバへの接続に使用する MySQL ユーザに、マスタに対する RELOAD 権限と SUPER 権限、およびロードするマスタテーブルに対する SELECT 権限が必要です。 スレーブ側では、LOAD TABLE FROM MASTER を発行するユーザに、該当するテーブルを破棄および作成する権限が必要です。 前述の LOAD DATA FROM MASTER 項目のタイムアウトに関する説明を参照してください。ここでも適用されます。また、LOAD DATA FROM MASTER の制約がここでも当てはまるので、説明を参照してください(たとえば、LOAD TABLE FROM MASTERMyISAM テーブルでのみ使用できます)。

4.11.8.4. MASTER_POS_WAIT()

SELECT MASTER_POS_WAIT('master_log_file', master_log_pos)

これは関数であり、コマンドではありません。これは、マスタバイナリログの指定位置までスレーブが達している(読み取りと実行を終了している)ことを確認するために使用します。詳細については、項6.3.6.2. 「その他の各種関数」 を参照してください。

4.11.8.5. RESET SLAVE

RESET SLAVE

スレーブのマスタバイナリログでのレプリケーション位置を、スレーブに忘れさせます。 このステートメントは、クリーンな開始のために使用します。これにより、master.info ファイルと relay-log.info ファイル、およびすべてのリレーログが削除され、新しいリレーログが開始されます。注意: スレーブの SQL スレッドによって完全に実行されていない場合でも、すべてのリレーログが削除されます(負荷の高いレプリケーションサーバや、STOP SLAVE ステートメントを発行している場合にこの状態が発生しやすくなります)。master.info ファイルに保存されている接続情報は、対応するスタートアップオプションで値が指定されていれば、すぐにその値にリセットされます。 この情報には、マスタホスト、マスタポート、マスタユーザ、およびマスタパスワードなどの値が含まれます。 スレーブ SQL スレッドが停止したときに、テンポラリテーブルのレプリケート中であった場合、RESET SLAVE が発行され、レプリケートされたテンポラリテーブルはスレーブから削除されます。

このステートメントは MySQL 3.23.26 より前は FLUSH SLAVE という名前でした。

4.11.8.6. SET GLOBAL SQL_SLAVE_SKIP_COUNTER

SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n

マスタの次の n イベントをスキップします。これは、ステートメントによるレプリケーション中断をリカバリするのに役立ちます。

このステートメントは、スレーブスレッドが実行していない場合にのみ有効です。 実行中にはエラーになります。

MySQL 4.0 より前のバージョンを使用している場合には、ステートメントから GLOBAL キーワードを除外してください。

4.11.8.7. SHOW SLAVE STATUS

SHOW SLAVE STATUS

スレーブスレッドの重要なパラメータのステータス情報を提供します。mysql クライアントを使用してこのステートメントを発行する場合、セミコロンの代わりに \G ステートメント終端記号を使用して、読みやすい縦方向のレイアウトにできます。

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
       Slave_IO_State: Waiting for master to send event
          Master_Host: localhost
          Master_User: root
          Master_Port: 3306
        Connect_Retry: 3
      Master_Log_File: gbichot-bin.005
  Read_Master_Log_Pos: 79
       Relay_Log_File: gbichot-relay-bin.005
        Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
     Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
      Replicate_Do_DB:
  Replicate_Ignore_DB:
           Last_Errno: 0
           Last_Error:
         Skip_Counter: 0
  Exec_Master_Log_Pos: 79
      Relay_Log_Space: 552
      Until_Condition: None
       Until_Log_File:
        Until_Log_Pos: 0
   Master_SSL_Allowed: No
   Master_SSL_CA_File:
   Master_SSL_CA_Path:
      Master_SSL_Cert:
    Master_SSL_Cipher:
       Master_SSL_Key:
Seconds_Behind_Master: 8

MySQL のバージョンによっては、ここで示したフィールドがすべて表示されない場合もあります。特に、MySQL 4.1.1 にのみ存在するフィールドもあります。

SHOW SLAVE STATUS で表示されるフィールドには、以下の意味があります。

  • Slave_IO_State

    スレーブ I/O スレッドの SHOW PROCESSLIST 出力の State カラムのコピー。このスレッドがマスタに接続しようとしているのか、マスタからのイベントを待っているのか、マスタに再接続しているのか、などを示す。可能なステータスについては、項4.11.2. 「レプリケーション実装の概要」 を参照のこと。スレッドは実行中だが、マスタとの接続がうまくいかないなどの状況では、このカラムの確認が必要となる。接続で問題がある場合に、それを示すことができるのはこのカラムだけである。反対に、SQL スレッドの場合、シンプルであるため、そのステータスはコピーされない。実行中であれば、何も問題はない。SQL スレッドが実行していなければ、Last_Error カラム(後述)にエラーが表示される。

    このフィールドは MySQL 4.1.1 で導入された。

  • Master_Host

    現在のマスタホスト。

  • Master_User

    マスタへの接続に使用する現在のユーザ。

  • Master_Port

    現在のマスタポート。

  • Connect_Retry

    master-connect-retry の現在値。

  • Master_Log_File

    I/O スレッドが現在読み取り中のマスタのバイナリログファイル名。

  • Read_Master_Log_Pos

    I/O スレッドがマスタのバイナリログでそれまでに読み取りを完了した位置。

  • Relay_Log_File

    SQL スレッドが現在読み取りおよび実行中のリレーログファイル名。

  • Relay_Log_Pos

    SQL スレッドがリレーログ内でそれまでに読み取りおよび実行を完了した位置。

  • Relay_Master_Log_File

    SQL スレッドによって実行された最後のイベントを含むマスタのバイナリログファイル名。

  • Slave_IO_Running

    I/O スレッドが開始されたかどうかを示す。

  • Slave_SQL_Running

    SQL スレッドが開始されたかどうかを示す。

  • Replicate_Do_DB, Replicate_Ignore_DB

    --replicate-do-db オプションおよび --replicate-ignore-db オプションでデータベースが指定されていれば、その一覧。

  • Replicate_Do_Table, Replicate_Ignore_Table, Replicate_Wild_Do_Table, Replicate_Wild_Ignore_Table

    --replicate-do-table--replicate-ignore-table--replicate-wild-do-table--replicate-wild-ignore_table の各オプションでテーブルが指定されていれば、その一覧。

    これらのフィールドは、MySQL 4.1.1 で導入された。

  • Last_Errno

    最後に実行したクエリが返したエラー番号。 0 の値は ``エラーがない'' ことを意味する。

  • Last_Error

    最後に実行したクエリが返したエラーメッセージ。 例:

    Last_Errno: 1051
    Last_Error: error 'Unknown table 'z'' on query 'drop table z'
    

    このメッセージは、マスタにあったテーブル z が破棄されているが、スレーブには存在しないため、DROP TABLE を実行できなかったということを示す。これは、レプリケーションのセットアップ時にテーブルをスレーブにコピーし忘れた場合に発生する。

    空白文字列は ``エラーがない'' ことを意味する。 Last_Error 値が空白でない場合、スレーブのエラーログにもメッセージが表示される。

  • Skip_Counter

    SQL_SLAVE_SKIP_COUNTER で最後に使用された値。

  • Exec_Master_Log_Pos

    マスタのバイナリログ(Relay_Master_Log_File)内の、SQL スレッドによって実行された最後のイベントの位置。マスタのバイナリログの(Relay_Master_Log_File,Exec_Master_Log_Pos)は、リレーログの(Relay_Log_File,Relay_Log_Pos)に対応する。

  • Relay_Log_Space

    既存リレーログすべての合計サイズ。

  • Until_Condition, Until_Log_File, Until_Log_Pos

    START SLAVE ステートメントの UNTIL 節で指定された値。

    Until_Condition には以下の値がある。

    • None UNTIL 節が指定されていない場合。

    • Master スレーブが、マスタのバイナリログの指定位置までを読み取り中である場合。

    • Relay スレーブが、そのリレーログの指定位置までを読み取り中である場合。

    Until_Log_FileUntil_Log_Pos は、SQL スレッドが実行を中止するポイントを定義するログファイル名と位置を示す。

    これらのフィールドは、MySQL 4.1.1 で導入された。

  • Master_SSL_Allowed, Master_SSL_CA_File, Master_SSL_CA_Path, Master_SSL_Cert, Master_SSL_Cipher, Master_SSL_Key

    これらのフィールドは、スレーブがマスタに接続するために使用する SSL パラメータがある場合、それを示す。

    Master_SSL_Allowed には以下の値がある。

    • Yes マスタへの SSL 接続が許可されている場合。

    • No マスタへの SSL 接続が許可されていない場合。

    • Ignored SSL サポートが有効化されていないスレーブによって SSL 接続が許可されている場合。

    他のフィールドの値は、--master-ca--master-capath--master-cert--master-cipher--master-key の各オプションの値に対応する。

    これらのフィールドは、MySQL 4.1.1 で導入された。

  • Seconds_Behind_Master

    スレーブ SQL スレッドによって実行された最後のマスタイベントのタイムスタンプから経過した秒数。まだイベントがまったく発生していない場合、あるいは CHANGE MASTER および RESET SLAVE からイベントが発生していない場合は NULL 値となる。このカラムにより、スレーブがどれだけ ``遅い'' かを知ることができる。マスタとスレーブで同一の時計を使用していなくても問題ない。

    このフィールドは MySQL 4.1.1 で導入された。

4.11.8.8. START SLAVE

START SLAVE [thread_name [, thread_name] ... ]
START SLAVE [SQL_THREAD] UNTIL
    MASTER_LOG_FILE = 'log_name', MASTER_LOG_POS = log_pos
START SLAVE [SQL_THREAD] UNTIL
    RELAY_LOG_FILE = 'log_name', RELAY_LOG_POS = log_pos

thread_name = IO_THREAD | SQL_THREAD

START SLAVE はオプションなしで、両方のスレーブスレッドを開始します。I/O スレッドは、マスタサーバからクエリを読み取り、リレーログに保存します。SQL スレッドはリレーログからクエリを読み取り、実行します。 注意: START SLAVE がスレーブスレッドの開始に成功すると、エラーなしで戻ります。ただし、その場合でも、スレーブスレッドが開始した後に停止することがあります(マスタへの接続に失敗したり、バイナリログの読み取りに失敗した場合など)。START SLAVE は、そのような場合に警告を出しません。エラーログ内で、スレーブスレッドによって生成されるエラーメッセージをチェックするか、SHOW SLAVE STATUS を実行してスレッドが適切に実行しているかどうかをチェックする必要があります。

MySQL 4.0.2 で、ステートメントに IO_THREAD オプションまたは SQL_THREAD オプションを追加して、どちらのスレッドを開始するか指定できるようになりました。

MySQL 4.1.1 以降、UNTIL 節を追加して、マスタバイナリログまたはスレーブリレーログの指定ポイントに SQL スレッドが到達するまでにスレーブを開始するよう指定できます。SQL スレッドがそのポイントに達すると、停止します。ステートメントで SQL_THREAD オプションが指定されていれば、SQL スレッドだけを開始します。そうでない場合は、両方のスレッドを開始します。SQL スレッドがすでに実行中の場合、UNTIL 節は無視され、警告が出力されます。

UNTIL 節では、ログファイル名と位置の両方を指定する必要があります。マスタオプションとリレーログオプションを混同しないでください。

UNTIL 条件は、後続の STOP SLAVE ステートメント、または UNTIL 節を含まない START SLAVE ステートメント、またはサーバの再起動でリセットされます。

UNTIL 節は、レプリケーションのデバッグや、特定のステートメントをスレーブにレプリケートさせたくない場合、その直前までレプリケートするときに使用します。たとえば、マスタで DROP TABLE ステートメントを実行しているが、これが賢明ではなかった場合、UNTIL を使用してその直前までをレプリケートするようスレーブに指示できます。 イベントを調べるには、マスタログまたはリレーログで mysqlbinlog を使用するか、SHOW BINLOG EVENTS ステートメントを使用します。

UNTIL を使用してスレーブにセクションごとのクエリのレプリケーションを実行させる場合は、--skip-slave-start オプションでスレーブを起動し、スレーブの起動と同時に SQL スレッドを開始しないようにすることを推奨します。このオプションは、予期しないサーバの再起動に備えて、コマンドラインではなくオプションファイルで使用するのが良いでしょう。

SHOW SLAVE STATUS ステートメントには、UNTIL 条件の現在の値を表示する出力フィールドが含まれます。

このコマンドは、MySQL 4.0.5 より前は SLAVE START と呼ばれていました。 しばらくは、SLAVE START も下位互換性のために認められますが、将来は廃止されます。

4.11.8.9. STOP SLAVE

STOP SLAVE [thread_name [, thread_name] ... ]

thread_name = IO_THREAD | SQL_THREAD

スレーブスレッドを停止します。 START SLAVE と同様、このステートメントは IO_THREAD オプションと SQL_THREAD オプションを使用して、どちらのスレッドを停止するか指定できます。

このコマンドは、MySQL 4.0.5 より前は SLAVE STOP と呼ばれていました。 しばらくは、SLAVE STOP も下位互換性のために認められますが、将来は廃止されます。

4.11.9. レプリケーション FAQ

Q:マスタがすでに実行中でそれを停止したくない場合、どのようにスレーブをセットアップしますか。

A:いくつかの方法があります。マスタのバックアップを作成してあり、スナップショットに対応するバイナリログ名とオフセットを記録(SHOW MASTER STATUS の出力から)してある場合は、以下を実行します。

  1. スレーブに一意のサーバ ID が割り当てられていることを確認する。

  2. 各パラメータに適切な値を割り当て、以下のステートメントをスレーブで実行する。

    mysql> CHANGE MASTER TO
        ->     MASTER_HOST='master_host-name',
        ->     MASTER_USER='master_user_name',
        ->     MASTER_PASSWORD='master_pass',
        ->     MASTER_LOG_FILE='recorded_log_name',
        ->     MASTER_LOG_POS=recorded_log_pos;
    
  3. スレーブで START SLAVE を実行する。

マスタのバックアップがない場合、以下の方法ですばやく確実にスレーブのセットアップを実行できます。

  1. FLUSH TABLES WITH READ LOCK

  2. gtar zcf /tmp/backup.tar.gz /var/lib/mysql(または、このバリエーション)

  3. SHOW MASTER STATUS(後で必要となるため、出力を必ず記録しておく)

  4. UNLOCK TABLES

代替手段として、上記のバイナリコピーの代わりに、マスタの SQL ダンプを使用することもできます。これを行うには、マスタで mysqldump --master-data を実行し、後でその SQL ダンプをスレーブで実行します。ただし、これはバイナリコピーよりも時間がかかります。

2 つの方法のどちらを使用する場合でも、その後、スナップショットがあり、ログ名およびオフセット値を記録する場合の指示に従ってください。同じスナップショットを使用して複数のスレーブをセットアップできます。いったんマスタのスナップショットを作成すれば、マスタのバイナリログが損傷を受けない限り、数日後でも、場合によっては一ヶ月後でもそのスナップショットを使用してスレーブをセットアップできます。理論的には、待機できる時間は無限です。現実的な制約としては、マスタのディスク空き容量が古いログによって減っていくことと、スレーブがマスタに追いつくのに時間がかかることが挙げられます。

LOAD DATA FROM MASTER を使用することもできます。これはスナップショットを撮り、スレーブにそれをリストアして、スレーブ上のログ名とオフセットを調整することを、全部同時に実行できる便利なコマンドです。将来は、LOAD DATA FROM MASTER がスレーブセットアップの推奨方法となります。ただし、このコマンドを使用した場合、読み取りロックが長時間掛かる可能性があります。このコマンドはまだ理想とする効率性では実装されていません。大きなテーブルがある場合、現時点での推奨方法は、FLUSH TABLES WITH READ LOCK を実行後のローカル tar スナップショットです。

Q: スレーブは常にマスタに接続しておく必要がありますか。

A: いいえ、その必要はありません。スレーブは何時間でも、あるいは何日間でもシャットダウンしておいたり、非接続にしておいても、再接続してマスタの更新に追いつくことができます。たとえば、マスタとスレーブの関係をダイヤルアップリンクでセットアップし、リンクアップを散発的かつ短時間に設定できます。この場合、何か特殊な対策をとらないと、任意の時点でスレーブがマスタと同期されている保証はありません。将来、少なくとも 1 つのスレーブが同期するまでマスタをブロックするオプションを追加する予定です。

Q: スレーブがマスタと比較してどれだけ遅れているかを知るにはどうすればいいですか。つまり、スレーブによってレプリケートされた最後のクエリの日付を知る方法はありますか。

A: スレーブが 4.1.1 以降の場合は、SHOW SLAVE STATUSSeconds_Behind_Master カラムを参照します。これより前のバージョンについては、次のようになります。スレーブ SQL スレッドが存在する場合、つまりSHOW PROCESSLIST で表示される場合(MySQL 3.23 では、スレーブスレッドが存在する場合、つまりスレーブスレッドが SHOW PROCESSLIST で表示される場合)(see 項4.11.3. 「レプリケーションの実装の詳細」)、およびそのスレッドがマスタから読み取ったイベントを最低 1 回は実行している場合のみ、スレーブによってレプリケートされた最後のクエリの日付を知ることができます。実際、スレーブ SQL スレッドがマスタから読み取ったイベントを実行すると、このスレッドは自分の時間をそのイベントのタイムスタンプに修正します(これが、TIMESTAMP もレプリケートする理由です)。結果、SHOW PROCESSLIST 出力の Time カラムでスレーブ SQL スレッドに対して表示される秒数は、最後にレプリケートされたイベントのタイムスタンプとスレーブマシンの実際の時刻の差になります。これを使用して、最後にレプリケートされたイベントの日付を特定できます。注意: スレーブがマスタから切断されて 1 時間経過してから再接続した場合、SHOW PROCESSLISTTime カラムでスレーブ SQL スレッドが 3600 の値を表示する場合があります。これは、スレーブが実行しているクエリが、タイムスタンプから 1 時間経過しているためです。

Q: スレーブが追いつくまでマスタの更新をブロックするにはどうしますか。

A: 以下の手順を実行します。

  1. マスタで、以下のコマンドを実行する。

    mysql> FLUSH TABLES WITH READ LOCK;
    mysql> SHOW MASTER STATUS;
    

    SHOW ステートメントの出力からログ名とオフセットを記録する。

  2. スレーブで以下のコマンドを実行する。ここで、MASTER_POS_WAIT() 関数の引数であるレプリケーション座標は、前のステップで記録した値。

    mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
    

    指定のログファイルおよびオフセットにスレーブが到達するまで、SELECT ステートメントによってブロックされる。到達した時点でスレーブはマスタと同期しており、こここでステートメントが戻る。

  3. マスタで以下のステートメントを発行し、マスタによる更新処理の再開を許可する。

    mysql> UNLOCK TABLES;
    

Q: 二方向レプリケーションをセットアップするときに注意すべき点はありますか。

A: MySQL レプリケーションでは、現在のところ、分散(サーバ間の)更新の原子性を保証するためのマスタとスレーブ間のロッキングプロトコルをサポートしていません。つまり、クライアント A が co-master 1 に更新を行い、それを co-master 2 に伝播する前に、クライアント B が co-master 2 に更新を行って、クライアント A の更新が co-master 1 で行ったものとは変わってしまう可能性があります。この場合、co-master 2 からの更新がすべて伝播した後であっても、クライアント A の更新が co-master 2 に伝わったとき、co-master 1 とは異なるテーブルが生成されます。このため、どのような順序でも更新が安全に行われるという確証がある場合、またはクライアントコードで更新順序の不正に対処できる場合以外は、二方向レプリケーションで 2 つのサーバをチェーン状に設定しないでください。

また更新については、二方向レプリケーションはそれほどパフォーマンス向上に役立たないことも認識してください。サーバは両方ともそれぞれ、1 つのサーバのときと同じ量の更新を行います。違いは、別のサーバから発生した更新が 1 つのスレーブスレッドでシリアル化されるため、ロックの競合が少なくなることぐらいです。その利点も、ネットワーク遅延によって相殺されてしまいます。

Q: レプリケーションを使用してシステムのパフォーマンスを改善する方法はありますか。

A: 1 つのサーバをマスタとしてセットアップし、すべての書き込みをそれにダイレクトします。そして予算とスペースが許容する限り多くのスレーブをセットアップし、マスタと複数のスレーブで読み取りを分散します。--skip-bdb--low-priority-updates、および --delay-key-write=ALL でスレーブを起動すると、スレーブの速度が向上します。この場合、スレーブは速度を上げるため、BDB テーブルの代わりに非トランザクションの MyISAM テーブルを使用します。

Q: パフォーマンス改善レプリケーションを使用するアプリケーションを作成したいのですが、クライアントコードはどうすればいいですか。

A: コード内のデータベースアクセスを担当する部分が適切に抽象化つまりモジュール化されていれば、レプリケートのセットアップで実行できるように変換するのはスムーズかつ簡単です。データベースアクセスの実装部分を変更し、すべての書き込みをマスタに、そして読み取りをマスタかスレーブに送信するようにします。ご使用のコードにこのレベルの抽象化がなされていなければ、レプリケーションシステムを 1 からセットアップします。まず以下の関数で、ラッパライブラリまたはモジュールを作成します。

  • safe_writer_connect()

  • safe_reader_connect()

  • safe_reader_query()

  • safe_writer_query()

各関数名の safe_ は、関数がすべてのエラー条件を処理することを意味します。もちろん、関数には別の名前を使用することも可能です。重要なことは、読み取りのための接続、書き込みのための接続、読み取り実行、および書き込み実行で統合インタフェースを持つことです。

次に、ラッパライブラリを使用するようにクライアントコードを変換します。このプロセスは最初は苦痛かもしれませんが、長期的に見ると損はありません。先ほど説明したアプローチを使用するアプリケーションはすべて、マスタ/スレーブ構成の利点を活用できます。これは、スレーブが複数の場合でも同様です。コードは保守が非常に簡単で、トラブルシューティングオプションの追加も手間がかかりません。1 つか 2 つの関数を修正するだけで、各クエリにかかった時間をログしたり、数千のクエリの中からどのクエリがエラーの原因になったかを特定することなどができます。

コード作成の経験が豊富であれば、replace ユーティリティを使用して変換タスクを自動化することもできます。このユーティリティは MySQL の標準ディストリビューションに含まれています。また、独自の Perl スクリプトを作成することもできます。 コードが認識可能なパターンに従っていれば理想的です。そうでない場合は、書き換えるのが良いでしょう。あるいは少なくとも、1 つのパターンになっているようにしてください。

Q: MySQL レプリケーションによって、どのような場合にどれだけシステムのパフォーマンスを改善できますか。

A: MySQL レプリケーションは、読み取り頻度が高く、書き込み頻度が低いシステムで最も威力を発揮します。単一マスタと複数スレーブのセットアップを使用することにより、理論的にはネットワーク帯域幅の限界またはマスタが処理できる更新負荷の限界までスレーブを追加することにより、システムを拡張できます。

追加する利点がなくなるまでいくつのスレーブを追加できるか、またサイトのパフォーマンスをどれだけ改善できるかを判断するには、クエリパターンを知り、実証的に(ベンチマークを使用して)通常のマスタと通常のスレーブの間の読み取り(毎秒ごとの読み取り、または max_reads)と書き込みスループットの関係を調べる必要があります。ここでは、例として、仮想システムのレプリケーションでの単純化した計算を示します。

システム負荷が 10% の書き込みと 90% の読み取りで構成され、max_reads が 1200 - 2 * max_writes であると仮定します。 つまり、書き込みがなければシステムは毎秒 1200 の読み取りを実行できます。書き込みの平均は読み取り平均の 2 倍かかります。そしてその関係は直線的です。 マスタと各スレーブの能力は同じで、1 マスタと N スレーブがあると想定します。各サーバ(マスタまたはスレーブ)は以下のようになります。

reads = 1200 - 2 * writes(ベンチマークから)

reads = 9* writes / (N + 1) (読み取りは分散されるが、書き込みはすべてのサーバで行われる)

9*writes/(N+1) + 2 * writes = 1200

writes = 1200/(2 + 9/(N+1)

この分析により、以下の結論を導きだせます。

  • N = 0(レプリケーションがないことを意味する)の場合、システムは 1200/11、つまり毎秒 109 書き込みを処理できる(アプリケーションの性質上、読み取りが 9 倍になる)。

  • N = 1 の場合、毎秒 184 の書き込みまで処理できる。

  • N = 8 の場合、毎秒 400 の書き込みまで処理できる。

  • N = 17 であれば、480 の書き込みとなる。

  • N が無限に近づくと(予算も無限大に膨らむが)、毎秒 600 の書き込みに近くなり、システムスループットは 5.5 倍になる。しかし、8 サーバだけで 4 倍近くになっている。

注意: この計算ではシステム帯域を無限として想定しており、現実の場面では重要となるかもしれない要因をいくつか無視しています。多くの場合、N アプリケーションスレーブを追加した場合の結果を正確に予測する上記のような計算を行うのは難しいと言えます。しかし、以下の質問から、レプリケーションによってシステムのパフォーマンスが改善されるかどうか、またどの程度改善されるか、ある程度判断できるでしょう。

  • システムの読み取りと書き込みの比率はどれくらいか。

  • 読み取りを減らした場合、1 つのサーバで処理できる書き込み負荷をどの程度増やせるか。

  • ネットワークの帯域幅を使用できるスレーブ数の上限はいくつか。

Q: 冗長性と高可用性を実現するようにレプリケーションを使用するにはどうすればよいですか。

A: 現在使用可能な機能で、1 つのマスタと 1 つのスレーブ(または複数のスレーブ)をセットアップする必要があります。そして、マスタの稼働状態を監視し、失敗時にアプリケーションとスレーブにマスタの変更を指示するスクリプトを作成します。以下のガイドラインを参考にしてください。

  • スレーブにマスタを変更するよう指示するには、CHANGE MASTER TO コマンドを使用する。

  • アプリケーションにマスタの場所を認識させておくためには、マスタに動的 DNS エントリを採用すると良い。bind で、nsupdate を使用して DNS を動的に更新できる。

  • --log-bin オプションを指定し、--log-slave-updates なしでスレーブを実行する。STOP SLAVE および RESET MASTER を実行し、他のスレーブで CHANGE MASTER TO を実行することにより、スレーブがマスタになる準備ができる。たとえば、以下のセットアップがあると仮定する。`M'' はマスタ、``S'' はスレーブ、``WC'' はデータベース読み取りおよび書き込みを発行するクライアントを意味する。データベース読み取りだけを発行するクライアントは、切り替えの必要がないため、ここでは考慮されていない。

           WC
            \
             v
     WC----> M
           / | \ 
          /  |  \ 
         v   v   v
        S1   S2  S3
    

    S1(S2 および S3 と同様)は、--log-bin を使用し、--log-slave-updates なしで実行しているスレーブである。S1 で実行される書き込みは M からのレプリケーションのみなので、S1 のバイナリログは空白である(S1 は --log-slave-updates なしで実行されている)。 何らかの理由で M が利用できなくなったため、S1 を新しいマスタにする(すべての WC を S1 にダイレクトし、S2 と S3 が S1 をレプリケートするように設定する)。

    すべてのスレーブで、自身のリレーログにあるすべてのクエリを処理したことを確認する。各スレーブで STOP SLAVE IO_THREAD を発行し、SHOW PROCESSLIST の出力で Has read all relay log が表示されることを確認する。すべてのスレーブでこれを確認したら、新しい環境に設定できる。すべてのスレーブで STOP SLAVE を発行し、マスタに昇格するスレーブに RESET MASTER を、他のスレーブには CHANGE MASTER を実行する。

    これで、M にアクセスする WC はいなくなる。すべての WC に、クエリを S1 に送信するよう指示する。これ以降、WC によって S1 に送信されたクエリはすべて、S1 のバイナリログに書き込まれる。S1 のバイナリログには、M が終了した時点以降に S1 に送信されたクエリがすべて正確に含まれる。 S2(および S3)で、STOP SLAVECHANGE MASTER TO MASTER_HOST='S1' を実行する('S1' には S1 の実際のホスト名が入る)。CHANGE MASTER で、S2 または S3 から S1 に接続するための全情報(ユーザ、パスワード、ポート)を追加する。CHANGE MASTER で、S1 のバイナリログの名前や位置を指定する必要はない。それが最初のバイナリログであり、位置が 4 であることがわかっており、これらの値は CHANGE MASTER のデフォルトとなっているからである。最後に、S2 と S3 で START SLAVE を実行すると、以下のようになる。

           WC   
          /   
          |  
     WC   |  M(unavailable)
      \   | 
       \  | 
        v v
         S1<--S2  S3  
          ^       |
          +-------+
    

    M が再稼動したら、S2 および S3 と同じように CHANGE MASTER を実行するだけで済む。そうすると M は S1 のスレーブとなり、ダウンしてから実行された WC 書き込みをすべてピックアップする。M をマスタに戻す(それが一番強力なマシンである、という理由などで)には、S1 と M の立場を逆にして前回の手順を繰り返す。このとき、S1、S2、S3 を M のスレーブにする前に、M で RESET MASTER を実行することを忘れてはいけない。そうしないと、M が非稼動になる前の古い WC 書き込みも拾ってしまう。

現在、自動マスタ選択システムを MySQL に統合する方向で進んでいますが、それが実現するまでは、自分で監視ツールを作成してください。

4.11.10. レプリケーションのトラブルシューティング

指示に従って設定したにもかかわらず、レプリケーションセットアップが機能しない場合は、まず、以下の項目をチェックしてください。

  • エラーログのメッセージをチェックする。多くのユーザがこれを最初に実行せずに多くの時間を浪費している。

  • マスタがバイナリログに記録しているかどうか。SHOW MASTER STATUS でチェックする。記録していれば、Position はゼロ以外の値になっている。そうでない場合、マスタに log-bin オプションを設定していること、および server-id を設定していることを確認する。

  • スレーブが実行しているかどうか。SHOW SLAVE STATUS を実行し、Slave_IO_RunningSlave_SQL_Running の値が両方とも Yes であることをチェックする。そうでなければ、スレーブオプションを確認する。

  • スレーブが実行している場合、スレーブがマスタとの接続を確立しているかどうか。SHOW PROCESSLIST を実行し、I/O スレッドと SQL スレッドを見つけ(その表示については、see 項4.11.3. 「レプリケーションの実装の詳細」)、その State カラムをチェックする。Connecting to master であれば、レプリケーションユーザのマスタでの権限、マスタホスト名、DNS 設定、マスタが実際に実行しているかどうか、マスタがスレーブからアクセス可能かどうかを調べる。

  • スレーブが以前は実行していたが現在は停止している場合、その理由は通常、マスタで成功したクエリがスレーブで失敗したことにある。マスタのスナップショットを適切に作成しており、スレーブスレッド外でスレーブのデータを変更していなければ、これは発生しないはずである。発生した場合はバグと考えられるので、次のバグレポートのセクションを参照のこと。

  • マスタで成功したクエリがスレーブでは実行できず、完全データベース再同期(スレーブのデータベースを削除し、マスタの新規スナップショットをコピーする)の実行が難しい場合、以下を試す。

    • 最初に、スレーブのテーブルがマスタのテーブルと異なっていないか確認する。異なっていた場合、どのようにそれが発生したかを見極める。バグの可能性もある。http://www.mysql.com/documentation でオンライン MySQL マニュアルの変更ログを読み、それが既知のバグかどうか、またすでに解決されているものであるかどうか確認する。 次に、スレーブのテーブルをマスタのテーブルと同じなるように変更して、START SLAVE を実行する。

    • 上記のことを行ってもうまく機能しない場合、または上記のことができない場合は、必要に応じて手動で更新し、マスタからの次の更新を無視しても安全かどうかを判断する。

    • 次のクエリをスキップすることに決定した場合、以下のステートメントを発行する。

      mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = n;
      mysql> START SLAVE;
      

      クエリが AUTO_INCREMENT または LAST_INSERT_ID() を使用しない場合、n の値は 1 にする。使用する場合、値は 2 にする。AUTO_INCREMENT または LAST_INSERT_ID() を使用するクエリに 2 の値を使用する理由は、そのクエリはマスタのバイナリログでイベントを 2 つ使用するからである。

    • 最新のバージョンにアップグレードし、古いバグを確実に回避する。

    • スレーブがマスタと完璧に同期して開始し、スレーブスレッド外で誰もテーブルを更新していないと確信がある場合は、バグを報告する。

4.11.11. レプリケーションバグのレポート

ユーザエラーがないにもかかわらずレプリケーションが機能しない、または不安定であると判断したら、当社にバグレポートを送ってください。バグをトラックダウンするために、できるだけ多くの情報が必要です。ある程度の時間と労力を費やしてバグレポートを準備してください。

バグが再現可能な場合、バグデータベース(http://bugs.mysql.com/)に入力してください。ファントム問題(意図的に再現できないもの)がある場合、以下の手順に従います。

  1. ユーザエラーがないことを確認する。たとえば、スレーブをスレーブスレッド外から更新すると、データの同期が失われ、更新でユニークキー違反となる。この場合、スレーブスレッドは停止し、ユーザが手動でクリーンアップして同期を取り戻すのを待つ。これはレプリケーションの問題ではない。レプリケーションを妨害する外部干渉の問題である。

  2. --log-slave-updates オプションおよび --log-bin オプションでスレーブを実行する。これにより、スレーブは受け取った更新を自身のバイナリログに記録する。

  3. レプリケーションの状態をリセットする前に、すべての証拠を保存する。情報がなかったり少ない場合には、問題のトラッキングに時間がかかる。以下のような証拠を収集すること。

    • マスタからのすべてのバイナリログ

    • スレーブからのすべてのバイナリログ

    • 問題発見時のマスタでの SHOW MASTER STATUS 出力

    • 問題発見時のマスタでの SHOW SLAVE STATUS 出力

    • マスタおよびスレーブのエラーログ

  4. mysqlbinlog を使用してバイナリログを調べる。たとえば以下を実行して、問題のあるクエリを見つけることができる。

    shell> mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head
    

ファントム問題の証拠を収集したら、まず個別のテストケースに分類する努力をしてください。その後、バグデータベース(http://bugs.mysql.com/)に、その問題を、できるだけ多くの情報とともに入力します。


This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

アダルトレンタルサーバー