Go to the first, previous, next, last section, table of contents.

# 4 MySQL Database Administration

## 4.1 Configuring MySQL

### 4.1.1 mysqld コマンド行オプション

`mysqld` は次のコマンド行オプションを受け付けます:

`--ansi`
  MySQL 構文の代わりに ANSI SQL 構文を使用します。 「1.4.3 ANSI モードでの MySQL の実行」節参照。
`-b, --basedir=path`
  インストール先ディレクトリのパス。すべてのパスは通常ここからの相対パスで決 定されます。
`--big-tables`
  ファイルにすべての一時セットを保存することにより、大きな結果セットを許しま す。これは、多くの 'table full' エラーを解決します。しかし、メモリ内テーブ ルでも十分なクエリは遅くなります。バージョン 3.23.2 からは、 MySQL は自動的にメモリを使用し、必要なときにディスクテーブルにス イッチすることによって、これを解決します。
`--bind-address=IP`
  bind する IP アドレス。
`--character-sets-dir=path`
  キャラクタ・セット ディレクトリ。 「4.6.1 データとソートに使用されるキャラクターセット」節参照。
`--chroot=path`
  起動中に `mysqld` デーモンを chroot します。推奨されるセキュリティ手法です。 これは `LOAD DATA INFILE` と `SELECT ... INTO OUTFILE` を制限し ます。
`--core-file`
  `mysqld` が死んだ場合 core ファイルを書き出します。いくつかのシステム では、`--core-file-size` も `safe_mysqld` に記述する必要がありま す。 「4.7.2 safe_mysqld, the wrapper around mysqld」節参照.
`-h, --datadir=path`
  データベースルートのパス。
`--default-character-set=charset`
  デフォルト のキャラクタ・セットの設定。 「4.6.1 データとソートに使用されるキャラクターセット」節参照。
`--default-table-type=type`
  テーブルのデフォルトテーブル型を設定する。 「7 MySQL テーブル型」節参照.
`--debug[...]=`
  MySQL が `--with-debug` つきで configure された場合、このオ プション使用して、`mysqld` が何を行なっているかのトレースファイルを得 ることができます。 「G.1.2 Creating trace files」節参照.
`--delay-key-write-for-all-tables`
  任意の `MyISAM` テーブルについて書き込み間でキーバッファをフラッシュ しません。 「5.5.2 サーバーパラメーターのチューニング」節参照.
`--enable-locking`
  システムロックを有効にします。注意: lockd() が完全に働かない(Linux のよう な)システムでこのオプションを使用した場合、mysqld が簡単にデッドロックしま す。
`-T, --exit-info`
  mysqld サーバをデバッグするために使用できる、様々なフラグのビットマスクで す; 何が行なわれるのか正確に知らない場合は、このオプションを使用すべきでは ありません！
`--flush`
  各 SQL コマンド後にすべての変更をディスクにフラッシュします。通常 MySQL は各 SQL コマンドにすべての変更をディスクに書き出すだけで、 OS がディスクへの sync を処理します。 「A.4.1 What To Do If MySQL Keeps Crashing」節参照.
`-?, --help`
  短いへルプを表示して終了します。
`--init-file=file`
  起動時にファイルから SQL コマンドを読み込みます。
`-L, --language=...`
  与えられた言語のクライアントエラーメッセージ。フルパスで与えることもできます。 「4.6.2 Non-English Error Messages」節参照.
`-l, --log[=file]`
  接続とクエリをファイルに記録します。 「4.9.2 The General Query Log」節参照.
`--log-isam[=file]`
  すべての ISAM/MyISAM 変更をファイルに記録します(ISAM/MyISAM のデバッグ時に のみ使用できます)。
`--log-slow-queries[=file]`
  実行に `long_query_time` 秒以上掛かるすべてのクエリをファイルに記録し ます。 「4.9.5 The Slow Query Log」節参照.
`--log-update[=file]`
  更新を `file.#` に記録します。`#` は与えられなければ一意な番号で す。 「4.9.3 更新ログ」節参照.
`--log-long-format`
  更新ログに拡張情報を記録します。`--log-slow-queries` を使用すると、イ ンデックスを使用しないクエリが slow query ログに記録されます。
`--low-priority-updates`
  テーブル変更操作 (`INSERT`/`DELETE`/`UPDATE`) は SELECT よ りも低い優先度になります。あるクエリだけ優先度を低くするには、 `{INSERT | REPLACE | UPDATE | DELETE} LOW_PRIORITY ...` によって行 なわれます。また、ひとつのスレッドの優先度を変更するには、`SET OPTION SQL_LOW_PRIORITY_UPDATES=1` で行なわれます。 「5.3.2 テーブル・ロッキングの問題」節参照.
`--memlock`
  メモリに `mysqld` プロセスをロックします。これはシステムが `mlockall()` システムコールをサポートしている時(Solaris のように)にだけ動作します。これ は、OS が `mysqld` をディスク上にスワップさせる問題がある場合の助けに なります。
`--myisam-recover [=option[,option...]]] where option is any combination`
  of `DEFAULT`, `BACKUP`, `FORCE` or `QUICK`. このオプションを使用すると、`mysqld` はオープン時にテーブルがクラッシュ したとマークされているかどうか、テーブルが適切にクローズされていないかどう かチェックします。(最後のオプションは `--skip-locking` で起動している 場合にだけ働きます)。If this is the case `mysqld` will run check on the table. テーブルが壊れている場合、`mysqld` はその修復を試みます。 次のオプションは修復の動作に影響します：

  DEFAULT | `--myisam-recover` にオプションを与えないのと同じです。
  BACKUP | データテーブルが修復中に変更された場合、 ``table_name.MYD'` データファイルのバックアップを ``table_name-datetime.BAK'` に保存します。
  FORCE | .MYD ファイルからひとつより多くのレコードが失われている 場合でも修復を実行します。
  QUICK | 削除ブロックがない場合にテーブル内のレコードをチェック しません。

  テーブルが自動的に修復される前に、MySQL はエラーログにこれについ てのメモを追加します。ユーザの介入なしで多くのことを修復したい場合は、オプ ション `BACKUP,FORCE` を使用すべきです。いくつかのレコードが削除され る場合でも、テーブルを強制的に修復しますが、古いデータファイルをバックアッ プとして保存するため、あとで何が起こったか検証できます。
`--pid-file=path`
  `safe_mysqld` によって使用される pid ファイルのパス。
`-P, --port=...`
  TCP/IP 接続で listen するポート番号。
`-o, --old-protocol`
  とても古いクライアントとの互換のために、3.20 プロトコルを使用します。 「2.5.3 バージョン 3.20 から バージョン 3.21 へのアップグレード」節参照.
`--one-thread`
  一つのスレッドだけを使用します(Linux 下でデバックするため)。 「G.1 MySQL server のデバッグ」節参照.
`-O, --set-variable var=option`
  変数に値を与えます。`--help` は変数をリストします。すべての変数の完全 な詳細はこのマニュアルの `SHOW VARIABLES` 節で見られます。 「4.5.5.4 `SHOW VARIABLES`」節参照。サーバパラメータの調整についての節はこれらの最適化 方法の情報を含んでいます。 「5.5.2 サーバーパラメーターのチューニング」節参照.
`--safe-mode`
  いくつかの最適化ステージをスキップします。`--skip-delay-key-write` を 含みます。
`--safe-show-database`
  ユーザが権限を何も持っていないデータベースを表示しません。
`--safe-user-create`
  If this is enabled, a user can't create new users with the GRANT command, if the user doesn't have `INSERT` privilege to the `mysql.user` table or any column in this table.
`--skip-concurrent-insert`
  同時に `MyISAM` テーブルに select と insert を行なう機能をオフにしま す。(この機能にバグを見つけたと考える場合にだけ使用します)。
`--skip-delay-key-write`
  すべてのテーブルに対し `delay_key_write` オプションを無視します。 「5.5.2 サーバーパラメーターのチューニング」節参照.
`--skip-grant-tables`
  このオプションは、サーバをすべての権限システム使用しないようにします。これ は全員にすべてのデータベースへの完全アクセスを与えます！ (`mysqladmin flush-privileges` や `mysqladmin reload` を実行する ことで、権限テーブルを使用して起動するように実行中のサーバに伝えることがで きます。)
`--skip-host-cache`
  より速いホスト名-IP解決のためのホスト名キャッシュを使用しません。代わりに すべての接続で DNS サーバへクエリします。 「5.5.5 How MySQL uses DNS」節参照.
`--skip-locking`
  システムロックを使用しません。`isamchk` または `myisamchk` を使 用するためには、サーバをシャットダウンする必要があります。 「1.1.7 MySQL はどれくらい安定か？」節参照。注意: MySQL バージョン 3.23 では、 `REPAIR` と `CHECK` を `MyISAM` テーブルの修復／チェックに 使用できます。
`--skip-name-resolve`
  ホスト名を解決しません。権限テーブルのすべての `Host` フィールド値は IP 番号か `localhost` でなければなりません。 「5.5.5 How MySQL uses DNS」節参照.
`--skip-networking`
  TCP/IP 接続の listen をまったく行ないません。`mysqld` との接続には UNIX ソケット経由で行なう必要があります。このオプションはローカル要求だけ を許可するシステムでは、高く推奨されます。 「5.5.5 How MySQL uses DNS」節参照.
`--skip-new`
  Don't use new, possible wrong routines. Implies `--skip-delay-key-write`. This will also set default table type to `ISAM`. 「7.3 ISAM Tables」節参照.
`--skip-symlink`
  Don't delete or rename files that a symlinked file in the data directory points to.
`--skip-safemalloc`
  MySQL が `--with-debug=full` で configure されている場合、す べてのプログラムがすべてのメモリ割り当てとメモリ解放をオーバーラン用にチェッ クします。このチェックはとても遅いので、メモリチェックが不要な場合、このオ プションを使用することでこれを無効にできます。
`--skip-show-database`
  process 権限を持っていないユーザに 'SHOW DATABASE' コマンドを許し ません。
`--skip-stack-trace`
  スタックトレースを書き出しません。このオプションは、`mysqld` をデバッ ガ下で実行している時に有用です。 「G.1 MySQL server のデバッグ」節参照.
`--skip-thread-priority`
  より速いレスポンスタイム用のスレッド優先度の使用を無効にします。
`--socket=path`
  デフォルト `/tmp/mysql.sock` の代わりに、ローカル接続用に使用されるソ ケットファイル。
`--sql-mode=option[,option[,option...]]`
  Option can be any combination of: `REAL_AS_FLOAT`, `PIPES_AS_CONCAT`, `ANSI_QUOTES`, `IGNORE_SPACE`, `SERIALIZE`, `ONLY_FULL_GROUP_BY`. It can also be empty (`""`) if you want to reset this. By specifying all of the above options is same as using --ansi. With this option one can turn on only needed SQL modes. 「1.4.3 ANSI モードでの MySQL の実行」節参照.
`transaction-isolation= { READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE }`
  Sets the default transaction isolation level. 「6.7.3 `SET TRANSACTION` 構文」節参照.
`-t, --tmpdir=path`
  一時ファイル用のパス。デフォルトの `/tmp` ディレクトリが一時テーブル を保持するのに小さすぎるパーティション上にある場合に有用です。
`-u, --user=user_name`
  ユーザ `user_name` で `mysqld` デーモンを実行します。このオプショ ンは、`mysqld` を root で起動した時に 強制されます。
`-V, --version`
  バージョン情報を出力して終了します
`-W, --warnings`
  `Aborted connection...` のような警告を `.err` ファイルに出力しま す。 「A.2.9 Communication Errors / Aborted Connection」節参照.

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

MySQL バージョン 3.22 のサーバー、クライアントともに、 オプションファイルからデフォルトの起動オプションを読み込むことができます。

UNIX では MySQL は以下のファイルからデフォルトオプションを読みます：

ファイル名 | 意味
`/etc/my.cnf` | 全体のオプション
`DATADIR/my.cnf` | サーバ固有オプション
`defaults-extra-file` | --defaults-extra-file=# で指定されたファイル
`~/.my.cnf` | ユーザ固有オプション

`DATADIR` は MySQL データディレクトリです (普通 バイナリ配布では ``/usr/local/mysql/data'` 、ソース配布では ``/usr/local/var'`). このディレクトリはconfigure時に決定されており、 `--datadir` を `mysqld` 起動時に指定しても変更されません。 (サーバーはコマンドラインの引数を処理する前にオプションファイルを探します。 よって、`--datadir` 引数を指定してもオプションファイルを探す場所を指定することにはなりません。)

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

ファイル名 | 意味
`windows-system-directory\my.ini` | Global options
`C:\my.cnf` | 全体のオプション
`C:\mysql\data\my.cnf` | サーバ固有オプション

注意: Windows では `\` の代わりに `/` で全てのパスを記述すべきで す。`\` を使用する場合、`\` は MySQL のエスケープ文字 なので、これを二重に記述する必要があります。

MySQL は上記の表にかかれている順にオプションファイルを読みます。 もし複数オプションファイルがあった場合、後から読まれた設定が有効になります。 全てのオプションはコマンドラインの引数に上書きされます。 いくつかのオプションは環境変数に定義できます。 オプションファイルとコマンドラインの引数は環境変数を上書きします。 「H Environment Variables」節参照.

次のプログラムはオプションファイルをサポートします： `mysql`, `mysqladmin`, `mysqld`, `mysqldump`, `mysqlimport`, `mysql.server`, `myisamchk`, and `myisampack`.

オプションファイルには、プログラムがサポートしているコマンドラインの long オプション(例えば、`-u` ではなくて `--user` の方)を書くことができます。 プログラムを `--help` で起動すれば、設定可能な変数名が得られます。

オプションファイルの書式は以下です：

`#comment`
  コメントは ``#'` か ``;'` 文字で始めます。空の行は無視します。
`[group]`
  グループ宣言。 `group` はオプションを定義するプログラムかグループの名前です。 この宣言の後、`オプション` か `set-variable` 行で、このグループにオプションを与えます。 このセクションの範囲は、他のグループ宣言の行が来るか、ファイルの最後に来るまでです。
`option`
  これはコマンドラインの `--option` と等価です。
`option=value`
  これはコマンドラインの `--option=value` と等価です。
`set-variable = variable=value`
  これはコマンドラインの `--set-variable variable=value` と等価です。 これは `mysqld` 変数で使用される形式です。

`client` グループは、全ての MySQL クライアント(`mysqld`は除)に対してオプションを定義します。 これはサーバーに接続する際に使用するパスワードを指定できるグループです。 (この場合、オプションファイルは自分だけが読み書きできるようにしてください)

オプションや値の善後にある全てのブランク文字は自動で取り除かれます。 値として、``\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]
    # The following password will be sent to all standard MySQL clients
    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 がインストールされたディレクトリのパス名で、 普通は ``/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-defualts`は `--defaults-xxx-file` コマンドの直後 にも置けます。

開発者向け情報：　オプションファイルの操作は全てのオプションをコマンドラインの 引数より先に処理するように簡単に埋め込まれています。 これはオプションを最後に処理するプログラムを複数立ちあげる場合に都合よく動きます。 もしオプションファイルを読み込む機能のない古いプログラムを使用しているなら、 たった二行だけ注意して書けばいいだけです。 この動作については MySQL クライアントプログラムのコードを参考にしてください。

シェルスクリプト内では、``my_print_defaults'` コマンドを使用して、コ ンフィグファイルを解析することができます:

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

上記は、'client' と 'mysql' グループ用の全オプションを出力します。

### 4.1.3 同じマシンに多くのサーバをインストールする

同じマシン上で多くの異なる `mysqld` デーモン(サーバ)を動作させたい場 合があります。例えば、テスト用に `MySQL` の新しいバージョンを使用中の 古いバージョンと共に実行したい場合や、異なる `mysqld` サーバにそれを管理する 異なるユーザアクセスを与えたい場合などです。

一つの方法は、新しいサーバを次のように異なるソケットとポートで起動すること です:

    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/safe_mysqld &

The environment variables 付録は `mysqld` に影響する他の環境変数の 一覧を含んでいます。 「H Environment Variables」節参照.

The above is the quick and dirty way that one commonly uses for testing. The nice thing with this is that all connections you do in the above shell will automatically be directed to the new running server!

If you need to do this more permanently, you should create an option file for each server. 「4.1.2 my.cnf オプションファイル」節参照. In your startup script that is executed at boot time (mysql.server?) you should specify for both servers:

`safe_mysqld --default-file=path-to-option-file`

少なくとも、次のオプションはサーバごとに異なるようにすべきです:

`port=#`
`socket=path`
`pid-file=path`

次のオプションが使用される場合、異なるようにすべきです:

`log=path`
`log-bin=path`
`log-update=path`
`log-isam=path`
`bdb-logdir=path`

さらに性能を求める場合、次も異なるように記述できます:

`tmpdir=path`
`bdb-tmpdir=path`

「4.1.1 mysqld コマンド行オプション」節参照.

バイナリの MySQL バージョン (.tar ファイル) をインストールして、 `./bin/safe_mysqld` で起動する場合、多くの場合では、追加/変更する必要 のあるオプションは `safe_mysqld` への `socket` と `port` 引 数だけです。

### 4.1.4 同一マシン上に複数の MySQL サーバーを走らせる

同じマシン上で複数のサーバーを走らせたい場合があります。 例えば、すでに存在しているサーバーはそのままにしておいて、新しい MySQL をテストしたい場合や、 あるいは、インターネットプロバイダーを営んでいて、MySQL をそれぞれの顧客用に提供したい場合など。

複数のサーバーをたちあげる場合、簡単な方法として、 TCP/IP ポート、ソケットファイルを変えて、サーバーをコンパイルする方法があります。 「4.7.3 mysqld_multi, program for managing multiple MySQL servers」節参照.

そでに走っているサーバーがデフォルトのポート番号とソケットファイルで動作しているとします。 新しくサーバーを作るには、以下のように `configure` します：

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

`port_number` と `file_name` には、デフォルトのポート番号、 ソケットファイルとは違うものを指定します。 そして `--prefix` を、すでに走っている MySQL の インストール先とは違うディレクトリーに指定します。

現在走っている MySQL サーバーが使用している ソケットとポートをチェックするには、以下のようにします：

    shell> mysqladmin -h hostname --port=port_number variables

Note that if you specify ```localhost`'' as a hostname, `mysqladmin` will default to using Unix sockets instead of TCP/IP.

あなたが使用しているポートに MySQL サーバーが走っていれば、 これは変更可能な MySQL 変数を(ソケットファイルの名前も含んで)出力します。

この場合、 MySQL サーバーを再コンパイルする必要はありません。 `safe_mysqld` のオプションを指定してサーバーを起動すれば、 ポートとソケットを変更できます：

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

`mysqld_multi` can also take `safe_mysqld` (or `mysqld`) as an argument and pass the options from a configuration file to `safe_mysqld` and further to `mysqld`.

もし、他のサーバーがロギングを行っているディレクトリと同じデータベースディレクトリを、 新しいサーバーで使用するのであれば、ログファイルの名前を指定すべきです。 ( `safe_mysqld` に `--log` , `--log-update` , `--log-slow-queries` を指定する) そうしないと、両方のサーバーが同じログファイルに書き込もうとするからです。

WARNING: 通常、二つサーバーに同じデータベースを操作させてはいけません！ もし使用している OS が fault-free system locking をサポートしていないと、 これは悲惨なことになるでしょう！

もし二つ目のサーバーに違うデータベースディレクトリを使用させたい場合、 `safe_mysqld` に `--datadir=path` オプションを指定します。

NOTE also that starting several MySQL servers (`mysqlds`) in different machines and letting them access one data directory over `NFS` is generally a BAD IDEA! The problem is that the `NFS` will become the bottleneck with the speed. It is not meant for such use. And last but not least, you would still have to come up with a solution how to make sure that two or more `mysqlds` are not interfering with each other. At the moment there is no platform that would 100% reliable do the file locking (`lockd` daemon usually) in every situation. Yet there would be one more possible risk with `NFS`; it would make the work even more complicated for `lockd` daemon to handle. So make it easy for your self and forget about the idea. The working solution is to have one computer with an operating system that efficiently handles threads and have several CPUs in it.

もし違うポートで走っている MySQL サーバーに、 これまた違うポートを使用するように作られたクライアントから接続したい場合、 以下のようにします：

- クライアントを TCP/IP での接続 `--host 'hostname' --port=port_numer` か UNIX ソケット経由での接続 `[--host localhost] --socket=file_name` オプションで起動します。
- C あるいは Perl プログラムの場合、ポートとソケットを与えることができます：
- If your are using the Perl `DBD::mysql` module you can read the options from the MySQL option files. 「4.1.2 my.cnf オプションファイル」節参照.

      $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);

- `MYSQL_UNIX_PORT` と `MYSQL_TCP_PORT` 環境変数に UNIX ソケットファイルと TCP/IP のポート番号とセットし、クライアントを立ちあげます。 もし、このポート番号やソケットファイルを常に使用するのであれば、 ``.login'` ファイルかなにかに環境変数をセットするように書いておけばよいでしょう。 「H Environment Variables」節参照.
- あなたのホームディレクトリの ``.my.cnf'` ファイルに、 通常使用するポート番号とソケットファイルを書くこともできます。 「4.1.2 my.cnf オプションファイル」節参照.

## 4.2 General Security Issues and the MySQL Access Privilege System

MySQL has an advanced but non-standard security/privilege system. This section describes how it works.

### 4.2.1 General Security Guidelines

よくあるセキュリティの間違いを避けるために、インターネットに接続されたコン ピュータ上で MySQL を使用する誰もが、このセクションを読むべきです。

``セキュリティ'' の議論において、我々は、すべての該当するアタックタイプ (eavesdropping, altering, playback, Denial of Service) に対して、すべてのサー バホスト(MySQL サーバだけではなく)の完全な保護の必要性を強調しま す。We do not cover all aspects of availability and fault tolerance here.

MySQL は、ユーザが実行しようとするすべての接続、クエリ、その他の オペレーションに対して、アクセス制御リスト(ACLs: Access Control Lists)セキュ リティを使用します。MySQL クライアントとサーバの間で SSL 暗号化接 続のサポートもいくつかあります。ここで議論されるコンセプトの多くは、 MySQL に特有のものではありません; 同じ一般的なアイデアはほとんど すべてのアプリケーションに適用します。

MySQL 実行時、可能な限りいつでもこれらのガイドラインに従ってくだ さい:

- (MySQL ROOT ユーザ以外の)誰にも `mysql` データベース内の `user` テーブルへのアクセスを与えないでください！ 暗号化されたパスワー ドは MySQL の本当のパスワードです。もしあなたが与えられたユーザに ついて `user` テーブルにリストされたパスワードを知ることができれば、 そのアカウントについてリストされたホストへアクセスすれば、あなたは簡単にそ のユーザとしてログインできます。
- MySQL ACL システムの理解に努めるべきです。 `GRANT` と `REVOKE` コマンドは MySQL へのアクセスを制限するための物です。 必要以上の権限を誰にも与えないでください。 全てのホストに対して、何か出来るような許可を与えてはいけません。 Checklist:
  - `mysql -u root` を行ってみます。 パスワードを尋ねられること無しにサーバへの接続ができる場合、問題があります。 どのユーザでも(root でなくても)、MySQL サーバに完全な権限で接続で きます！ `root` パスワードの設定についての項目に特別な注意を払って MySQL インストール説明を見直してください。
  - `SHOW GRANTS` を使用し、だれがなんのアクセスを持つかチェックします。 必要ない権限を、`REVOKE` コマンドを使用して削除してください。
- いかなる平文パスワードもデータベースに保存しないようにします。 あなたのコンピュータが妥協される時、新入者はパスワードの完全なリストを得て、 それらを使用できます。代わりに `MD5()` や他の one-way hashing 関数を 使用してください。
- 辞書からパスワードを選んではいけません。 それらを破る プログラムがあるのです。 ``xfish98'' のようなパスワードは悪い例です。 これよりは ``duag98'' の方がよいでしょう。 これは "fish" を打つ際に、 キーを一つずつずらしたものです。 他の方法としては、 "Mhall" 、これは "Mary had a little lamb" という文の頭文字を羅列したものです。 これを知っている物には打ちやすいパスワードですが、知らない者にとっては、 類推することが難しいパスワードです。
- ファイアーウォールを導入します。This protects you from at least 50% of all types of exploits in any software. MySQL をファイアーウォール で守られた方に置くか、DMZ (緩衝地帯, 非武装地帯) に置きます。 Checklist:
  - インターネットから `nmap` のようなツールを使用して、 あなたのマシンのポートをスキャンしてみます。 MySQL はデフォルトで 3306 番を使用しています。 このポートには信用できないホストからはアクセスできないようにすべきです。 MySQL ポートがオープンしているかどうかをチェックする他の簡単な方 法は、次のコマンドをいくつかのリモートマシンから試すことです。ここで `server_host` はあなたの MySQL サーバのホスト名です:

        shell> telnet server_host 3306

    接続し、いくつかのゴミ文字が得られた場合、ポートはオープンして います。それをオープンしておく正当な理由が本当にない限り、ファイアーウォー ルやルータでクローズすべきです。`telnet` がハングしたり拒否されたり する場合、すべて OK です。ポートはブロックされています。
- ユーザーから入力されたデータは信頼しないで下さい。 ユーザーは、Webのフォーム、URL、あるいはあなたのカスタムプログラムから 特定の文字を入れることが可能です。 もしユーザーがフォームに `; DROP ALL DATABASES ;` のような文字を入力しても、 あなたのアプリケーションは安全ですか？ これは極端な例ですが、それらに対して準備しない場合、似たようなテクニックを 使用するハッカーの結果として、大きなセキュリティリークとデータ喪失が発生し 得ます。 数値データのチェックも忘れないでください。よくある間違いは文字列しか保護し ないことです。時々、人はデータベースが保護される必要のない公に有効なデータ だけを含んでいるかどうかを考えます。これは間違いです。少なくとも、 denial-of-service タイプのアタックはそのようなデータベースでも実行されます。 このタイプのアタックから保護するもっとも簡単な方法は、数値定数の回りにアポ ストロフィを使用することです: `SELECT * FROM table WHERE ID=234` の代 わりに `SELECT * FROM table WHERE ID='234'`。MySQL は自動的 にこの文字列を数値に変換し、そこからすべての非数値シンボルを取り除きます。 Checklist:
  - すべての Web アプリケーション:
    - あなたの WWW の全てのフォームに、``''` と ``"'` を入力することを試みてください。 もしなんらかの MySQL エラーがでたら、あなたのサイトを停止したほうが よいでしょう。
    - あなたの URL に `%22` (``"'`), `%23` (``#'`) , `%27` (``''`) をつけてみて、動的URLを いろいろ変更して試してみてください。
    - 動的 URL のデータタイプを数値から上述の例の文字を含む文字列に修正してみて ください。アプリケーションはこれと似たようなアタックに対して安全であるべき です。
    - 数値フィールドに対して、文字、スペース、特殊文字の入力を試みてください。 アプリケーションは、それらを MySQL に送る前に取り除くか、 あるいはエラーを出すべきです。 検査しない値を MySQL に送ることは危険です。
    - MySQL にデータを送る前に、そのサイズをチェックします。
    - あなたのアプリケーションが、管理目的であなたが使用するのと異なるユーザ名を 使用してデータベースに接続することを考慮してください。必要以上のアクセス権 をアプリケーションに与えないで下さい。
  - Users of PHP:
    - Check out the `addslashes()` function. As of PHP 4.0.3, a `mysql_escape_string()` function is available that is based on the function of the same name in the MySQL C API.
  - Users of MySQL C API:
    - Check out the `mysql_escape_string()` API call.
  - Users of MySQL++:
    - Check out the `escape` and `quote` modifiers for query streams.
  - Users of Perl DBI:
    - Check out the `quote()` method or use placeholders.
  - Users of Java JDBC:
    - Use a `PreparedStatement` object and placeholders.
- 生のデータ(暗号化されていないデータ)をインターネット越しに送ってはいけませ ん。このデータは、その情報をトラップして、どこかで再利用することに興味のあ る誰にでもアクセス可能です。もし送る必要があるなら、SSL のような暗号化され た通信を使用すべきです。MySQL はバージョン 3.23.9 から内部 SSL 接 続をサポートします。暗号化された(そして圧縮された)通信のトンネルを生成する ために、SSH ポートフォワーディングを使用することができます。
- "tcpdump", "strings" ユーティリティを使うことを学んで下さい. 以下のコマンドで、ほとんどの場合、暗号化されていない MySQL のデータが見えるでしょう：

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

  (この例は Linux のものです。他のシステムでは少し違うでしょう). 警告: データが見えなくても、実際に常に暗号化されているわけではありません。 高いセキュリティが必要なら、セキュリティエキスパートに相談すべきです。

### 4.2.2 MySQL をクラッカーに対して安全にする方法

MySQL サーバーに接続するときは、パスワードを使用すべきです。 パスワードはコネクション間で、べたテキストでは流れません。 しかし、暗号化アルゴリズムはそんなに強力なわけではありません。クライアント とサーバ間のトラフィックを sniff できれば、いくつかの試みで、賢いアタッカー はパスワードをクラックできます。クライアントとサーバ間の接続が信頼できない ネットワークを通るなら、通信を暗号化するために SSH トンネルを使用 すべきです。

その他の全ての情報はテキストで転送され、 これは接続を覗くことが出来る人に読まれます。 もしこれを心配するなら、圧縮プロトコル(MySQL バージョン 3.22 以上)を 使用することが出来ます。より安全にしたい場合、 `ssh` をインストールすべきです。 オープンソースの `ssh` クライアントは http://www.openssh.org に、 商用の `ssh` クライアントは http://www.ssh.com に見ることができます。 これを使用すれば、MySQL サーバーと MySQL クライアント 間の TCP/IP コネクションは全て暗号化されます。 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 デーモンを UNIX の `root` ユーザーで実行しないでください。 `FILE`権限を持つ任意のユーザが `root` としてファイル(例えば、 `~root/.bashrc`)を生成できるためとても危険です。これを防ぐために、 `mysqld` は、`--user=root` オプションで直接指定されない限り、 `root` としての実行を拒否します。 代わりに `mysqld` は権限を持たない一般ユーザとして実行できます。 より安全にするため、新しく UNIX ユーザ `mysql` を追加することもできます。 `mysqld` を 他の Unix ユーザーで起動したとしても、 MySQL の `user` テーブルの `root` ユーザーの名前を変更する必要はありません。 なぜなら、 MySQL ユーザーの名前は Unix のユーザー名とはなんの関係もないからです。 root ユーザ名を変更する必要はありません。 `mysqld` を他の UNIX ユーザで起動するためには、``/etc/my.cnf'` オ プションファイルまたはサーバのデータディレクトリの ``my.cnf'` オプショ ンファイルの、`[mysqld]` グループにユーザ名を記述した `user` 行 を追加してください。たとえば:

      [mysqld]
      user=mysql

  これは、あなたが手動で起動したり `safe_mysqld` または `mysql.server` を使用して起動しても、指定されたユーザでサーバを起動さ せます。詳細は、 「A.3.2 一般ユーザで MySQL を動かす方法」節 を見てください。
- Don't support symlinks to tables (This can be disabled with the `--skip-symlink` option. This is especially important if you run `mysqld` as root as anyone that has write access to the mysqld data directories could then delete any file in the system! 「5.6.1.2 Using Symbolic Links for Tables」節参照.
- データベースディレクトリは `mysqld` を実行している UNIX ユーザだけが 読み込み／書き込み可能なことをチェックしてください。
- process 権限を全てのユーザに与えないでください。この許可がある人は誰でも `mysqladmin processlist` コマンドで実行されているクエリーの中身を見ることができます。 もし誰かが、`UPDATE user SET password=PASSWORD('not_secure')` クエリーを 実行していたとして、それが見えてしまいます。 `mysqld` は process 権限を持つユーザに対する特別な接続をリザーブします。 そのため、たとえ全ての通常接続が使われたとしても、MySQL `root` ユーザだけは、 ログインでき、いろいろチェックできます。
- file を全てのユーザに与えないでください。ユーザがこの権限を持つ場 合、`mysqld` デーモンを実行している Unix ユーザーの権限で ファイルシステム内のどこにでもファイルを書き込むことができます！ これを少し安全にするために、`SELECT ... INTO OUTFILE` で作成される全てのファイルは 全員に読み込み可能で生成され、既存のファイルには上書きできません。 file 権限はサーバーを走らせている UNIX ユーザーがアクセスできる 全てのファイルを読むために使用されかもしれません。 例えば、 ``/etc/passwd'` をテーブルに取り込むために `LOAD DATA` が 使用されると、 `SELECT` でその内容が読めることになります。
- あなたの DNS を信用しない場合、権限テーブル内にはホスト名の代わりに IP を使用すべきです。`mysqld` への `--secure` オプションは原理上はホスト名を安 全にします。どんな場合でも、ワイルドカードを含んだホスト名を、許可テーブルに登録する 事は本当に注意深くすべきです！
- 一ユーザからの接続数を制限したい場合は、`mysqld` の `max_user_connections` 変数を設定することで、これを行なうことができま す。

### 4.2.3 セキュリティに関する `mysqld` の起動オプション

`mysqld` の次のオプションはセキュリティに影響します:

`--safe-show-database`
  With this option, `SHOW DATABASES` returns only those databases for which the user has some kind of privilege.
`--safe-user-create`
  If this is enabled, an user can't create new users with the `GRANT` command, if the user doesn't have `INSERT` privilege to the `mysql.user` table. If you want to give a user access to just create new users with those privileges that the user has right to grant, you should give the user the following privilege:

      GRANT INSERT(user) on mysql.user to 'user''hostname';

  This will ensure that the user can't change any privilege columns directly, but has to use the `GRANT` command to give privileges to other users.
`--skip-grant-tables`
  特権システムを全く使用しません。これは全員に全てのデータベースへの 完全なアクセス を与えます！ (`mysqladmin flush-privileges` か `mysqladmin reload` を実行することで、 起動しているサーバーは特権システムを使用するようになります。)
`--skip-name-resolve`
  ホスト名を解析しません。権限テーブル中の全ての `Host`フィールドは IP アドレスか `localhost` でなければなりません。
`--skip-networking`
  ネットワーク (TCP/IP) 経由の接続を許可しません。`mysqld` への全ての接続は、 UNIX ソケットで行われます。MIT-pthreads は UNIX ソケットをサポートしない ため、このオプションは MIT-pthreads を使用するシステム上では、うまく動きません。
`--skip-show-database`
  このオプションを指定すると、`SHOW DATABASE` コマンドは何も返しません。

### 4.2.4 特権システムの行うこと

MySQL 特権システムの基本機能は、与えられたホストから接続する ユーザを認証すること、そしてデータベースに対する select, insert, update, delete 等の権限を与えることです。

拡張機能は匿名ユーザをもつ能力を含み、`LOAD DATA INFILE` のような MySQL 固有の機能を使用する許可を与えます。

### 4.2.5 特権システムはどのように動くか？

MySQL の特権システムは、全てのユーザーが与えられた許可の範囲内で動く事を保証します。 MySQL サーバーに接続するとき、本人の身元は、接続元のホスト と 接続に使用するユーザー名 によって確認されます。 このシステムは、あなたの身元とあなたが要求することが何か によって、権限を与えます。

MySQL はあなたのホスト名とユーザー名の両方をあわせてチェックします。 これはインターネット上に同じ名前のユーザーがどこかにいるかもしれないということからそうしています。 例えば、`whitehouse.gov` から接続してきた `bill` と、 `microsoft.com` から接続してきた `bill` は同一人物である必要はありません。 MySQL はこの違うホストから接続してきた同名のユーザーを以下のようにして扱います： `whitehouse.gov` から接続した `bill` にある許可をあたえ、 それとは違う許可を `microsoft.com` から接続してきた `bill` に与えます。

MySQL のアクセスコントロールは以下の二つからなります：

- Stage 1: サーバーは接続許可があるかどうかをチェックします。
- Stage 2: 接続許可後、サーバーはそれぞれのリクエストをチェックします。 あなたが要求してきた事柄を、あなたが実行できるかどうかをチェックします。 例えば、あるデータベースのテーブルの行の取り出しやテーブルの破棄をあなたが命令した場合、 サーバーは、あなたにそのテーブルに対する select 許可があるのか、 データベースに対して drop する許可が与えられているのか、を確認します。

サーバーは `mysql` データベースの `user`, `db`, `host` ３つのテーブルから、 この２つのアクセス制限を決定します。 このテーブルのフィールドは以下のようになっています：

Table name | `user` | `db` | `host`
Scope fields | `Host` | `Host` | `Host`
| `User` | `Db` | `Db`
| `Password` | `User` |
Privilege fields | `Select_priv` | `Select_priv` | `Select_priv`
| `Insert_priv` | `Insert_priv` | `Insert_priv`
| `Update_priv` | `Update_priv` | `Update_priv`
| `Delete_priv` | `Delete_priv` | `Delete_priv`
| `Index_priv` | `Index_priv` | `Index_priv`
| `Alter_priv` | `Alter_priv` | `Alter_priv`
| `Create_priv` | `Create_priv` | `Create_priv`
| `Drop_priv` | `Drop_priv` | `Drop_priv`
| `Grant_priv` | `Grant_priv` | `Grant_priv`
| `References_priv` |  |
| `Reload_priv` |  |
| `Shutdown_priv` |  |
| `Process_priv` |  |
| `File_priv` |  |

アクセスコントロールの第2段階(要求承認)のために、サーバーはこれら 3 つの テーブルによって決められた許可を基本としますが、もしテーブルに対する要求で あるならば、`tables_priv` と `columns_priv` テーブルを さらに調べます。これらのテーブルのフィールドは以下のようになっています：

Table name | `tables_priv` | `columns_priv`
Scope fields | `Host` | `Host`
| `Db` | `Db`
| `User` | `User`
| `Table_name` | `Table_name`
|  | `Column_name`
Privilege fields | `Table_priv` | `Column_priv`
| `Column_priv` |
Other fields | `Timestamp` | `Timestamp`
| `Grantor` |

テーブルの各フィールドを分類すると、２種類にわかれます： 適用範囲を指定するフィールド(以下　スコープフィールド)と許可を定義するフィールド(以下　権限フィールド)です。

スコープフィールドは、権限テーブルの登録ごとに、その適用範囲を決めます。 例えば、 `user` テーブルの `Host` と `User` に `'thomas.loc.gov'` と `'bob'` が登録されている場合、 サーバーへの接続は ホスト `thomas.loc.gov` から来た `'bob'` に許可されます。 同様に、`db` テーブルの `Host`, `User`, `Db` に `'thomas.loc.gov'`, `'bob'`, `'reports'` が登録されていると、 ホスト `thomas.loc.gov` から来た `bob` に対し `reports` データベースへの接続が許されます。 `tables_priv` と `columns_priv` テーブルは、 テーブルか、テーブルとフィールドを対にしたスコープフィールドを含みます。

アクセスのチェックは、`Host` の値はケース非依存で比較されます。 `User`, `Password`, `Db`, `Table_name` の値はケース依存で比較されます。 `Column_name` の値は MySQL バージョン 3.22.12 以上ではケース非依存で比較されます。 (バージョン 3.22.11 までは ケース依存です)

権限フィールドは、テーブルに登録されることにより有効になった許可をしめし、 これはどの操作が実行できるかを示します。 サーバーは許可テーブルの情報をユーザーの権限を得るためにまとめます。 このユーザーの権限許可を割り出す方法は 「4.2.9 Access Control, Stage 2: Request Verification」節 に述べておきます。

スコープフィールドは文字で定義され、デフォルト値は空文字になっています：

Field name | Type
`Host` | `CHAR(60)`
`User` | `CHAR(16)`
`Password` | `CHAR(16)`
`Db` | `CHAR(64)` | (`CHAR(60)` for the `tables_priv` and `columns_priv` tables)
`Table_name` | `CHAR(60)`
`Column_name` | `CHAR(60)`

`user`, `db`, `host` テーブルでは、 全ての権限フィールドは `ENUM('N','Y')` で定義されます。 この値は `'N'` か `'Y'` のどちらかで、デフォルト値は `'N'` です。

`tables_priv` と `columns_priv` テーブルでは、 権限フィールドは `SET` フィールドとして定義されます：

Table name | Field name | Possible set elements
`tables_priv` | `Table_priv` | `'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'`
`tables_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`
`columns_priv` | `Column_priv` | `'Select', 'Insert', 'Update', 'References'`

サーバーは以下のように権限テーブルを使用します：

- `user` テーブルのスコープフィールドは、接続要求を受け入れるか拒否するかを決定します。 許可された接続について、`user` テーブルで与えられたすべての権限は、ユー ザのグローバル(スーパーユーザ)権限を示します。この権限はサーバ上の すべての データベースに適用されます。 (訳注： 例えば、`user` テーブル の権限を `'Y'` にした場合、 どんなに `db` テーブルや `host` テーブルで権限を `'N'` にしたとしても 権限は `'Y'` のままである。 ようは `user` テーブルの権限許可 `'Y'` が全てに反映されてしまうという事。 `user` テーブルには最低限の許可を与えるようにし、 `db` テーブルや `host` テーブルで、それぞれの権限許可を定義する方が無難。 )
- `db` と `host` テーブルは一緒に使用されます：
  - `db` テーブルのスコープフィールドはどのホストからどのデータベースのアクセスできるかを決定します。 権限フィールドは、どういった操作ができるか定義します。
  - `host` テーブルは、`db` テーブルの登録をいくつかのホストに与えたい時に、 `db` テーブルの拡張として使用されます。 例えば、ネットワーク上の限定したマシンからデータベースを使用したい場合、 `db` テーブルの `Host` の値は空にしておきます。 そして `host` テーブルにそれぞれのホストについての登録を行います。 この機構は、 「4.2.9 Access Control, Stage 2: Request Verification」節 で詳細に述べられています。
- `tables_priv` と `columns_priv` テーブルは `db` テーブルに似ていますが、 それらはより細かく定義できます； データベースレベルではなく、テーブルとフィールドのレベルで与えます。

管理者権限 (reload, shutdown,など) は `user` テーブルにだけ定義するように。 これは、管理者操作はデータベースではなくサーバーへの操作であり、 他の許可テーブルにある必要がないからです。 またこうしておくと、管理者操作の許可は、`user` テーブルの定義だけを 見ればわかるようになります。

file 操作の権限は `user` テーブルにだけ定義するように。 これは管理者操作ではありませんが、アクセスしているデータベースにかかわらず、 サーバー内のファイルを読み書きできるのです。

`mysqld` サーバーは起動時にこれらのテーブルを読み込みます。 許可テーブルの変更を反映させる方法はこちらを参照のこと → 「4.3.3 いつ権限の変更が反映されるか」節

これらのテーブルの登録を変更した場合、思ったとおりの権限状態になっている事を確認することはいいことです。 問題の解決には, 「4.2.10 何故 `Access denied` エラーになるのか」節. セキュリティに関するアドバイスは 「4.2.2 MySQL をクラッカーに対して安全にする方法」節.

便利なツールとして `mysqlaccess` スクリプト( Yves Carlier 作)が MySQL の配布に含まれています。 `mysqlaccess` を `--help` オプションで起動するとヘルプが表示されます。 `mysqlaccess` は `user`,`db` and `host` テーブルだけしか 検査しません。テーブルレベルの権限、フィールドレベルの権限は調べません。

### 4.2.6 MySQL が提供する権限

権限の設定は `mysql` データベースの `user`, `db`, `host`, `tables_priv`, `columns_priv` で行います。 (`mysql` はデータベースの名前です) MySQL サーバーは、サーバーの起動時か 「4.3.3 いつ権限の変更が反映されるか」節 で説明されている方法により、 これらのテーブルから権限の設定を読み込みます。

MySQL が提供する権限の名称は, 本マニュアルでは以下の表の名称を用います。 この表の項目名がそれぞれの許可される権限とその説明に対応しています：

Privilege | Column | Context
select | `Select_priv` | tables
insert | `Insert_priv` | tables
update | `Update_priv` | tables
delete | `Delete_priv` | tables
index | `Index_priv` | tables
alter | `Alter_priv` | tables
create | `Create_priv` | databases, tables, or indexes
drop | `Drop_priv` | databases or tables
grant | `Grant_priv` | databases or tables
references | `References_priv` | databases or tables
reload | `Reload_priv` | server administration
shutdown | `Shutdown_priv` | server administration
process | `Process_priv` | server administration
file | `File_priv` | file access on server

select, insert, update, delete の権限は、 存在しているデータベースのテーブルに対して許可されます。

もしテーブルから行を取り出すだけなら、`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 サーバーがが読み書きできるファイルに対して、この権限が与えられたユーザーは ファイルを読み書きできます。

残りの権限はアドミン操作に関する許可で、`mysqladmin` コマンドを使用して実行します。 次の表に `mysqladmin` コマンドのどれが、どの権限に対応しているかを示します：

Privilege | Commands permitted to privilege holders
reload | `reload`, `refresh`, `flush-privileges`, `flush-hosts`, `flush-logs`, and `flush-tables`
shutdown | `shutdown`
process | `processlist`, `kill`

`reload` コマンドはサーバーに権限の設定を再読込させるように伝えます。 `refresh` コマンドは全てのテーブルをフラッシュし、ログファイルを開き直します。 `flush-privileges` は `reload` と同義です。 その他の `flush-*` コマンドは `refresh` の動作とよく似ていますが、 適用範囲を絞っており、ちょっとした場合に有効です。 例えば、ログファイルだけをフラッシュしたい場合、 `refresh` を行うよりも `flush-logs` がいいです。

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

`processlist` コマンドはサーバーが実行しているスレッドの情報を表示します。 `kill` コマンドはサーバーのスレッドをkillします。 自分のスレッドは常に表示、killできますが、他人のスレッドをそうするには process 権限が必要です。 「4.5.4 `KILL` 構文」節参照.

ある権限を欲しがるユーザーだけにその権限を許可するのはよい考えですが、 権限を与えるときには、特定の事項を熟知していなければなりません：

- grant 権限を許可されたユーザーは、他のユーザーの権限を変える事ができます。 二人のユーザー間で違っている権限と `grant` 権限を入れ換えることができます。
- alter 権限は、テーブル名の変更を行うことにより特権システムを破るために 使用されるかもしれません。
- file 権限は、サーバー上にある全ての読み込み可能なファイルを データベースに取り込むことができ、これは `SELECT` 文でアクセスできます。 これはサーバに置かれているすべてのデータベースの内容を含みます！
- shutdown 権限は、他のユーザーに対するサービスを、サーバーを 停止することによって、拒否するようにできます。
- process 権限は実行されているクエリーをプレーンテキストで見ることに使えます。 パスワードの設定、変更のクエリーも含みます。
- `mysql` データベースに対しての権限は、パスワードの変更と他の権限の設定を変更時に使用されます。 (パスワードは暗号化されて登録されており、悪意のあるユーザーでも 単純に読むことはできません). `mysql.user` のパスワードフィールドにアクセスできれば、それを使用して MySQL サーバに与えられたユーザでログインすることができます。(十分 な権限があれば、同じユーザが別のものにパスワードを置き換えることもできます。 )

以下は MySQL の特権システムで行うものではありません：

- アクセスを拒否するユーザーを特定して設定することはできません。 完全に一致したユーザーからの接続を拒否できません。
- データベース内のテーブルの作成、破棄の権限を持つが、 データベースそのものを作成、破棄できる、そのようなユーザーを設定できません。

### 4.2.7 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` とパスワードの間にはスペースがないことに注意

注意: コマンドラインにパスワードを与えるのは安全ではありません！ システムに入っている如何なるユーザーも `ps auxww` のようなコマンドを 使用する事でパスワードを見付ける事ができます 「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 システムでは、ある値をデフォルト値にして接続に使用することができます。 そうすることにそり、毎回毎回コマンドラインに引数を与えなくてすむようになります：

- 自分のホームディレクトリに ``.my.cnf'` を作り、そのファイルの中の `[client]` セクションに接続用のパラメターを記述できます。 その記述は以下のようです：

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

  「4.1.2 my.cnf オプションファイル」節参照.
- 接続のパラメターに環境変数を使用することもできます。 ホスト名は `MYSQL_HOST` 環境変数を使用します。 MySQL のユーザー名は `USER` (これは Windows のみ) に設定された値を使用します。 パスワードは `MYSQL_PWD` 環境変数を見ますが、これは危険です。(次の節参照) 「H Environment Variables」節参照.

### 4.2.8 Access Control, Stage 1: 接続の承認

MySQL サーバーに接続すると、あなたがパスワード認証して接続していようがいまいが、 サーバーはあなたの身元により接続の許可拒否を行います。 もし身元が一致しない場合接続を拒否し、接続許可した場合、 サーバーは Stage 2 へと進み、要求を待ちます。

身元は二つのものに基づいて確認されます：

- あなたが接続しようとしているホスト
- あなたの MySQL ユーザー名

身元の確認は `user` テーブルのスコープフィールド (`Host`, `User`, `Password`) を使用して行います。 サーバーは `user` テーブルの登録に一致しているホスト名と ユーザー名に限り接続を許可し、その後、パスワードを要求します。

`user` テーブルのスコープフィールドの登録は以下のようになります：

- `Host` の値はホスト名か IP アドレスか `'localhost'`(ローカルホスト) です。
- `Host` にはワイルドカード文字 ``%'` と ``_'` を使用できます。
- `Host` に `'%'` を設定すると、全てのホストにマッチします。
- 空の `Host` 値は、権限が `host` テーブル内の与えられたホスト名に 適合するエントリと AND されることを意味します。次の章にこれについての詳し い情報を見つけられます。
- MySQL バージョン 3.23 では、IPアドレスが記述された `Host` 値には、何 ビットがネットワークアドレスに使用されるかを示すネットマスクを記述すること ができます。例えば:

      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` フィールドをブランク(空)にすることはできます。ブランクは全ての名前にマッチします。 これはユーザー名がない状態で接続してきたものに適用され、 クライアントがユーザー名を明記しない限り、匿名ユーザー(名前がブランク)として扱われます。 全てのアクセスのチェックにブランクのユーザー名が使用される事を意味します。(that is, during Stage 2)
- `Password` フィールドは空にできます。 これは、いかなるパスワードにもマッチするという意味ではなくて、 パスワードなして接続できるということになります。

非ブランクの `Password` 値はパスワードを暗号化したものです。 MySQL はだれもが見れるようにパスワードを平文では保存しません。 接続を試みようとしているユーザーのパスワードも、(`PASSWORD()` 関数で) 暗号化されます。 それから、暗号化パスワードは、クライアント／サーバがパスワードが正しいかチェッ クする時に使用されます(This is done without the encrypted password ever traveling over the connection)。注意: MySQL では、暗号化パスワー ドが本当のパスワードです。そのため、それへのアクセスを誰にも与えるべきでは ありません！ 特に、一般ユーザには`mysql` データベース内のテーブルの読 み取り権を与えないでください！

以下の表は、接続要求に対して与える、 `user` テーブルの `Host` と `User` の設定例です：

`Host` value | `User` value | Connections matched by entry
`'thomas.loc.gov'` | `'fred'` | `fred`, `thomas.loc.gov` から接続
`'thomas.loc.gov'` | `''` | `thomas.loc.gov` から接続してくる全てのユーザー
`'%'` | `'fred'` | `fred`, 全てのホストから接続
`'%'` | `''` | 全てのホストから接続してくる全ユーザー
`'%.loc.gov'` | `'fred'` | `fred`, `loc.gov` ドメイン内の全てのホストからの接続
`'x.y.%'` | `'fred'` | `fred`, `x.y.net`, `x.y.com`,`x.y.edu`, などからの接続. (あまり有効な使い方ではないです)
`'144.155.166.177'` | `'fred'` | `fred`, IP address が `144.155.166.177` のホストからの接続
`'144.155.166.%'` | `'fred'` | `fred`, `144.155.166` class C subnet 内の全てのホストからの接続
`'144.155.166.0/255.255.255.0'` | `'fred'` | 上の例と同じ

`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` テーブルが以下のようにソートされていた場合：

    +-----------+----------+-
    | 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'` エントリもマッチします。が、これは最初にはマッチしません。)

もう一例。`user` が以下の設定と仮定します：

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

これは次のようにソートされます：

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

`thomas.loc.gov` の `jeffrey` からの接続は、最初のエントリにマッチし、 `whitehouse.gov` の `jeffrey` からの接続は、二つ目のエントリにマッチします。

最初にサーバが,接続のためのマッチを見つけるのを試みるとき,共通の誤解は与えられた ユーザ名に明らかにそのユーザを命名するすべてのエントリが使用されると思うことです. これは単に本当ではありません. jeffreyによるthomas.loc.govからの接続が最初に エントリによってユーザ分野値として‘jeffrey'を含まないいずれのエントリによってる合わ せられる場合,前の例はこれをユーザ名なしで例示します!

よくある考え違いは、ユーザー名を与えた場合、 サーバーが接続にマッチするものを探す際に、 そのユーザーが登録されている全てのルールが、 最初に使用されるだろうと考えることです。これは正しくありません。 前の例でこれを示しましたが、`thomas.loc.gov` の `jeffrey` からの接続が 最初にマッチするのは、 `User` フィールドの値が `'jeffrey'` に なっているエントリではなく、ユーザー名なし(＝だれでも) のエントリの方が 先にマッチします！

もしサーバーへの接続がうまく行かない場合、 `user` テーブルを表示し、 マニュアルでソートしてみて、どのエントリに最初にマッチするか探してください。

### 4.2.9 Access Control, Stage 2: Request Verification

一度接続か確立されると、サーバーはステージ２に移ります。 このステージでは、サーバーはこの接続から来るそれぞれの要求が許可されて いるかどうかをチェックします。 チェックは実行しようとしている操作のタイプにより行います。 その操作が許可テーブルのどの権限フィールドに当てはまるかを見ます。 これら権限は `user`, `db`,`host`, `tables_priv` か `columns_priv` テーブルより導出されます。 許可テーブルは `GRANT` コマンドで操作します。 「4.3.1 `GRANT` と `REVOKE` 構文」節参照. (You may find it helpful to refer to 「4.2.5 特権システムはどのように動くか？」節, which lists the fields present in each of the grant tables.)

`user` テーブルは全てに対して基本となる権限をユーザーに割り当てます。 たとえカレントのデータベースが許可を与えていなくても、`user` テーブルの設定が有効になります。 例えば、`user` テーブルで delete を許可した場合、 サーバーにあるどんなデータベースの行も削除できるのです！ いうならば、`user` テーブルの権限はスーパーユーザーの権限と言ってもいいでしょう。 この権限はスーパーユーザー(サーバーやデーターベース管理者)のみに与えておく事が賢明です。 他のユーザーは、`user` テーブルの権限の設定を `'N'` のままにしておくべきですし、 また、`db` テーブルと `host` テーブルを利用して、 データベースを指定した上でユーザーに権限を許可すべきです。

`db` テーブルと `host` テーブルは特定のデータベースに対する権限許可を行います。 スコープフィールドの値は次のように記述されます:

- ワイルドカード文字 ``%'` と ``_'` は `Db` テーブルと `Host` フィールドだけに使用できます。
- `'%'` `Host` 値は ``あらゆるホスト'' を意味します。 `db` テーブルの `Host` に空を設定すると、``さらに `host` テーブルに許可情報を探しにいく'' となります。
- `'%'` か 空値を `Host` テーブルに設定すると、それは ``あらゆるホスト'' となります。
- `'%'` か 空値を `host` テーブルの `Db` フィールドに設定すると、 それは ``あらゆるデータベース'' となります。
- `User` を空値にすると、匿名ユーザーにマッチします。

サーバー起動時に、`db` テーブルと `host` テーブルはサーバーに読み込まれます。 (`user` テーブルもこの時に同時に読まれます) `db` テーブルは `Host`, `Db`, `User` のフィールドでソートされ、 `host` テーブルは `Host`, `Db` フィールドでソートされます。 `user` テーブルは、一番特定できるエントリを最初に、一番特定できないものを最後にソートします。 サーバーはソートされたものの中から、最初にマッチしたものを使用します。

`tables_priv` と `columns_priv` テーブルは、 特定のテーブルとフィールドに対する権限を許可します。 スコープフィールドの値は、いかにそって記述されます：

- ワイルドカード文字 ``%'` と ``_'` はどちらかのテーブルの `Host` フィールドに使用できます。
- どちらかのテーブルの `Host` 値を `'%'` かブランクにすると、 ``any host.'' を意味します。
- `Db`, `Table_name`, `Column_name` フィールドはどのテーブルにも ワイルドカードやブランクは使用できません。

`tables_priv` と `columns_priv` テーブルは `Host`, `Db`, `User` フィールドで並び換えられます。 これは `db` テーブルのソートに似ていますが、 `Host` フィールドだけが ワイルドカードを含むので、ソートはより単純なものになります。

この要求の承認は次のようにして行います。 もしアクセス承認を決定する部分のソースコードを理解できるなら、 ちょっと変わったアルゴリズムで承認の決定を行っている事に気づくでしょう。

管理者の要求(shutdown, reload, etc.)については、サーバーは `user` テーブルだけを参照します。(`user` テーブルだけが管理者権限のフィールドを持つ)。 エントリに許可登録されている操作は受け入れられ、それ以外は拒否されます。 例えば、`mysqladmin shutdown` を実行しようとしても、 `user` テーブルの shutdown 権限が許されていなければ実行できません。 この時、`db` と `host` テーブルはチェックされません。 (これらのテーブルには `Shutdown_priv` フィールドが無いからです)

データベースへの要求 (insert, update, etc.) において、 サーバーはまず最初に、ユーザーのグローバルな権限(スーパーユーザー)を `user` の中から探しだします。 もし許可が与えられていれば、アクセスは成功します。

`user` テーブルのグローバルな権限の設定が不十分であるなら、 サーバーはユーザーのデータベースに対する権限を `db` テーブルと `host` テーブルから決定します：

1. サーバーは `db` テーブルの `Host`,`Db`,`User`フィールドを参照します。 `Host` と `User` フィールドはユーザーの接続時のホスト名と MySQL ユーザー名にマッチします。 `Db` フィールドはユーザーがアクセスしたいデータベース名にマッチします。 `Host` と `User` にマッチするものが無かった場合、アクセスは拒否されます。
2. `db` テーブル内の `Host` フィールドが空でないエントリにマッチした場合、 ユーザーの指定されているデータベースに対する権限が定義されます。
3. `Host` フィールドが空値の `db` テーブルのエントリにマッチした場合、 どのホストがそのデータベースへアクセスできるかを `host` テーブルから探し出します。 この場合、`host` テーブル の `Host`, `Db` フィールドとマッチするものを探し出します。 `host` テーブルにエントリがなかった場合、アクセスは拒否されます。 もしマッチすると、ユーザーの特定データベースに対する権限は、 `host` テーブルと `db` テーブル両方にまたがった権限から割り出されます。 いうならば両方とも `'Y'` である権限。 (この方法を使用すると、まず `db` テーブルのエントリに大まかな権限を設定しておき、 それから `host` テーブルのエントリを使用して、ホスト情報もとに権限を限定していくという事ができます)

特定データベースに対する権限が `db` テーブルと `host` テーブルのエントリから決定された後、 サーバーはその割り出された権限に対し、`user` テーブルて設定されている権限を加えます。 この結果から得られた権限にマッチした要求は受け入れられます。 そうでなければ、サーバーはユーザーのテーブル、フィールドに対する許可を、 `tables_priv` と `columns_priv` 内に探します。 アクセスはこの結果により、許可、拒否されます。

先のユーザーの権限が計算される方法の記述は、boolean 表記で示すならば、 以下のようになるでしょう：

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

これは少し分かりにくいかもしれません。もしグローバルの `user` エントリ 権限許可が、リクエストされたオペレーションには不十分だと最初に分かった際、 サーバーがこれらの権限を database-, table-, column-固有の権限の 後に、なぜ、追加してしまうのか。 その理由は、リクエストが1個以上の権限を要求するだろうということです。 例えば、もしあなたが `INSERT ... SELECT` 構文を実行するなら、 あなたには insert と select 許可が必要です。 あなたの権限が、 `user` テーブルエントリで一つの権限が許可され、 `db` テーブルで、そのほかの権限が許可されていたとします。 この場合、あなたは、そのリクエストを実行するために、必要な権限を持っています。 しかし、サーバーはどちらのテーブル、それ単体からでは、権限を得ることが出来ません。 権限は、両方のエントリーを合わせなくてはならないのです。

`host` テーブルは ``安全な'' ホストのリストを維持するために使用できます。

TcX では、`host` テーブルにはローカルネット上の全てのホストが登録されています。 これらのホストは全ての権限が許可されています。

逆に `host` table で安全ではないホストを指定することもできます。 `public.your.domain` というマシンが安全ではない、公開されている場所にあるとします。 その場合以下のようにして、その公開マシン以外のネットワーク上のホストに対して、 アクセスを許可することができます：

    +--------------------+----+-
    | Host               | Db | ...
    +--------------------+----+-
    | public.your.domain | %  | ... (all privileges set to 'N')
    | %.your.domain      | %  | ... (all privileges set to 'Y')
    +--------------------+----+-

権限のテーブル設定は、あなたの思い通りに許可が得られるのか、 常に(`mysqlaccess`等を使用して)チェックすべきです。

### 4.2.10 何故 `Access denied` エラーになるのか

もし、MySQL サーバーに接続しようとして `Access denied` エラーに 遭遇してしまったら、以下に記すことが問題の解決のための指標となるでしょう:

- MySQL をインストールした後に、スクリプト `mysql_install_db` を実行して 許可テーブルを初期化しましたか？ していなければ実行してください。 「4.3.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` がリゾルブできなかったホスト名で、クライアントが登録されていないからです。 この場合、 ``/etc/hosts'` ファイルあるいは ``\windows\hosts'` ファイルを編集して ホスト名を追加し、`--skip-grant-tables` オプションでサーバーをリスタートします。
- 次のようなエラーが出た場合:

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

  これは間違ったパスワードを使用したことを意味します。 「4.3.6 パスワードの設定法」節参照. root のパスワードを忘れた場合、`mysqld` を `--skip-grant-tables` で再起動して、パスワードを変更することができま す。このオプションについての詳細は、マニュアルのこの節の後ろに見つけること ができます。 パスワードを指定してないのに、上のエラーがでた場合は、`my.ini` ファイ ルに間違ったパスワードがあることを意味します。 「4.1.2 my.cnf オプションファイル」節参照. このオ プションファイルは、次のように `--no-defaults` オプションで回避できま す:

      shell> mysqladmin --no-defaults -u root ver

- もしバージョン 3.22.11 より前の MySQL から バージョン 3.22.11 以上にバージョンアップしたなら、 `mysql_fix_privilege_tables` スクリプトを実行しましたか？ 実行していないなら、このエラーになります。 許可テーブルの構造が MySQL バージョン 3.22.11 から変更され、 `GRANT` 構文が機能しています。
- もしあなたの権限がセッションの途中で変更されたように思ったなら、それは スーパーユーザーが権限を変えたのかも知れません。許可テーブルの再読み込みは 新しいクライアントの接続から反映されますが、すでに接続している場合でも 「4.3.3 いつ権限の変更が反映されるか」節. に示す条件下では影響を受けます。
- もしあなたのパスワードが働かないのであれば、 `INSERT`, `UPDATE`, `SET PASSWORD` 構文でパスワードを設定するとき `PASSWORD()` 関数を使用しなければならないことを思い出してください。 しかし `PASSWORD()` 関数は、`GRANT ... INDENTIFIED BY` 構文や `mysqladmin password` コマンドでは不要です。 「4.3.6 パスワードの設定法」節参照.
- `localhost` はローカルのホスト名です。 もしクライアントがホストを指定せずに接続してきた場合、`localhost` がデフォルトで使用されます。 しかし、 MIT-pthreads を使用している場合、`localhost` への接続は失敗します。 (`localhost` への接続は、UNIXソケットを使用しますが、 MIT-pthreads が ソケット接続をサポートしていないためです。) この問題が起きるシステムでは、サーバー名を指定するために `--host` オプションを使用すべきです。 これは TCP/IP 接続を使用して `mysqld` サーバーに接続します。 この場合、`user` テーブルに、サーバーの実ホスト名を登録しておかなくてはなりません。 (これはクライアントプログラムをサーバーと同じホスト上で動かしている場合真となります) 例えば、`Using password: NO` を含むエラーメッセージを得た場合、これは パスワードなしでログインしようとしたことを意味します。
- `mysql -u user_name db_name` を使用してデータベースに接続しているときに `Access denied` エラーが発生した場合、`user` テーブルの設定違いが考えられます。 `mysql -u root mysql` を実行し、以下の SQL 文を試してください：

      mysql> SELECT * FROM user;

  `Host` と `User` にあなたのコンピュータ名と MySQL ユーザー名にマッチする登録がなされていなければなりません。
- `Access denied` エラーは、どのユーザーで接続してきたか、 どのホストから接続しようとしているか、パスワードを使用しているのかをメッセージに出力します。 通常、エラーになっているホスト名とユーザー名がマッチするエントリが `user` テーブルに一つはなければなりません。
- 他のホストから MySQL サーバーに接続を試みた時に以下のエラーが出た場合、 `user` テーブルにあなたがアクセスしているホストにマッチする行がありません：

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

  `mysql` コマンドをサーバーのホスト上で使用して、 `user`, `db`, `host` テーブルに接続しようとしている ユーザー名／ホスト名 を加えて、`mysqladmin flush-privileges` を 実行すれば解決できるでしょう。 もしサーバーが MySQL バージョン 3.22 ではなく、接続しようとしている ホストの IP もホスト名もわからない場合、 `user` テーブルの `Host` フィールドに `'%'` を設定し、 `mysqld` を `--log` オプションで再起動してください。 そしてクライアントホストから接続すれば、MySQL のログファイルに そのホストの情報が記録されているはずです。 それがわかれば、先に設定した `user` テーブルの `Host` フィールドの `'%'` を ログに記録されたホスト名に置き換えます。(しかしこれはシステムを危険にさらします) Linux 上でこのエラーの他の原因は、あなたの使用しているのと異なる glibc バー ジョンでコンパイルされた、バイナリ MySQL バージョンを使用している ことを意味します。この場合、あなたの OS/glibc をアップグレードするか、ソー ス MySQL バージョンをダウンロードしてコンパイルすべきです。ソース RPM は、通常コンパイルとインストールは簡単なので、これは大きな問題ではあり ません。
- ホスト名で接続しようとしたのに、ホスト名が現れないか、ホスト名が IP でエラー メッセージが出る場合:

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

  これは MySQL が IP をホスト名に解決しようとした時に何かエラーを得 たことを意味します。この場合、`mysqladmin flush-hosts` を実行して、内 部の DNS キャッシュをリセットできます。 「5.5.5 How MySQL uses 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` フィールドにホスト名を確定できる形で指定していないか、 使用しているシステムのリゾルブが FQDN (or vice-versa) を返しているかだと思われます。 例えば、`user` テーブルに `'tcx'` ホストの定義があったとして、 DNS が MySQL に `'tcx.subnet.se'` をホスト名として返した場合、 これは動きません。 `user` テーブルの `Host` フィールドの値に、あなたのホストの IP 番号を加えてください。 (`user` テーブルの `Host` の値にワイルドカードを使用することができます。`'tcx.%'` のように。 しかしホスト名の値を ``%'` 文字で終わらせる設定は、安全ではなく、推奨されません)
- もし `mysql -u user_name test` が動作し `mysql -u user_name other_db_name` が 動作しない場合は、`db` テーブルに `other_db_name` のエントリが 登録されていません。
- `mysql -u user_name db_name` はザーバー上では動作するが、 `mysql -u host_name -u user_name db_name` がクライアントホスト上で動作しない場合、 `user` テーブルか `db` テーブルにクライアントホストの名前が登録されていません。
- `Access denied` の原因がもし上記に当てはまらない場合は、 `user` テーブルから `Host` にワイルドカードを使用しているエントリを 全て消去してみてください。(``%'` や ``_'` を含む値です) よくある間違いは、`localhost` に対して `localhost` と同じマシン上から の接続を許可すると考えて `Host`=`'%'` と `User`=`'some user'` を登録することです。 これは動きません。なぜなら、デフォルトの権限に `Host`=`'localhost'` と `User`=`''` が含まれているからです。 `Host` の値が `'localhost'` の場合、これは `'%'` よりも 具体的に指定されているので、`localhost` からの接続にはこちらの方が 使用されるのです！ 正しい指定の仕方は、二番目の登録として `Host`=`'localhost'` と `User`=`'some_user'` を追加するか、 あるいは、`Host`=`'localhost'` と `User`=`''` を削除することです。
- もし以下のエラーが出た場合 `db` か `host` テーブルに問題があるのかもしれません。：

      Access to database denied

  もし `db` テーブルに `Host` フィールドが空の登録がある場合には、 `host` テーブル中に、`db` テーブルに登録されている ホストを明記した物が一つ以上あるかどうかを確認してください。 もし `SELECT ... INTO OUTFILE` や `LOAD DATA INFILE` SQL 文を 使用している時にこのエラーが出る場合、 `user` テーブルのあなたの登録に file 権限が 許可されていないと思われます。
- クライアントプログラムは接続に際して、 設定ファイルで設定された値か環境変数の値を使用することに注意してください。 もしクライアントプログラムが誤った値を接続に使用しているようなら、 環境変数とホームディレクトリにある ``.my.cnf'` ファイルを確認してください。 もちろんシステムワイドの MySQL 設定ファイルも、パラメターが記述されていないか、 チェックしてみてください。 「4.1.2 my.cnf オプションファイル」節参照. もしクライアントをオプションなしで起動していて `Access denied` がでるなら、 オプションファイルに古いパスワードが書かれているか確認してください。 「4.1.2 my.cnf オプションファイル」節参照.
- 権限テーブルを(`INSERT` または `UPDATE` ステートメントを使用して )直接変更する場合、あなたの変更は無視されたように見えます。サーバに権限テー ブルを再読み込みさせるために、`FLUSH PRIVILEGES` ステートメントの発行 か、`mysqladmin flush-privileges` コマンドの実行の必要があることを忘 れないでください。そうでないと、あなたの変更は次回のサーバ再起動まで効果が ありません。`UPDATE` コマンドで `root` パスワードを設定後、権限 をフラッシュするまでそれを指定する必要がありません。サーバはまだパスワード を変更したことを知らないからです！
- Perl, PHP, Python, ODBC プログラムでアクセスの問題があった場合、 `mysql -u user_name db_name` または `mysql -u user_name -pyour_pass db_name` でサーバへの接続を試してください。`mysql` クライ アントを使用して接続できれば、アクセス権でなく、あなたのプログラムに問題が あります。(`-p` とパスワードの間に空白がないことに注意してください; パスワードを指定するのに、`--password=your_pass` 構文も使用できます。 単に `-p` オプションを使用すると、MySQL はパスワードの入力を 求めます。)
- テストのために、`mysqld` デーモンを `--skip-grant-tables` オプショ ン付きで開始してください。MySQL 権限テーブルを変更し、あなたの変 更が望む効果があるかどうかのチェックに、`mysqlaccess` スクリプトを使 用できます。あなたの変更が満足できた時に、`mysqladmin flush-privileges` を実行し、`mysqld` サーバに新しい権限テーブルを使用 して開始するように伝えてください。注意: 権限テーブルのリロードは `--skip-grant-tables` オプションを上書きします。これは、サーバを落と して再起動することなしに、権限テーブルの使用を始めるようにサーバに伝えるこ とができます。
- もし全て失敗するなら、`mysqld` デーモンをデバッグオプションで起動してください。 例えば、`--debug=d,general,query`。これはコネクションに試みたホストやユーザーの情報、 また実行したコマンドを表示します。 「G.1.2 Creating trace files」節参照.
- もし MySQL の権限許可についてその他の問題が起こり、 メーリング・リストに問題をポストしなくてはいけないと感じれば、 いつも MySQL 許可テーブルのダンプを提供して下さい。 `mysqldump mysql` コマンドでダンプできます。 いつものように、 `mysqlbug` スクリプトでポストしてください。 「1.2.22.3 バグや問題を報告する方法」節参照. ときにはは、 `mysqldump` を実行するために、 `mysqld` を `--skip-grant-tables` オプションで実行しないと いけないかもしれません。

## 4.3 MySQL User Account Management

### 4.3.1 `GRANT` と `REVOKE` 構文

    GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
        ON {tbl_name | * | *.* | db_name.*}
        TO user_name [IDENTIFIED BY 'password']
            [, user_name [IDENTIFIED BY 'password'] ...]
        [WITH GRANT OPTION]

    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 ユーザに次の４つの権限レベルの権 利を与えたり取り消すことをできるようにすることです:

Global レベル
  Global 権限は与えられたサーバ上の全てのデータベースに適用します。これらの権限は `mysql.user` テーブル内に格納されます。
Database レベル
  Database 権限は与えられたデータベース内の全てのテーブルに適用します。こ れらの権限は `mysql.db` テーブルと `mysql.host` テーブル内に格納されます。
Table レベル
  Table 権限は与えられたテーブル内の全てのフィールドに適用します。これらの権限は `mysql.tables_priv` テーブル内に格納されます。
Column レベル
  Column 権限は与えられたテーブル内の一つのフィールドに適用します。これらの権限は `mysql.columns_priv` テーブル内に格納されます。

If you give a grant for a users that doesn't exists, that user is created. For examples of how `GRANT` works, see 「4.3.5 新しいユーザを MySQL へ追加」節.

`GRANT` と `REVOKE` ステートメントにおいて `priv_type` には 以下が指定できます:

    ALL PRIVILEGES      FILE                RELOAD
    ALTER               INDEX               SELECT
    CREATE              INSERT              SHUTDOWN
    DELETE              PROCESS             UPDATE
    DROP                REFERENCES          USAGE

`ALL` は `ALL PRIVILEGES` の同義語です. `REFERENCES` はまだ実行されません。 `USAGE` は ``no privileges'' と同義です. これはなんの権限も持たないユーザーを作る場合に使用します.

ユーザーから権限許可を取り除くには、`GRANT OPTION` オプションの値に `priv_type` を指定します：

    REVOKE GRANT OPTION ON ... FROM ...;

テーブルに対する許可のために指定できる `priv_type` は次のフィールドだけです： `SELECT`,`INSERT`, `UPDATE`, `DELETE`, `CREATE`, `DROP`, `GRANT`, `INDEX`, `ALTER`.

フィールドに対する許可のために指定できる `priv_type` は次のフィールドだけです (これは `column_list` 節を使用する場合に適用されます)： `SELECT`, `INSERT`, `UPDATE`.

`WITH GRANT OPTION` 節は、`GRANT` 構文を使用して 他のユーザーに権限を与えることができるようにします。

`ON *.*` を使用してグローバル権限を設定できます。 `ON db_name.*` を使用してデータベース権限を設定できます。`ON *` を 指定すると、現在のデータベースの権限を設定できます。 (警告： 現在のデータベースを持たない状態で `ON *` を指定した場合、 global 権限に影響します！)

ユーザへの権利の供与を他のホストから適応するために、MySQL は `user_name` の値を `user@host` の形で書けるようにしています。 特殊文字(``%'` のような)で `user_name` の値を指定したい場合、 ユーザやホスト名をクォートできます; (例えば `'test-user'@'test-hostname'`)。

ホスト名にワイルドカードを使用できます。例えば、`user@"%.loc.gov"` は `loc.gov` ドメインの全てのホストの `user` を与え、 `user@"144.155.166.%"` は `144.155.166` クラスCサブネットの あらゆるホストの `user` となります。

単に `user` と書くと `user@"%"` と同じです. 注意： もし匿名ユーザーからの MySQL サーバーへの接続を 許す場合(デフォルトです)、全てのローカルユーザー `username@localhost` を加えるべきです。 なぜなら、匿名ユーザーは同じマシンから MySQL サーバーに入ろうとした場合に 使用されるからです！ 匿名ユーザーは `mysql.user` ユーザーテーブルに、 `User=''` として登録されています。 これを確認するには、以下のようにします：

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

さしあたり, `GRANT` はホスト名、テーブル名、データベース名、フィールド名に 最大60文字まで使用できます。ユーザー名は最大16文字までです。

テーブル/フィールドの権限は global(ユーザとデータベース)権限と `GRANT` 権限と `OR` されます。例えば、ユーザが `mysql.user` テーブル内の global select 権限を持っている場合、 これはデータベースやテーブル/フィールドレベル内のエントリでは拒否できません。

フィールドの権利は次のように計算できます:

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

多くの場合、異なる権限レベルの一つでユーザに権利を与えるので、人生は通常 上述のようには複雑ではありません。:) アクセス制限のチェックの詳細は→ 「4.2 General Security Issues and the MySQL Access Privilege System」節.

ユーザへの権利の供与を他のホストから適応するために、MySQL はユー ザ名が形式 `user@host` で指定できることをサポートします。簡単な形 式 `user` は `user@%` の同義語です。特殊文字(`.` のよう な)でホスト名を指定したい場合、`"user"@"hostname"` 構文を使用でき ます。

ユーザとホスト名の組が存在しない場合、エントリは `mysql.user` テー ブルに追加され、`DELETE` コマンドで削除されるまでそこに残ります。 いうならば `GRANT` は `user` テーブルの登録を作りますが、 `REVOKE` はそれらを削除できません; そうするには `DELETE` を使用しなくてはなりません。

MySQL バージョン 3.22.12 以上では、 新しいユーザーが作成された場合、あるいは、あなたがグローバルな権限を許可されている場合、 ユーザーのパスワードは `IDENTIFIED BY` 節を使用して設定できます。 すでにユーザーにパスワードがある場合、新しく設定されたパスワードに置き換えられます。

警告： もし新しいユーザーを作っても `IDENTIFIED BY` 節を指定しなければ、 そのユーザーはノーパスワードです。 これは危険です。

パスワードは `SET PASSWORD` コマンドでも設定できます。 「5.5.6 `SET` 構文」節参照.

データベースに権限を `GRANT` する場合、`mysql.db` テーブル内の エントリは必要な場合に生成されます。全てのデータベース権限が `REVOKE` で削除された時、このエントリは削除されます。

ユーザがテーブルに何も権限を持っていない場合、テーブルの一覧要求時(例え ば、`SHOW TABLES` ステートメントで)には、テーブルは現れません。

`WITH GRANT OPTION` 節は、他のユーザーに、自分が持っている権限を与えることができます。 権限許可を他に与える場合は注意してください。 あなたと許可を与えるユーザーが違う権限を持っている場合、 与えられる権限の許可は、二つを合わせた物になります！

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

あなたがユーザーに格別の権限レベルを与えた場合、既にユーザーが持っているいかなる権限 (あるいは 将来持つ権限) はそのユーザーによっても許可が与えられます。 あなたがデータベースに対する insert 許可をあるユーザーに与えたと仮定します。 もし、データベースに対する select 権限を与えたり、 `WITH GRANT OPTION` を行うと、ユーザーは select 権限だけでなく insert も得ることになります。 もし update 権限をユーザーに与えると、そのユーザーは insert, select, update が可能です。

alter 権限を一般ユーザに与えるべきではありません。この場合 ユーザはテーブルをリネームでき、この方法で権限を回ることを試みることがで きます！

注意：もし table/column 権限を一人のユーザーにだけ与えた場合、 MySQL は全てのユーザーに対してテーブルとフィールドの承認権限を検討します。 これは MySQL を少し遅くします。

`mysqld` 開始時、全ての権限はメモリに読み込まれます。データベース、 テーブル、フィールド権限は一度効果を得ます。ユーザレベル権限はユーザ再接続時に 効果を得ます。 これらの許可テーブルを `GRANT` や `REVOKE` を使って変更しても サーバーにはすぐに反映されません。 もしこれらの許可テーブルを手動で変更した場合(`INSERT`, `UPDATE`, 等で変更した場合)、 `FLUSH PRIVILEGES` 構文を実行するか、`mysqladmin flush-privileges` を実行して サーバーに許可テーブルの再読み込みを行わせなくてはなりません。 「4.3.3 いつ権限の変更が反映されるか」節参照.

`ANSI SQL GRANT` と MySQL `GRANT` との大きな違いは: `GRANT` are:

- In MySQL privileges are given for an username + hostname combination and not only for an username.
- ANSI SQL はグローバルとデータベースレベル承認を持たず、ANSI SQL は MySQL がサポートする全ての権限をサポートしません。 MySQL doesn't support the ANSI SQL `TRIGGER`, `EXECUTE` or `UNDER` privileges.
- ANSI SQL privileges are structured in a hierarchal manner. If you remove an user, all privileges the user has granted are revoked. In MySQL the granted privileges are not automatically revoked, but you have to revoke these yourself if needed.
- If you in MySQL have the `INSERT` grant on only part of the columns in a table, you can execute `INSERT` statements on the table; The columns for which you don't have the `INSERT` privilege will set to their default values. ANSI SQL requires you to have the `INSERT` privilege on all columns.
- ANSI SQL でテーブルを破棄する時、そのテーブルの全ての権限は破棄さ れます。`ANSI SQL` で権限を取り消す場合、この権限に基づいて承認され た全ての権限も取り消されます。`MySQL` では、全ての権限は明示的な `REVOKE` コマンドまたは MySQL 権限テーブルの操作によっての み破棄されます。

### 4.3.2 MySQL ユーザ名とパスワード

MySQL によって使用されるユーザー名とパスワードの使用のされ方と、 UNIX, Windows で使用される方法とは、いくつか異なる点があります。

- MySQL データベースのアクセス認証に使用するユーザー名は、 UNIX のログインユーザやWindowsのユーザー名で行うことはありません(一致していません)。 利便性をはかるため、多くの MySQL クライアントは現在のログインしているユーザ名を MySQLのユーザー名としてログインを試みます。 しかしこれは `-u` か `--user` スイッチで変更できます。 これは、全てのユーザに対しパスワードを設定しておかないと、 全くデータベースを安全にできないことを意味します。 もしパスワードを全ユーザーに設定しておかないと、そのユーザー名で認証なしにサーバーに接続できます。
- MySQL のユーザー名は 16文字まで(英数半角)使用できます。 UNIXはだいたい8文字ですが。(8文字をこえるシステムもある)
- MySQL ユーザーのパスワードは、UNIX のパスワードと違います。 よって、それらのマシン上で UNIX のログインパスワードと データベースのパスワードは同じにする必要はありません。
- MySQL は UNIX のログインパスワードとは全く違う、 独自の暗号化されたパスワードだけを使用します。 `PASSWORD()` と `ENCRYPT()` 関数の説明を参照 → 「6.3.5.2 その他の関数」節. 注意: パスワードが '暗号化' されて格納されていても、あなたの '暗号化' され たパスワードを知ることで、MySQL サーバに接続するのには十分です！

MySQL ユーザーと彼らの権限は通常 `GRANT` コマンドで作成されます。 「4.3.1 `GRANT` と `REVOKE` 構文」節参照。

MySQL サーバにコマンドラインクライアントでログインする時、 `--password=your-password` でパスワードを指定すべきです。 「4.2.7 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.3.3 いつ権限の変更が反映されるか

`mysqld` の起動時、全ての許可テーブルはメモリーに読み込まれ、 この時点で有効になります。

`GRANT`, `REVOKE`, `SET PASSWORD` を使用して許可テーブルを 変更した場合、直にサーバに通知されます。

もし手動で許可テーブルを変更した場合(`INSERT`, `UPDATE` などで)、 `FLUSH PRIVILEGES` 構文か `mysqladmin flush-privileges` コマンド か `mysqladmin reload` コマンドを実行して、 サーバーに許可テーブルの読み込みを指示しなければなりません。 そうしなければ、サーバーを再起動させるまで、変更は反映されません。 権限テーブルを手で変更して、権限のリロードを忘れた場合、変更が何も行なわれ ないように見えるのがなぜかと不思議に思うでしょう！

サーバーが許可テーブルの変更を通知した場合、既に接続している クライアントは、以下のような影響を受けます：

- テーブルとフィールドの許可の変更は、次のクライアントの要求から反映されます。
- データベースに対する許可の変更は次の `USE db_name` コマンド以降から 有効になります。

グローバル権限とパスワードの変更は、次のクライアントの接続時から反映されます。

### 4.3.4 MySQL 権限許可の初期設定

MySQL インストール後、`scripts/mysql_install_db` を 実行して権限のアクセス許可を初期化します。 「2.3.1 素早いインストールの概要」節参照. `mysql_install_db` スクリプトは `mysqld` サーバーを起動し、 以下のように権限を初期化してテーブルに登録します：

- MySQL `root` ユーザーはスーパーユーザーとして登録され、 全ての操作ができます。 localhostからしか接続できません。 注意: `root` のパスワードの初期値は空です。 全ての人が パスワードなしで `root` になれ、全ての権限許可を得ることができます。
- `'test'` あるいは `'test_'` で名前がはじまっているデータベースに対して、 匿名ユーザーでもなんでもできるように許可が与えられます。 これは ローカルホストからの全てのユーザーは パスワード無しで接続ができ、 匿名ユーザーとして扱われるということです。
- その他の要求は拒否されます。例えば、一般ユーザーは `mysqladmin shutdown` や `mysqladmin processlist` を実行できません。

注意: デフォルトの権限は Windows では違います。 「2.6.2.3 Windows 上で MySQL を実行」節参照.

初期インストールの状態ではかなりアクセスが解放されているので、 インストール後最初にすることは、MySQL `root` ユーザーにパスワードを設定することです。 以下のようにします(パスワードは `PASSWORD()` 関数を使用することをお忘れなく)：

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

MySQL バージョン 3.22 以上では、`SET PASSWORD` 構文も使用できます:

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

password をセットする他の方法として、`mysqladmin` コマンドも使用できます：

    shell> mysqladmin -u root password new_password

`mysql` データベースに書き込み／更新アクセスのあるユーザだけが他のユーザのパ スワードを変更できます。すべての通常のユーザ(匿名ユーザ以外)は、上記のコマ ンドか、または `SET PASSWORD=PASSWORD('new password')` で、自分のパス ワードだけを変更できます。

もし最初の方法で `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.3.5 新しいユーザを MySQL へ追加

ユーザーは２つの違った方法で追加できます： `GRANT` 構文を使用して行う方法と、 MySQL の許可テーブルを直接操作する方法とです。 `GRANT` 構文の使用をお勧めします。 「4.3.1 `GRANT` と `REVOKE` 構文」節参照。

`phpmyadmin` のような、ユーザの生成と管理に使用できる contribute され たプログラムも多くあります。 「D Contributed Programs」節参照。

以下の例では、いかにして `mysql` クライアントを使用して新規にユーザーを登録するかを示します。 以下の例では、権限は前節で述べたデフォルト値になっているとします。 よって変更を行うためには、あなたは `mysqld` が走っているマシン上にログインしていなくてはなりませんし、 かつ、MySQL `root` ユーザーで接続していなければなりません。 さらに MySQL `root` ユーザーには `mysql` データベースに対して insert 権限を持ち、 reload のアドミニストレーター権限を持っていなければなりません。 もし `root` ユーザーのパスワードを変えていたならば、 `mysql` コマンドにパスワード指定を与えなくてはなりません。

You can add new users by issuing `GRANT` statements:

    shell> mysql --user=root mysql
    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`
  どこからでもサーバーに接続できる完全なスーパーユーザ。 しかし、MySQL を使用する時にはパスワード `'some_pass'` を 使用する必要があります。 `monty@localhost` と `monty@"%"` の両方に `GRANT` 構文を 発行しなくてはならない事に注意してください。 もし `localhost` からの許可をした登録がないと、`localhost` から接続した時、 `mysql_install_db` が自動で作成した `localhost` への匿名ユーザーが優先されます。 なぜなら、 `Host` フィールドの値が(ブランクやワールドカード以外に)明記されており、 許可登録が MySQL 内部でソートされる時に順番が上にソートされるからです。
`admin`
  `localhost` からパスワードなしで接続できますが、`reload`, `process` の使用だけが許されます。 これは、`mysqladmin reload`, `mysqladmin refresh`, `mysqladmin flush-*` そして `mysqladmin processlist` コマンドの実行がこのユーザーに許可されます。 データベースへのアクセスは許可されていません。 しかしこれは後でテーブル `GRANT` 構文を発行すれば、 個々のデータベースへのアクセス権限が設定できます。
`dummy`
  パスワードなしで localhost からのみ、接続できるユーザー。 グローバルな権限は全て `'N'` に設定されます。 `USAGE` 権限は権限無しユーザーの設定を許可する事になります。 これは、特定データーベースに対しての許可を後から与える事を想定しています。

同じアクセス許可を `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 以前のバージョンでは項目数が少なくなります). `admin` ユーザーを登録で使用している `INSERT` の拡張は バージョン 3.22.11 以上で可能です。

スーパーユーザーを定義するためには、`user` テーブルの許可フィールドを `'Y'` にするだけでかまいません。 `db` や `host` テーブルに登録は必要無いのです。

`user` テーブルの許可フィールドは最後の `INSERT` 文で(`dummy` ユーザーのために) は設定されていません。これらのフィールドはデフォルト値の `'N'` になります。 これは `GRANT USAGE` が行うのと同じものです。

以下は、`localhost`, `server.domain`, `whitehouse.gov` から接続が可能な `custom` ユーザーの追加例です。 `custom` ユーザーは `bankaccount` データーベースには `localhost` からの接続のみを許可され、 `expenses` データベースには `whitehouse.gov` からのみ接続が許可され、 `customer` データベースには全てのホストから接続できます。 `custom` ユーザーは、 `stupid` というパスワードを全てのホストで使用したいとします。

このユーザーの許可を `GRANT` 構文で定義するには、以下のようにします：

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

The reason that we do to grant statements for the user 'custom' is that we want the give the user access to MySQL both from the local machine with Unix sockets and from the remote machine 'whitehouse.gov' over TCP/IP.

許可テーブルを直接変更してこのユーザーの権限を設定するにはいかのようにします (`FLUSH PRIVILEGES` を最後に実行している事に注意)：

    shell> mysql --user=root mysql
    mysql> INSERT INTO user (Host,User,Password)
           VALUES('localhost','custom',PASSWORD('stupid'));
    mysql> INSERT INTO user (Host,User,Password)
           VALUES('server.domain','custom',PASSWORD('stupid'));
    mysql> INSERT INTO user (Host,User,Password)
           VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
    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('%','customer','custom','Y','Y','Y','Y','Y','Y');
    mysql> FLUSH PRIVILEGES;

最初の３つの `INSERT` 文は、 `custom` ユーザーがそれぞれのホストから パスワードつきで接続できるように `user` テーブルに追加しています。 しかしここでは権限は１つも与えられていません(権限のデフォルト値は `'N'` です)。 次の三つの `INSERT` 文は、`bankaccount`, `expenses`, `customer` データベースに対する該当ホストからのアクセス許可を `custom` ユーザーに与えるように、 `db` テーブルに追加しています。 許可テーブルが直接変更された場合、これらをサーバーに反映させるために、許可テーブルの 再読み込みを(`FLUSH PRIVILEGES`で) サーバーにつげなければなりません。

もし、あるドメインの全てのマシンに接続を許可したい場合、 以下のように `GRANT` 構文を発行します：

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

許可テーブルを直接変更するには以下のようにします：

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

もちろん、`xmysqladmin`, `mysql_webadmin`, そして `xmysql` を使って も、権限テーブルへの値の挿入/変更/更新ができます。これらのユーティリティは Contrib directory of the MySQL Website. に見つけることができます。

### 4.3.6 パスワードの設定法

多くの場合、ユーザ／パスワードを設定するために、`GRANT` を使用すべき です。以下は上級ユーザのためにだけあてはまります。 「4.3.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;

これは `user` テーブルにプレーンテキストの `'biscuit'` をパスワードとして登録してしまいます。 `jeffrey` ユーザーでこのパスワードを使用してサーバーに接続しようとすると、 `mysql` クライアントは暗号化したパスワードをサーバーに送ります。 サーバーは暗号化されたパスワード(`'biscuit'` ではありません) と `user` テーブルに登録された値(`'biscuit'`) を比較します。 その結果、比較は失敗し、サーバーは接続を拒否します：

    shell> mysql -u jeffrey -pbiscuit test
    Access denied

`user` テーブルに登録されるパスワードは暗号化されたものでなくてはなりません。 `INSERT` 構文は以下のようにして使用しなくてはなりません：

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

`SET PASSWORD` 構文を使用する場合は、以下のようにしなくてはなりません：

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

もし `GRANT ... IDENTIFIED BY` 構文や `mysqladmin password` コマンド でパスワードを設定した場合、`PASSWORD()` 関数は必要ありません。 両方とも、パスワードを暗号化してくれますので、 以下のように`'biscuit'`と与えます：

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

or

    shell> mysqladmin -u jeffrey password biscuit

注意： `PASSWORD()` がパスワードを暗号化することに注意してください。 この暗号化は UNIX のパスワードで使用されている暗号化と違うことにも留意してください。 UNIX パスワードファイルに記録されている暗号と `PASSWORD()` が暗号化した物が同じでも、 同じパスワードであるとは思わないでください。 「4.3.2 MySQL ユーザ名とパスワード」節参照.

### 4.3.7 パスワードを安全にする

自分のパスワードを他人にさらけ出すのは勧められることではありません。 それぞれの方法に於ける危険度に応じ、以下に示す方法でクライアントプログラムに あなたのパスワードをあたえて走らせることができます：

- 一般ユーザに `mysql.user` テーブルへのアクセスを与えてはいけません。 ユーザの暗号化されたパスワード知ることで、そのユーザとしてログインが可能に なります。パスワードは、使用される本当のパスワードを見ることができないよう に、スクランブルされているだけです(同じようなパスワードを他のアプリケーショ ンでたまたま使用する場合のため)。
- `-pyour_pass` か `--password=your_pass` オプションをコマンドラインで使用します。 これは便利ですが安全ではありません。あなたのパスワードは (`ps` コマンドのような) システムの状態を見るコマンドにて見ることができます。 (MySQL クライアントは初期化過程においてコマンドラインの引数をゼロで上書きして 見せないようにしているのですが、瞬間ですが値が見えてしまうのです)
- `-p` あるいは `--password` オプションを `your_pass` を与えないで使用します。 この場合、クライアントプログラムはターミナルを通じてパスワードの入力を促してきます:

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

  ``*'` 文字はパスワードを表しています。 クライアントはあなたの入力したパスワードを ``*'` 文字で端末に返していますので、 画面をのぞき込まれたとしてもパスワードはわかりません。 これはコマンドラインにパスワードを指定するより安全です。他のユーザーには見えませんから。 しかしこのパスワードを毎回入れる方法は対話式のプログラムを実行する場合だけに使用できる手です。 もし非対話式のスクリプトからクライアントプログラムを起動したい場合、 パスワードを端末から入れる機会がありません。 On some systems, you may even find that the first line of your script is read and interpreted (incorrectly) as your password!
- 設定ファイルにパスワードを書いておくこともできます。 例えば、自分のホームディレクトリーにある ``.my.cnf'` ファイルの `[client]` セクションに、以下のような形で書きます：

      [client]
      password=your_pass

  もし ``.my.cnf'` ファイルにパスワードを書いているなら、ファイルはグループや その他のユーザーが読み書きできないようにすべきです。ファイルのモードは `400` か `600` にします。 「4.1.2 my.cnf オプションファイル」節参照.
- `MYSQL_PWD` 環境変数にパスワードを設定することもできます。しかしこの方法は きわめて危険であるので、使用すべきではありません。 `ps` のあるバージョンでは、実行中のプロセスの環境変数を表示するオプションがあります； もし `MYSQL_PWD` 環境変数にパスワードを設定していると全てべたで見れます。 このバージョンの `ps` を持っていないシステムだとしても、プロセスの環境変数を調べる 方法がないとはいえないので、この方法はあまりいい方法ではありません。 「H Environment Variables」節参照.

まとめると、より安全な方法は、 パスワードプロンプトを返すクライアントプログラムを実行するか、 適切なパーミッションをかけた ``.my.cnf'` ファイルにパスワードを書くか です。

## 4.4 Disaster Prevention and Recovery

### 4.4.1 データベースのバックアップ

MySQL テーブルはファイルとして格納されるため、バックアップを行 うのは簡単です。矛盾のないバックアップを得るためには、 `FLUSH TABLES` をおこなって、`LOCK TABLES` を関連するテーブルで行ってください。 「6.7.2 `LOCK TABLES/UNLOCK TABLES` 構文」節参照. 「4.5.3 `FLUSH` 構文」節参照. 読み込みロックだ けが必要なので、そのテーブルでデータベースディレクトリのファイルのコピー が行われている間も、他のスレッドはクエリを継続できます。 The `FLUSH TABLE` is needed to ensure that the all active index pages is written to disk before you start the backup.

もし、テーブルを SQL レベルでバックアップしたいのであれば、`SELECT INTO OUTFILE` か `BACKUP TABLE` を使用できます。 「4.4.2 `BACKUP TABLE` Syntax」節参照.

他の方法は `mysqldump` プログラムか `mysqlhotcopy スクリプト` を使用することです。 「4.8.5 mysqldump, データベースとテーブルから、構造とデータをダンプ」節参照. 「4.8.5 mysqldump, データベースとテーブルから、構造とデータをダンプ」節参照. 「4.8.6 mysqlhotcopy, Copying MySQL Databases and Tables」節参照.

1. フルバックアップをとるには：

       shell> mysqldump --tab=/path/to/some/dir --opt --full

       or

       shell> mysqlhotcopy database /path/to/some/dir

   You can also simply copy all table files (``*.frm'`, ``*.MYD'`, and ``*.MYI'` files) as long as the server isn't updating anything. The script `mysqlhotcopy` does use this method.
2. `mysqld` を止め、そして `--log-update[=file_name]` オプションをつけて起動します。 「4.9.3 更新ログ」節参照. ログファイルは、 `mysqldump` 実行後に行われたデータベースの変更を 複製するための情報を与えてくれます。

もしリストアをしなければならない場合、まず最初に `REPAIR TABLE` か `myisamchk -r` を実行してテーブルの修復を試みてください。 ほとんどの場合、99.9% 修復はできるはずです。 もし `myisamchk` が失敗した場合、以下のようにします： (This will only work if you have started MySQL with `--log-update`. 「4.9.3 更新ログ」節参照.):

1. オリジナルの `mysqldump` バックアップデータをリストアします。
2. 次のコマンドを実行して、バイナリログ内の更新を再実行します。

       shell> mysqlbinlog hostname-bin.[0-9]* | mysql

   更新ログを使用する場合は、次のようにできます:

       shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql

`ls` は、全ての更新ログファイルを正しい順で得るために行われます。

`SELECT * INTO OUTFILE 'file_name' FROM tbl_name` での選択的バックアップと `LOAD DATA FROM INFILE 'file_name' REPLACE ...` でのリストアを行う こともできます。重複レコードを避けるためには、テーブル内に `PRIMARY KEY` or a `UNIQUE` が必要です。`REPLACE` は、'重複インデックス' 衝突があった場合、 新しいレコードを挿入する時に古いレコードが新しいものに置き換えられることを意味します。

If you get performance problems in making backups on your system, you can solve this by setting up replication and do the backups on the slave instead of on the master. 「4.10.1 紹介」節参照.

If you are using a Veritas file system, you can do:

1. Execute in a client (perl ?) `FLUSH TABLES WITH READ LOCK`
2. Fork a shell or execute in another client `mount vxfs snapshot`.
3. Execute in the first client `UNLOCK TABLES`
4. Copy files from snapshot
5. Unmount snapshot

### 4.4.2 `BACKUP TABLE` Syntax

    BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'

Make a copy of all the table files to the backup directory that are the minimum needed to restore it. Currenlty only works for `MyISAM` tables. For `MyISAM` table, copies `.frm` (definition) and `.MYD` (data) files. The index file can be rebuilt from those two.

Before using this command, please see 「4.4.1 データベースのバックアップ」節参照.

During the backup, read lock will be held for each table, one at time, as they are being backed up. If you want to backup several tables as a snapshot, you must first issue `LOCK TABLES` obtaining a read lock for each table in the group.

The command returns a table with the following columns:

Column | Value
Table | Table name
Op | Always ``backup''
Msg_type | One of `status`, `error`, `info` or `warning`.
Msg_text | The message.

Note that `BACKUP TABLE` is only available in MySQL version 3.23.25 and later.

### 4.4.3 `RESTORE TABLE` Syntax

    RESTORE TABLE tbl_name[,tbl_name...] FROM '/path/to/backup/directory'

Restores the table(s) from the backup that was made with `BACKUP TABLE`. Existing tables will not be overwritten - if you try to restore over an existing table, you will get an error. Restore will take longer than BACKUP due to the need to rebuilt the index. The more keys you have, the longer it is going to take. Just as `BACKUP TABLE`, currently only works of `MyISAM` tables.

The command returns a table with the following columns:

Column | Value
Table | Table name
Op | Always ``restore''
Msg_type | One of `status`, `error`, `info` or `warning`.
Msg_text | The message.

### 4.4.4 `CHECK TABLE` 構文

    CHECK TABLE tbl_name[,tbl_name...] [option [option...]]

    option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED

`CHECK TABLE` は `MyISAM` テーブルでだけ動作します。 `MyISAM` テーブルでは、テーブル上で `myisamchk -m table_name` を 実行するのと同じことです。

オプションを何も指定しない場合は `MEDIUM` が使用されます。

テーブルのエラーチェックを行ないます。`MyISAM` テーブルではキー統計が 更新されます。 このコマンドは次のフィールドを持つテーブルを返します:

Column | Value
Table | テーブル名
Op | 常に ``check''
Msg_type | code{status}, `error`, `info`, `warning` の一つ。
Msg_text | メッセージ。

注意: チェックされた各テーブルに対する情報の多くのレコードが得られます。 最後の１レコードは `Msg_type status` になり、通常は `OK` で あるべきです。`OK` や `Not checked` が得られない場合は、 テーブルの修復を通常通り実行すべきです。 「4.4.6 テーブルのメンテナンス、クラッシュからの修復のための `myisamchk` 使用」節参照. `Not checked` means that the table the given `TYPE` told MySQL that there wasn't any need to check the table.

様々なチェックタイプは次の意味です:

Type | Meaning
`QUICK` | 間違ったリンクをチェックするレコードを走査しません。
`FAST` | 正しくクローズされなかったテーブルだけをチェックします。
`CHANGED` | 最後にチェックしてから変更されたテーブルと、正しくクローズされなかったテーブルだけをチェックします。
`MEDIUM` | 削除されたリンクが OK であることを確かめるためにレコードを走査します。これはレコードのキーチェックサムも計算し、キーの計算されたチェックサムをで、これを確かめます。
`EXTENDED` | 各レコードのすべてのキーを完全キー検索を行ないます。テーブルが 100% 正当なことを確実にしますが、長い時間が掛かります！

動的なサイズの `MyISAM` テーブルについて、開始されたチェックは常に `MEDIUM` チェックを行ないます。清適サイズレコードでは、レコードはめっ たに壊れないので、`QUICK` と `FAST` ではレコードスキャンをスキッ プします。

チェックオプションは次のように組み合わせられます:

    CHECK TABLE test_table FAST QUICK;

これは、テーブルが正しくクローズされなかったかどうかだけを素早くチェックし ます。

NOTE: いくつかのケースでは `CHECK TABLE` はテーブルを変更し ます！ これはテーブルが '汚れている' か '正しくクローズされなかった' とマー クされているのに、`CHECK TABLE` がテーブル内に何も問題を発見しなかっ た場合に発生します。この場合、`CHECK TABLE` はテーブルを OK とマーク します。

If a table is corrupted, then it's most likely that the problem is in the indexes and not in the data part. All of the above check types checks the indexes throughly and should thus find most errors.

If you just want to check a table that you assume is ok, you should use no check options or the `QUICK` option. The later should be used when you are in a hurry and can take the very small risk that `QUICK` didn't find an error in the data file (In most cases MySQL should find, under normal usage, any error in the data file. If this happens then the table will be marked as 'corrupted', in which case the table can't be used until it's repaired).

`FAST` and `CHANGED` are mostly intended to be used from a script (for example to be executed from cron) if you want to check your table from time to time. In most cases you `FAST` is to be prefered over `CHANGED`. (The only case when it isn't is when you suspect a bug you have found a bug in the `MyISAM` code.).

`EXTENDED` is only to be used after you have run a normal check but still get strange errors from a table when MySQL tries to update a row or find a row by key (this is VERY unlikely to happen if a normal check has succeeded!).

Some things reported by check table, can't be corrected automatically:

- `Found row where the auto_increment column has the value 0`. This means that you have in the table a row where the `auto_increment` index column contains the value 0. (It's possible to create a row where the auto_increment column is 0 by explicitely setting the column to 0 with an `UPDATE` statement) This isn't an error in itself, but could cause trouble if you decide to dump the table and restore it or do an `ALTER TABLE` on the table. In this case the auto_increment column will change value, according to the rules of auto_increment columns, which could cause problems like a duplicate key error. To get rid of the warning, just execute an `UPDATE` statement to set the column to some other value than 0.

### 4.4.5 `REPAIR TABLE` 構文

    REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED]

`REPAIR TABLE` は `MyISAM` テーブルだけで動作します。テーブルに `myisamchk -r table_name` を実行することと同じです。

Normally you should never have to run this command, but if disaster strikes you are very likely to get back all your data from a MyISAM table with `REPAIR TABLE`. If your tables get corrupted a lot you should try to find the reason for this! 「A.4.1 What To Do If MySQL Keeps Crashing」節参照. 「7.1.3 MyISAM table problems.」節参照.

`REPAIR TABLE` はなんとかなる壊れたテーブルを修復します。コマンドは次 のフィールドを含む表を返します:

Column | Value
Table | テーブル名
Op | Always ``repair''
Msg_type | `status`, `error`, `info`, `warning` のどれか
Msg_text | メッセージ

注意: 修復された各テーブルの情報の多くのレコードを得ることがあります。最後 の１レコードは `Msg_type status` になり、通常は `OK` であるべき です。`OK` が得られなければ、`myisamchk -o` でテーブルの修復を試 みるべきです。`REPAIR TABLE` はまだ、`myisamchk` のオプションの 全てを持っていないからです。 In the near future, we will make it more flexible.

`QUICK` が与えられた場合は、MySQL はインデックスツリー の `REPAIR` だけを試みます。

If you use `EXTENDED` then MySQL will create the index row by row instead of creating one index at a time with sorting; This may be better than sorting on fixed-length keys if you have long `char()` keys that compress very good.

### 4.4.6 テーブルのメンテナンス、クラッシュからの修復のための `myisamchk` 使用

Starting with MySQL Version 3.23.13, you can check MyISAM tables with the `CHECK TABLE` command. 「4.4.4 `CHECK TABLE` 構文」節参照. You can repair tables with the `REPAIR TABLE` command. 「4.4.5 `REPAIR TABLE` 構文」節参照.

MyISAM テーブル (`.MYI` and `.MYD`) の検査・修復には `myisamchk` を 使用します。 ISAM テーブル (`.ISM` and `.ISD`) の検査・修復には `isamchk` を 使用します。 「7 MySQL テーブル型」節参照.

以下の文は `myisamchk` について述べていますが、`isamchk` にもすべて 当てはまります。

`myisamchk` ユーティリティは、データベースのテーブルの情報を得たり、 チェックしたり、テーブルの修復や最適化に使用します。 以下のセクションでは、 `myisamchk` の起動方法(オプションの説明も含む)、 テーブルの保守スケジュールのたて方、 `myisamchk` の色々な機能の使い方を述べます。

テーブルの修復と最適化のために、ほとんどの場合、 `OPTIMIZE TABLES` コマンドが使用できます。しかしこれは `myisamchk` に比べて、 遅くて確実でもありません。(fatal error発生時の場合)。これは その反面、使用方法が簡単でテーブルのフラッシュを気にかける必要がありません。 「4.5.1 `OPTIMIZE TABLE` 構文」節参照.

Even that the repair in `myisamchk` is quite secure, it's always a good idea to make a backup BEFORE doing a repair (or anything that could make a lot of changes to a table)

#### 4.4.6.1 `myisamchk` 起動構文

`myisamchk` は以下のようにして起動します:

    shell> myisamchk [options] tbl_name

`options` に、あなたが `myisamchk` にさせたいことを指定します。 その説明は後述します。(`myisamchk --help` と実行すれば、オプションの一覧が取れます)。 オプションがなければ、 `myisamchk` は単にテーブルを検査するだけです。 より多くの情報を得たい、あるいは、 `myisamchk` に誤り訂正の行動を 取らせる事については、後述します。

`tbl_name` は検査/修復したいテーブル名です。 もしどこか違うディレクトリにあるデータベースに対して `myisamchk` を走らせたいなら、 `myisamchk` にはファイルがどこにあるかわからないので、 ファイルのパスを指定しなければなりません。 実際、 `myisamchk` はあなたが使用しているファイルがデータベースのディレクトリにある かどうかは考慮しません； ほかの場所にデータベーステーブルのファイルをコピーし、そのコピーしたファイルに対して 回復操作を実行することができます。

`myisamchk` コマンドラインには、複数のテーブル名が指定できます。 また、インデックスファイル名(``.MYI'` 接尾語のついたファイル)も指定でき、 さらに ``*.MYI'` とすれば、ディレクトリ内の全てのテーブルが指定できます。 例えば、現在のカレントディレクトリがデーターベースディレクトリならば、 そのディレクトリ内の全てのテーブルは、以下のようにして検査できます：

    shell> myisamchk *.MYI

データベースディレクトリに入っていない場合、 パスを指定することにより全てのテーブルが検査できます：

    shell> myisamchk /path/to/database_dir/*.MYI

MySQL データディレクトリのパスにワイルドカードを使用することにより、 データベースの全てのテーブルも検査できます：

    shell> myisamchk /path/to/datadir/*/*.MYI

The recommended way to quickly check all tables is:

    myisamchk --silent --fast /path/to/datadir/*/*.MYI
    isamchk --silent /path/to/datadir/*/*.ISM

If you want to check all tables and repair all tables that are corrupted, you can use the following line:

    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

The above assumes that you have more than 64 M free.

Note that if you get an error like:

    myisamchk: warning: 1 clients is using or hasn't closed the table properly

This means that you are trying to check a table that has been updated by the another program (like the `mysqld` server) that hasn't yet closed the file or that has died without closing the file properly.

If you `mysqld` is running, you must force a sync/close of all tables with `FLUSH TABLES` and ensure that no one is using the tables while you are running `myisamchk`. In MySQL Version 3.23 the easiest way to avoid this problem is to use `CHECK TABLE` instead of `myisamchk` to check tables.

#### 4.4.6.2 `myisamchk` の一般オプション

`myisamchk` supports the following options.

`-# or --debug=debug_options`
  デバッグログの出力。 `debug_options` はよく `'d:t:o,filename'` とされます。
`-? or --help`
  ヘルプを表示して終了。
`-O var=option, --set-variable var=option`
  変数に値を入れます。可能な変数は `myisamchk --help` で確認できます:

  key_buffer_size | 523264
  read_buffer_size | 262136
  write_buffer_size | 262136
  sort_buffer_size | 2097144
  sort_key_blocks | 16
  decode_bits | 9

  `sort_buffer_size` is used when the keys are repaired by sorting keys, which is the normal case when you use `--recover`. `key_buffer_size` is used when you are checking the table with `--extended-check` or when the keys are repaired by inserting key row by row in to the table (like when doing normal inserts). Repairing through the key buffer is used in the following cases:
  - If you use `--safe-recover`.
  - If you are using a `FULLTEXT` index.
  - If the temporary files needed to sort the keys would be more than twice as big as when creating the key file directly. This is often the case when you have big `CHAR`, `VARCHAR` or `TEXT` keys as the sort needs to store the whole keys during sorting. If you have lots of temporary space and you can force `myisamchk` to repair by sorting you can use the `--sort-recover` option.
  Reparing through the key buffer takes much less disk space than using sorting, but is also much slower. もし速い修復を望むなら、メモリの 1/4 を上記の変数にセットします。 You can set both variables to big values, as only one of the above buffers will be used at a time.
`-s or --silent`
  静粛モード。 エラーのみを出力します。 二度 `-s` を指定すると(`-ss`)、`myisamchk` は ほとんど出力をしなくなります。
`-v or --verbose`
  冗長モード。より多く情報を出力します。 `-d` と `-e` オプションと共に使用できます。 `-v` を複数指定すると(`-vv`, `-vvv`)、もっと出力が多くなります！
`-V or --version`
  `myisamchk` バージョンを表示して終了。
`-w or, --wait`
  Instead of giving an error if the table is locked, wait until the table is unlocked before continuing. Note that if you are running `mysqld` on the table with `--skip-locking`, the table can only be locked by another `myisamchk` command.

#### 4.4.6.3 `myisamchk` の検査オプション

`-c or --check`
  テーブルのエラーをチェック。 これは `myisamchk` にオプションを 与えていない時のデフォルトです。
`-e or --extend-check`
  テーブルを非常に徹底的に検査します。 (ただし多くのインデックスがある場合、 とても遅くなります。). 極端な場合にだけで必要とされます。 通常 `myisamchk` や `myisamchk --medium-check` は、 このオプションなしで全てのエラーを見つけるはずです。 多くのメモリがマシンにあるなら、`--extended-check` を使用する際には `key_buffer_size` の値を多く増やします。
`-F or --fast`
  Check only tables that haven't been closed properly.
`-C or --check-only-changed`
  Check only tables that have changed since the last check.
`-f or --force`
  Restart `myisamchk` with `-r` (repair) on the table, if `myisamchk` finds any errors in the table.
`-i or --information`
  検査されたテーブルの統計情報を表示。
`-m or --medium-check`
  Faster than extended-check, but only finds 99.99% of all errors. Should, however, be good enough for most cases.
`-U or --update-state`
  Store in the ``.MYI'` file when the table was checked and if the table crashed. This should be used to get full benefit of the `--check-only-changed` option, but you shouldn't use this option if the `mysqld` server is using the table and you are running `mysqld` with `--skip-locking`.
`-T or --read-only`
  Don't mark table as checked. This is useful if you use `myisamchk` to check a table that is in use by some other application that doesn't use locking (like `mysqld --skip-locking`).

#### 4.4.6.4 myisamchk の修復オプション

以下のオプションは `myisamchk` を `-r` か `-o` オプションで 実行した場合に使用できます:

`-D # or --data-file-length=#`
  Max length of data file (when re-creating data file when it's 'full').
`-e or --extend-check`
  Try to recover every possible row from the data file. Normally this will also find a lot of garbage rows. Don't use this option if you are not totally desperate.
`-f or --force`
  Overwrite old temporary files (`table_name.TMD`) instead of aborting.
`-k # or keys-used=#`
  If you are using ISAM, tells the ISAM table handler to update only the first `#` indexes. If you are using `MyISAM`, tells which keys to use, where each binary bit stands for one key (first key is bit 0). これはインサートを速くします！ 非アクティブになったインデックスは、`myisamchk -r` を使用すれば再びアクティ ブになります。
`-l or --no-symlinks`
  修復時にシンボリックリンクを追いません。 通常、`myisamchk` はシンボリックリンクが指し示すテーブルも修復します。 This option doesn't exist in MySQL 4.0, as MySQL 4.0 will not remove symlinks during repair.
`-r or --recover`
  Can fix almost anything except unique keys that aren't unique (which is an extremely unlikely error with ISAM/MyISAM tables). If you want to recover a table, this is the option to try first. Only if myisamchk reports that the table can't be recovered by `-r`, you should then try `-o`. (Note that in the unlikely case that `-r` fails, the data file is still intact.) If you have lots of memory, you should increase the size of `sort_buffer_size`!
`-o or --safe-recover`
  古い修復方法を使用します (reads through all rows in order and updates all index trees based on the found rows); これは `-r` よりも遅いですが、 `-r` が扱えないものも扱えます。 This recovery method also uses much less disk space than `-r`. Normally one should always first repair with `-r`, and only if this fails use `-o`. If you have lots of memory, you should increase the size of `key_buffer_size`!
`-n or --sort-recover`
  Force `myisamchk` to use sorting to resolve the keys even if the temporary files should be very big. This will not have any effect if you have fulltext keys in the table.
`--character-sets-dir=...`
  Directory where character sets are stored.
`--set-character-set=name`
  Change the character set used by the index
`.t or --tmpdir=path`
  一時ファイルを保存する先のパス。 もしセットされなければ、 `myisamchk` は `TMPDIR` 環境変数の値をこのパスとします。
`-q or --quick`
  Faster repair by not modifying the data file. One can give a second `-q` to force `myisamchk` to modify the original datafile in case of duplicate keys
`-u or --unpack`
  `myisampack` でパックされたテーブルファイルをアンパックします。

#### 4.4.6.5 `myisamchk` の他のオプション

Other actions that `myisamchk` can do, besides repair and check tables:

`-a or --analyze`
  キーの分布(配置)を分析します。 This improves join performance by enabling the join optimizer to better choose in which order it should join the tables and which keys it should use: `myisamchk --describe --verbose table_name'` or using `SHOW KEYS` in MySQL.
`-d or --description`
  テーブルに関するいくらかの情報を表示します
`-A or --set-auto-increment[=value]`
  Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.
`-S or --sort-index`
  インデックスブロックのソート。 これは、アプリケーションでの ``read-next'' を速くします。
`-R or --sort-records=#`
  インデックスに従ってソート。 これはあなたのデータをよりよく配置し、このインデックスへの `SELECT`, `ORDER BY` オペレーションを速くします。 (この操作の最初のソートは非常に遅くなるかもしれません！) テーブルのインデックスの番号をみつけるには `SHOW INDEX` を使用しますが、 これは `myisamchk` がテーブルのインデックスを見つけるのと同じ順序で行います。 インデックス番号は 1 から始まります。

#### 4.4.6.6 `myisamchk` メモリ使用

`myisamchk` を走らす上でメモリーの配分は重要です。 `myisamchk` は `-O` オプションで定義した以上のメモリは使用しません。 とても大きなファイルのたいして `myisamchk` をかけたいなら、 メモリーをどれくらい使用するかを最初に決めなくてはなりません。 デフォルトは固定で約 3M だけを使用します。大きな値を使用することで、 `myisamchk` をより速く動作できます。 例えば、32MBytesのRAMがあるなら、以下のように指定できます (他のオプションも指定して):

    shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...

`-O sort=16M` の使用は多くの場合おそらく十分でしょう。

しかし、`myisamchk` は `TMPDIR` 内に一時ファイルを使用します。 `TMPDIR` がメモリファイルシステムを指している場合は、簡単に out of memory エラーを得るでしょう。 If this happens, set `TMPDIR` to point at some directory with more space and restart `myisamchk`.

When repairing, `myisamchk` will also need a lot of disk space:

- Double the size of the record file (the original one and a copy). This space is not needed if one does a repair with `--quick`, as in this case only the index file will be re-created. This space is needed on the same disk as the original record file!
- Space for the new index file that replaces the old one. The old index file is truncated at start, so one usually ignore this space. This space is needed on the same disk as the original index file!
- When using `--recover` or `--sort-recover` (but not when using `--safe-recover`, you will need space for a sort buffer for: `(largest_key + row_pointer_length)*number_of_rows * 2`. You can check the length of the keys and the row_pointer_length with `myisamchk -dv table`. This space is allocated on the temporary disk (specified by `TMPDIR` or `--tmpdir=#`).

If you have a problem with disk space during repair, you can try to use `--safe-recover` instead of `--recover`.

#### 4.4.6.7 Using `myisamchk` for Crash Recovery

If you run `mysqld` with `--skip-locking` (which is the default on some systems, like Linux), you can't reliably use `myisamchk` to check a table when `mysqld` is using the same table. If you can be sure that no one is accessing the tables through `mysqld` while you run `myisamchk`, you only have to do `mysqladmin flush-tables` before you start checking the tables. If you can't guarantee the above, then you must take down `mysqld` while you check the tables. If you run `myisamchk` while `mysqld` is updating the tables, you may get a warning that a table is corrupt even if it isn't.

If you are not using `--skip-locking`, you can use `myisamchk` to check tables at any time. While you do this, all clients that try to update the table will wait until `myisamchk` is ready before continuing.

If you use `myisamchk` to repair or optimize tables, you MUST always ensure that the `mysqld` server is not using the table (this also applies if you are using `--skip-locking`). If you don't take down `mysqld` you should at least do a `mysqladmin flush-tables` before you run `myisamchk`.

This chapter describes how to check for and deal with data corruption in MySQL databases. If your tables get corrupted a lot you should try to find the reason for this! 「A.4.1 What To Do If MySQL Keeps Crashing」節参照.

The `MyISAM` table section contains reason for why a table could be corrupted. 「7.1.3 MyISAM table problems.」節参照.

When performing crash recovery, it is important to understand that each table `tbl_name` in a database corresponds to three files in the database directory:

File | Purpose
``tbl_name.frm'` | Table definition (form) file
``tbl_name.MYD'` | Data file
``tbl_name.MYI'` | Index file

Each of these three file types is subject to corruption in various ways, but problems occur most often in data files and index files.

`myisamchk` works by creating a copy of the ``.MYD'` (data) file row by row. It ends the repair stage by removing the old ``.MYD'` file and renaming the new file to the original file name. If you use `--quick`, `myisamchk` does not create a temporary ``.MYD'` file, but instead assumes that the ``.MYD'` file is correct and only generates a new index file without touching the ``.MYD'` file. This is safe, because `myisamchk` automatically detects if the ``.MYD'` file is corrupt and aborts the repair in this case. You can also give two `--quick` options to `myisamchk`. In this case, `myisamchk` does not abort on some errors (like duplicate key) but instead tries to resolve them by modifying the ``.MYD'` file. Normally the use of two `--quick` options is useful only if you have too little free disk space to perform a normal repair. In this case you should at least make a backup before running `myisamchk`.

#### 4.4.6.8 How to Check Tables for Errors

To check a MyISAM table, use the following commands:

`myisamchk tbl_name`
  This finds 99.99% of all errors. What it can't find is corruption that involves ONLY the data file (which is very unusual). If you want to check a table, you should normally run `myisamchk` without options or with either the `-s` or `--silent` option.
`myisamchk -m tbl_name`
  This finds 99.999% of all errors. It checks first all index entries for errors and then it reads through all rows. It calculates a checksum for all keys in the rows and verifies that they checksum matches the checksum for the keys in the index tree.
`myisamchk -e tbl_name`
  This does a complete and thorough check of all data (`-e` means ``extended check''). It does a check-read of every key for each row to verify that they indeed point to the correct row. This may take a LONG time on a big table with many keys. `myisamchk` will normally stop after the first error it finds. If you want to obtain more information, you can add the `--verbose` (`-v`) option. This causes `myisamchk` to keep going, up through a maximum of 20 errors. In normal usage, a simple `myisamchk` (with no arguments other than the table name) is sufficient.
`myisamchk -e -i tbl_name`
  Like the previous command, but the `-i` option tells `myisamchk` to print some informational statistics, too.

#### 4.4.6.9 テーブルの修復方法

In the following section we only talk about using `myisamchk` on `MyISAM` tables (extensions `.MYI` and `.MYD`). If you are using `ISAM` tables (extensions `.ISM` and `.ISD`), you should use `isamchk` instead.

Starting with MySQL Version 3.23.14, you can repair MyISAM tables with the `REPAIR TABLE` command. 「4.4.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 To get more information about the error you can run `perror ###`. Here is the most common errors that indicates a problem with the table:

      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

  Note that error 135, no more room in record file, is not an error that can be fixed by a simple repair. In this case you have to do:

      ALTER TABLE table MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

この他の場合、あなたは自分のテーブルを修理しなければなりません。 `myisamchk` はほとんどの問題を見つけ出し修正します。

修復過程は以下で記述する最大4つの段階を踏みます。 これを始める前に、あなたはデータベースディレクトリに `cd` して テーブルファイルのパーミッションを確認すべきです。 これらファイルは `mysqld` を実行している UNIX ユーザーが読み込み可能 であるようにしてください(検査のするのにあなたにファイルのアクセス権も必要)。 もしファイルの変更をする必要があるならば、ファイルへの書き込み許可も必要です。

If you are using MySQL Version 3.23.16 and above, you can (and should) use the `CHECK` and `REPAIR` commands to check and repair `MyISAM` tables. 「4.4.4 `CHECK TABLE` 構文」節参照. 「4.4.5 `REPAIR TABLE` 構文」節参照.

The manual section about table maintenance includes the options to `isamchk`/`myisamchk`. 「4.4.6 テーブルのメンテナンス、クラッシュからの修復のための `myisamchk` 使用」節参照.

The following section is for the cases where the above command fails or if you want to use the extended features that `isamchk`/`myisamchk` provides.

If you are going to repair a table from the command line, you must first take down the `mysqld` server. Note that when you do `mysqladmin shutdown` on a remote server, the `mysqld` server will still be alive for a while after `mysqladmin` returns, until all queries are stopped and all keys have been flushed to disk.

Stage 1: テーブルをチェックする

`myisamchk *.MYI` (時間がかかってもよいなら `myisamchk -e *.MYI`) を実行します。 `-s` (silent) オプションは不要な情報の出力をおさえます。

If the `mysqld` server is done you should use the --update option to tell `myisamchk` to mark the table as 'checked'.

`myisamchk` がエラーを返した場合にだけ、テーブルを修復する必要があります。 この場合、Stage 2 へ進みます。

チェック時に奇妙なエラー(`out of memory` エラーのような) が起きた場合、 あるいは `myisamchk` が落ちた場合、Stage 3 に進んでください。

Stage 2: 簡単で安全な修復

NOTE: If you want repairing to go much faster, you should add: `-O sort_buffer=# -O key_buffer=#` (where # is about 1/4 of the available memory) to all `isamchk/myisamchk` commands.

まず最初に `myisamchk -r -q tbl_name` を試みてください (`-r -q` は ``quick recovery mode''の意)。 これはデータファイルに触れないでインデックスファイルの修理を試みます。 もしデータファイルが全てとデータファイル中の正しい場所での削除リンクポイントを 含んでいるなら、これは動作してテーブルを修復します。 成功後、次のテーブルの修復に進んでください。 失敗した場合は、以下の手順で試みてください：

1. 続ける前にデータファイルをバックアップしてください。
2. `myisamchk -r tbl_name` を使用します(`-r` は ``recovery mode''の意)。 これは不正なレコードと削除されたレコードをデータファイルから消去し、 インデックスファイル(.MYI)を再構築します。
3. 上記が失敗した場合、`myisamchk --safe-recover tbl_name` を使用して下さい。 Safe recovery モードは古い方法を使用して修復します。 これは普通の修復モードでは行わない操作をいくつかもっています。(遅いですが)

If you get weird errors when repairing (such as `out of memory` errors), or if `myisamchk` crashes, go to Stage 3.

Stage 3: 難しい修復

インデックスファイル(.MYI)の最初の 16K ブロックが破壊された場合、 または不正な情報を含む場合、またはインデックスファイルがない場合にだけ、 本修復段階を経ます。 この場合、新しいインデックスファイルファイルを作成する必要があります。 次のようにしてください:

1. データファイルをどこか安全場所に移動します。
2. 新しい(空の)データとインデックスファイルを作るために、 テーブルディスクリプタファイルを使用します：

       shell> mysql db_name
       mysql> SET AUTOCOMMIT=1;
       mysql> TRUNCATE TABLE table_name;
       mysql> quit

   If your SQL version doesn't have `TRUNCATE TABLE`, use `DELETE FROM table_name` instead.
3. 古いデータファイルを新しく作ったデータファイルにコピーします。 (Don't just move the old file back onto the new file; you want to retain a copy in case something goes wrong.)

Go back to Stage 2. `myisamchk -r -q` should work now. (This shouldn't be an endless loop.)

Stage 4: とても難しい修復

これは、ディスクリプタファイル(.frm)もクラッシュした場合にだけ発生します。 これは発生することはありません。なぜならディスクリプタファイルは テーブルが生成された後に書かれることはないからです。

1. ディスクリプタファイルをバックアップからリストアして、Stage 3 に戻ってください。 インデックスファイルのリストアもできます。そして Stage 2 に戻ってください。 後者の場合、`myisamchk -r` で開始すべきです。
2. バックアップを持っていなくても、テーブルがどのように作成されたかを正確に知って いれば、他のデータベース内にテーブルのコピーを生成します。 新しいデータファイルを削除し、先ほど作ったデータベースの中の ディスクリプタファイルとインデックスファイルを、壊れたデータベース内に 移動します。これは新しいディスクリプタファイルとインデックスファイルを 与えることになりますが、データファイルはそのまま残っています。 Stage 2 に進み、インデックスファイルの修復を行ってください。

#### 4.4.6.10 テーブルの最適化

断片化されたレコードの結合と、 レコードの削除と更新から生じる無駄なスペースの排除、 これら行うには、修復モード(recovery mode)で `myisamchk` を実行します：

    shell> myisamchk -r tbl_name

SQL `OPTIMIZE TABLE` でも同様にテーブルを最適化できます。 `OPTIMIZE TABLE` does a repair of the table, a key analyzes and also sorts the index tree to give faster key lookups. There is also no possibility of unwanted interaction between a utility and the server, because the server does all the work when you use `OPTIMIZE TABLE`. 「4.5.1 `OPTIMIZE TABLE` 構文」節参照.

`myisamchk` には、あなたがテーブルの性能を向上させるのに使用することができる 他の多くのオプションがあります:

`-S, --sort-index`
`-R index_num, --sort-records=index_num`
`-a, --analyze`

For a full description of the option. 「4.4.6.1 `myisamchk` 起動構文」節参照.

### 4.4.7 テーブルの保守体制の設定

Starting with MySQL Version 3.23.13, you can check MyISAM tables with the `CHECK TABLE` command. 「4.4.4 `CHECK TABLE` 構文」節参照. You can repair tables with the `REPAIR TABLE` command. 「4.4.5 `REPAIR TABLE` 構文」節参照.

問題が発生するまで待つより、定期的にテーブルを検査する方がよりよい考えです。 保守目的には、`myisamchk -s` でテーブルを検査するのがよいでしょう。 `-s` オプション(short for `--silent`) はサイレントモードなので、 エラーが起きた場合にだけメッセージを出力します。

サーバーを開始するときにテーブルを検査するのもよい考えです。 例えば、更新最中にマシンがリブートされたなら、全てのテーブルに関して その影響がないか検査する必要があります。（これは``expected crashed table''です） リブート後にもし古い ``.pid'` ファイル(プロセスID) があるならば、 24時間以内に変更されたテーブルに対して `myisamchk` を走らせて検査させるよう に、 `safe_mysqld` にテストを追加しても構いません。 (``.pid'` ファイルは `mysqld` 起動時に作られ、通常修了時に消されます。 スタート時に ``.pid'` ファイルが存在するなら `mysqld` が異常終了したこと を示します。)

良いテストは、``.pid'` ファイルの作成時間以降に変更された 全てのテーブルを検査するテストです。

通常のシステム運用中にもテーブルを検査すべきです。 MySQL AB では、週に一度、 `cron` を使用して重要なテーブルを検査し ています。 ``crontab'` ファイルには以下のように記述します：

    35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

これは壊れたテーブルの情報を出力しますので、必要とあらば検査、修復が行えるわけで す。

予想外の事故で壊れたテーブル(ハードウェアのトラブルが原因で崩壊)を除き、 2,3年間、テーブルは壊れたことはありません(これは本当に本当です)。 ので、一週間に一度のチェックでも十分です。

24時間以内に変更された全てのテーブルに対して、 `myisamchk -s` を毎晩実行する事を勧めます。 そうすれば、あなたは我々と同じぐらいに MySQL を 信頼することになります。

Normally you don't need to maintain MySQL tables that much. If you are changing tables with dynamic size rows (tables with `VARCHAR`, `BLOB` or `TEXT` columns) or have tables with many deleted rows you may want to from time to time (once a month?) defragment/reclaim space from the tables.

You can do this by using `OPTIMIZE TABLE` on the tables in question or if you can take the `mysqld` server down for a while do:

    isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
    myisamchk -r --silent --sort-index  -O sort_buffer_size=16M */*.MYI

### 4.4.8 テーブル情報取得

テーブルから詳細/統計を得るためには、次の方法を使用します。後でさらに詳細な情 報をいくつか説明します。

`myisamchk -d tbl_name`
  `myisamchk` を ``describe mode'' で実行し、テーブルの説明記述を作ります。 `--skip-locking` を指定して MySQL サーバーを起動した場合、 `myisamchk` は myisamchk 実行中に更新されたテーブルについてエラーを報告します. しかし `myisamchk` は describe mode ではテーブルを変えないので、 データを破壊する危険性はありません。
`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.MYM

`myisamchk` が生成する情報の説明を以下に示します。 ``keyfile'' はインデックスファイルです。 ``Record'' と ``row'' は同義です。

`ISAM file`
  ISAM (index) ファイルの名前
`Isam-version`
  ISAM 形式のバージョン。現在は常に 2
`Creation time`
  データファイルが生成された時。
`Recover time`
  インデックス/データファイルが最後に再構築された時。
`Data records`
  レコード/行の数。
`Deleted blocks`
  予約された領域をまだ持っている削除ブロック数。 このスペースを最小にするために自分のテーブルを最適化することができます。 「4.4.6.10 テーブルの最適化」節参照.
`Datafile: Parts`
  動的なレコード形式にいくつのデータブロックがあるかを表示します。 分割なしで最適化されたテーブルでは `Data records` と同じです。
`Deleted data`
  改善されていない削除データのバイト数。 このスペースを最小にするために自分のテーブルを最適化することができます。 「4.4.6.10 テーブルの最適化」節参照.
`Datafile 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` を使用します。 他の値で可能な物は`圧縮`、`パック`します。
`table description`
  テーブル内の全てのキーのリスト。各キーについて、いくつかの低レベル情報が提供さ れます:
  `Key`
    このキー番号。
  `Start`
    このインデックス部が開始するレコード/行内の位置。
  `Len`
    インデックス部の長さ。 パックされた数値では、これは常に項目の完全な長さになります。 文字型においては、文字型の項目の頭の部分にインデックスがつく事になりますので、 インデックス項目の最大長さよりもこの値は短くなるでしょう。
  `Index`
    `unique` or `multip.` (multiple). このインデックス内では1つの値が複数 回存在し得ます。
  `Type`
    このインデックス部が持つデータ型。 これは NISAM データ型で、 `packed`, `stripped` か `empty` オプションを持ちます。
  `Root`
    ルートインデックスブロックのアドレス。
  `Blocksize`
    各インデックスブロックのサイズ。これはデフォルトでは 1024 ですが、コンパ イル時に変更できます。
  `Rec/key`
    これはオプティマイザによって使用される統計値です。このキーの値ごとのレコー ド数を知らせます。ユニークキーは常に1の値を持ちます。これはテーブルがロードさ れた(または大きく変更された)後に `myisamchk -a` で更新されます。これ が全く更新されない場合はデフォルト値の 30 が与えられます。
``
  上の最初の例では、9番目のキーは2つの部分をもったマルチパートキーです。
`Keyblocks used`
  使用されたキーブロックのパーセンテージ。このテーブルは `myisamchk` で再配置 されるため、値はとても高くなります (理論的な最大にとても近くなります)。
`Packed`
  MySQL は一般の接尾辞でキーのパックを試みます。これは `CHAR`/`VARCHAR`/`DECIMAL` キーでだけ使用できます。名前の ような長い文字列では、これは使用領域を顕著に減らします。上の三番目の例では4番目 のキーが10文字長で、領域の60%の減少を得ます。
`Max levels`
  このキーの Btree の深さ。長いキーを持つ大きなテーブルは高い値を得ます。
`Records`
  テーブルが持っている行数。
`M.recordlength`
  平均の行長。固定テーブルでは、これはレコード長です。
`Packed`
  MySQL は文字列の最後から空白を除きます。これによって節約された パーセンテージを `Packed` は示します。
`Recordspace used`
  データファイルが使用されたパーセンテージ。
`Empty space`
  データファイルが使用されていないパーセンテージ。
`Blocks/Record`
  レコード毎のブロック数 (断片化レコードの構成数)。 これは固定形式テーブルでは常に1です。この値は可能な限 り 1.0 に留まります。これが大きすぎる場合は、`myisamchk` でテーブルを再配置 できます。 「4.4.6.10 テーブルの最適化」節参照.
`Recordblocks`
  使用されたブロック (links) 数。固定型式ではこれはレコード数と同じです。
`Deleteblocks`
  削除されたブロック (links) 数。
`Recorddata`
  データファイル中にある実際のユーザデータのバイト数。
`Deleted data`
  データファイル中にある削除された(unused)データのバイト数。
`Lost space`
  レコードがより短い長さに更新された場合、いくつかの領域が失われます。これ はそのような消失の全ての合計です。in bytes.
`Linkdata`
  動的形式の使用時、ブロックはポインタ(4〜7バイト)にリンクされます。`Linkdata`は そのポインタの全ての合計です。

テーブルが `pack_isam` で圧縮されているなら、`myisamchk -d` は それぞれのテーブルコラムに関する追加情報を出力します。 「4.7.4 myisampack, MySQL の圧縮された読み込み専用テーブルジェネレータ」節. を参照してください。 この情報例と説明記述の意味があります。

## 4.5 Database Administration Language Reference

### 4.5.1 `OPTIMIZE TABLE` 構文

    OPTIMIZE TABLE tbl_name[,tbl_name]...

`OPTIMIZE TABLE`は、テーブルの大部分を削除したり、可変長となっているテーブ ル(`VARCHAR`、`BLOB`もしくは`TEXT`フィールドを持つテーブル)に多く の変更を加えた場合に使用すべきです。 削除されたレコードはリンクリストで維持され、次の`INSERT`操作は、古いレコー ド位置を再利用します。 未使用領域を再生するために`OPTIMIZE TABLE`を使用することができます。

今のところ、`OPTIMIZE TABLE` は MyISAM と `BDB` テーブ ル上でだけ動作します。`BDB` テーブルでは、`OPTIMIZE TABLE` が現 在 `ANALYZE TABLE` にマップされます。 「4.5.2 `ANALYZE TABLE` Syntax」節参照。

`--skip-new` または `--safe-mode` で `mysqld` を起動するこ とで、他のテーブル型で optimize table を動作するようにできます。しかし、こ の場合 `OPTIMIZE TABLE` は `ALTER TABLE` にマップされるだけです。

`OPTIMIZE TABLE` は次の方法で動作します:

- テーブルが削除されているかレコードが分割する場合、テーブルを修復します。
- インデックスページがソートされていない場合、ソートします。
- 統計が更新されていない（そしてインデックスをソートすることで修復が行なわれ なかった）場合、それを更新します。

`MyISAM` テーブルの `OPTIMIZE TABLE` はテーブル上で `myisamchk --quick --check-changed-tables --sort-index --analyze` を 実行することと同等です。

注意: テーブルは `OPTIMIZE TABLE` 実行中はロックされます！

### 4.5.2 `ANALYZE TABLE` Syntax

    ANALYZE TABLE tbl_name[,tbl_name...]

Analyze and store the key distribution for the table. During the analyze the table is locked with a read lock. This works on `MyISAM` and `BDB` tables.

This is equivalent to running `myisamchk -a` on the table.

MySQL uses the stored key distribution to decide in which order tables should be joined when one does a join on something else than a constant.

The command returns a table with the following columns:

Column | Value
Table | Table name
Op | Always ``analyze''
Msg_type | One of `status`, `error`, `info` or `warning`.
Msg_text | The message.

You can check the stored key distribution with the `SHOW INDEX` command. 「4.5.5.1 Retrieving information about Database, Tables, Columns, and Indexes」節参照.

If the table hasn't changed since the last `ANALYZE TABLE` command, the table will not be analyzed again.

### 4.5.3 `FLUSH` 構文

    FLUSH flush_option [,flush_option]

`FLUSH` コマンドで MySQL が使用している内部キャッシュの いくつかをきれいに消すことができます。 `FLUSH` を実行するには、 RELOAD 権限がなければなりません。

`flush_option` には以下の内一つが指定できます：

`HOSTS` | ホストキャッシュテーブルを空にします。あなたのホストの IP アドレスを変えたり、`Host ... is blocked` というエラーメッセージが 出る場合はホストテーブルキャッシュを一度空にしなくてはなりません。 （指定したホストに対して `max_connect_errors` 以上の接続エラーが出る場合、 MySQL は何か起きたと推定し、そのホストからのいかなる接続要求も 拒否します。ホストテーブルキャッシュの消去は、再び接続を許すようにします。 「A.2.4 `Host '...' is blocked` Error」節参照.） `mysqld` を `-O max_connection_errors=999999999` 開始し、 このエラーメッセージを回避できます
`LOGS` | 標準のログファイルと更新ログファイルを 一度閉じて再び開きます。 もし更新ログファイルを拡張子無しで指定している場合、新しい更新ログファイルの 拡張子の番号は、一つ前のファイルより 1 増やした数になります。 ファイル名に拡張を使用した場合、MySQL は更新ログファイルを閉じて開きま す。 「4.9.3 更新ログ」節参照. This is the same thing as sending the `SIGHUP` signal to the `mysqld` server.
`PRIVILEGES` | `mysql` データベースの許可テーブルから、権限情報を再読込します。
`TABLES` | 全ての開いているテーブルを閉じます。使用中のテーブルに も close を強制します。
`[TABLE | TABLES] table_name [,table_name...]` | Flushes only the given tables.
`TABLES WITH READ LOCK` | 全ての開いているテーブルを閉じ、 `UNLOCK TABLES` を実行するまで全てのテーブルを読み込みロックします。 This is very convenient way to get backups if you have a file system, like Veritas,that can take snapshots in time.
`STATUS` | ほとんどのステータス変数を 0 にします。 This is something one should only use when debugging a query.

上に示したコマンドは、`mysqladmin` を使用しても実行できます。 `mysqladmin` の引数はそれぞれ、 `flush-hosts`, `flush-logs`, `reload`, `flush-tables` と なります。

Take also a look at the `RESET` command used with replication. 「4.10.6 レプリケーションに関連する SQL コマンド」節参照.

### 4.5.4 `KILL` 構文

    KILL thread_id

`thread_id` には、`mysqld` に接続して走っているスレッドの ID を 空白で区切って指定します。 `SHOW PROCESSLIST` コマンドで走っているスレッドを知ることができ、 `KILL thread_id` コマンドでスレッドを KILL できます。

もし process 権限があるなら、全てのスレッドを確認し、KILL 出来ます。 そうでなければ、自分のスレッドだけを、 確認し、KILL する事ができます。

`mysqladmin processlist` と `mysqladmin kill` をスレッドの 検査と KILL に使用できます。

In most cases it may take some time for the thread to die as the kill flag is only checked at specific intervals.

- In `SELECT`, `ORDER BY` and `GROUP BY` loops, the flag is checked after reading a block of rows. If the kill flag is set the statement is aborted
- When doing an `ALTER TABLE` the kill flag is checked before each block of rows are read from the original table. If the kill flag was set the command is aborted and the temporary table is deleted.
- When doing an `UPDATE TABLE` and `DELETE TABLE`, the kill flag is checked after each block read and after each updated or delete row. If the kill flag is set the statement is aborted. Note that if you are not using transactions, the changes will not be rolled back!
- `GET_LOCK()` will abort with `NULL`.
- An `INSERT DELAYED` thread will quickly flush all rows it has in memory and die.
- If the thread is in the table lock handler (state: `Locked`), the table lock will be quickly aborted.
- If the thread is waiting for free disk space in a `write` call, the write is aborted with an disk full error message.

### 4.5.5 `SHOW` 構文

       SHOW DATABASES [LIKE wild]
    or SHOW [OPEN] TABLES [FROM db_name] [LIKE wild]
    or SHOW [FULL] COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
    or SHOW INDEX FROM tbl_name [FROM db_name]
    or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
    or SHOW STATUS [LIKE wild]
    or SHOW VARIABLES [LIKE wild]
    or SHOW LOGS
    or SHOW [FULL] PROCESSLIST
    or SHOW GRANTS FOR user
    or SHOW CREATE TABLE table_name
    or SHOW MASTER STATUS
    or SHOW MASTER LOGS
    or SHOW SLAVE STATUS

`SHOW` はデータベース、テーブル、フィールド、サーバーについての情報を与えます。 `LIKE wild` が使用された場合、`wild` 文字列は通常の SQL ワイルドカード (``%'` と ``_'`) です。

#### 4.5.5.1 Retrieving information about Database, Tables, Columns, and Indexes

`tbl_name FROM db_name` の代わりに、`db_name.tbl_name` が使用できます。 これら二つは同じです：

    mysql> SHOW INDEX FROM mytable FROM mydb;
    mysql> SHOW INDEX FROM mydb.mytable;

`SHOW DATABASES` は MySQL サーバー上のデータベースを示します。 `mysqlshow` コマンドでも同じ情報が得られます。

`SHOW TABLES` は指定されたデータベースのテーブルを一覧表示します。 `mysqlshow db_name` コマンドでも同じ情報が得られます。

NOTE: もしユーザーにテーブルに対する権限が無い場合、 テーブルは `SHOW TABLES` や `mysqlshow db_name` の要求で 表示されません。

`SHOW OPEN TABLES` はテーブルキャッシュに現在オープン去れているテーブ ルを一覧表示します。 「5.4.6 MySQL はどのようにテーブルのオープン & クローズを行なうか？」節参照. `Comment` フィールドはテーブ ルが何回 `cached` と `in_use` になったかを知らせます。

`SHOW COLUMNS` は与えられたテーブルのフィールドを表示します。 `FULL` オプションを指定した場合、各フィールドに持つ権限も得られます。 もしそのフィールドの型が、あなたが `CREATE TABLE` 構文実行時に与えたものと 違う場合は、 MySQL は、フィールドの型をときおり変更することが あることに注意してください。 「6.5.3.1 暗黙のフィールド定義変更」節参照.

`DESCRIBE` 文は `SHOW COLUMNS` と似たような情報を提供します。 「6.6.2 `DESCRIBE` 構文 (フィールドについての情報を得る)」節参照.

`SHOW FIELDS` は `SHOW COLUMNS` の別名として使用され、 `SHOW KEYS` は `SHOW INDEX` の別名として使用されます。 テーブルのフィールドやインデックスは `mysqlshow db_name tbl_name` か `mysqlshow -k db_name tbl_name` でも見れます。

`SHOW INDEX` は ODBC でいう `SQLStatistics` に近い形式で、インデックスの情報を表示します。 以下の項目が返ります：

Column | 意味
`Table` | テーブル名
`Non_unique` | インデックスが重複を含まないなら 0
`Key_name` | インデックス名
`Seq_in_index` | インデックスの項目番号。1 から始まります。
`Column_name` | フィールド名。
`Collation` | どのようにこのフィールドがインデックス中で ソートされるか. MySQL ではこれは `A` (Ascending) か `NULL` (Not sorted) に なります。
`Cardinality` | インデックス中のユニークな値の数。 これは `isamchk -a` の実行で更新されます。
`Sub_part` | もしこのフィールドがインデックスに一部分だけ使用 している場合、そのインデックスに使用しているキャラクター数をしめす。 もしキー全 体がインデックスされているなら `NULL` 。
`Comment` | Various remarks. For now, it tells whether index is FULLTEXT or not.

Note that as the `Cardinality` is counted based on statistics stored as integers, it's not necessarily accurate for small tables.

#### 4.5.5.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` | テーブルの種類 「7 MySQL テーブル型」節参照.
`Row_format` | レコードの保存形式 (Fixed, Dynamic, or Compressed)
`Rows` | レコード数
`Avg_row_length` | レコードの平均長
`Data_length` | データファイルの大きさ
`Max_data_length` | データファイルの最大値
`Index_length` | インデックスファイルの大きさ
`Data_free` | 割り当てられたが使用されていないバイト数
`Auto_increment` | 次の autoincrement 値
`Create_time` | テーブル作成時刻
`Update_time` | 一番最後に更新された時刻
`Check_time` | 一番最後にチェックされた時刻
`Create_options` | `CREATE TABLE` で使用された拡張オプション
`Comment` | テーブル作成時につけられたコメント (あるいは、なぜこの テーブルにMySQL がアクセスできないかのいくつかの情報).

`InnoDB` tables will report the free space in the tablespace in the table comment.

#### 4.5.5.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      |
    +--------------------------+------------+

上に示したステータス変数は以下に示すの意味を持ちます：

Variable | Meaning
`Aborted_clients` | クライアントが接続を閉じる前に死んでしまったために中断されたコネクション数。 「A.2.9 Communication Errors / Aborted Connection」節参照.
`Aborted_connects` | MySQL サーバーに接続を試みて失敗した数。 「A.2.9 Communication Errors / Aborted Connection」節参照.
`Bytes_received` | クライアントから受信したバイト数
`Bytes_sent` | クライアントに送信したバイト数
`Com_xxxx` | Number of times the xxx commands has been executed.
`Connections` | MySQL サーバーに接続を試みた数
`Created_tmp_disk_tables` | ステートメント実行中に暗黙のうちに作成されたメモり内にある一時テーブルの数
`Created_tmp_tables` | Number of implicit temporary tables in memory created while executing statements.
`Created_tmp_files` | How many temporary files `mysqld` have created.
`Delayed_insert_threads` | Number of delayed insert handler threads in use.
`Delayed_writes` | Number of rows written with `INSERT DELAYED`.
`Delayed_errors` | Number of rows written with `INSERT DELAYED` for which some error occurred (probably `duplicate key`).
`Flush_commands` | `FLUSH` コマンドの実行回数
`Handler_delete` | Number of times a row was deleted from a table.
`Handler_read_first` | Number of times the first entry was read from an index. If this is high, it suggests that the server is doing a lot of full index scans, for example, `SELECT col1 FROM foo`, assuming that col1 is indexed.
`Handler_read_key` | Number of requests to read a row based on a key. If this is high, it is a good indication that your queries and tables are properly indexed.
`Handler_read_next` | Number of requests to read next row in key order. This will be incremented if you are querying an index column with a range constraint. This also will be incremented if you are doing an index scan.
`Handler_read_rnd` | Number of requests to read a row based on a fixed position. This will be high if you are doing a lot of queries that require sorting of the result.
`Handler_read_rnd_next` | Number of requests to read the next row in the datafile. This will be high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have.
`Handler_update` | Number of requests to update a row in a table.
`Handler_write` | Number of requests to insert a row in a table.
`Key_blocks_used` | The number of used blocks in the key cache.
`Key_read_requests` | The number of requests to read a key block from the cache.
`Key_reads` | The number of physical reads of a key block from disk.
`Key_write_requests` | The number of requests to write a key block to the cache.
`Key_writes` | The number of physical writes of a key block to disk.
`Max_used_connections` | The maximum number of connections in use simultaneously.
`Not_flushed_key_blocks` | Keys blocks in the key cache that has changed but hasn't yet been flushed to disk.
`Not_flushed_delayed_rows` | Number of rows waiting to be written in `INSERT DELAY` queues.
`Open_tables` | オープンされているテーブル数
`Open_files` | Number of files that are open.
`Open_streams` | Number of streams that are open (used mainly for logging).
`Opened_tables` | Number of tables that have been opened.
`Select_full_join` | Number of joins without keys (Should be 0).
`Select_full_range_join` | Number of joins where we used a range search on reference table.
`Select_range` | Number of joins where we used ranges on the first table. (It's normally not critical even if this is big.)
`Select_scan` | Number of joins where we scanned the first table.
`Select_range_check` | Number of joins without keys where we check for key usage after each row (Should be 0).
`Questions` | サーバーに送られたクエリの数
`Slave_open_temp_tables` | Number of temporary tables currently open by the slave thread
`Slow_launch_threads` | Number of threads that have taken more than `slow_launch_time` to connect.
`Slow_queries` | code{long_query_time} 以上に時間のかかったクエリの数 「4.9.5 The Slow Query Log」節参照.
`Sort_merge_passes` | Number of merges the sort has to do. If this value is large you should consider increasing `sort_buffer`.
`Sort_range` | Number of sorts that where done with ranges.
`Sort_rows` | Number of sorted rows.
`Sort_scan` | Number of sorts that where done by scanning the table.
`Table_locks_immediate` | Number of times a table lock was acquired immediately. Available after 3.23.33.
`Table_locks_waited` | Number of times a table lock could not be acquired immediately and a wait was needed. If this is high, and you have performance problems, you should first optimize your queries, and then either split your table(s) or use replication. Available after 3.23.33.
`Threads_cached` | Number of threads in the thread cache.
`Threads_connected` | 現在開いている接続数
`Threads_created` | Number of threads created to handle connections.
`Threads_running` | スリープ状態になっていないスレッドの数
`Uptime` | サーバーが走っている秒数

上についてのいくつかコメント：

- もし `Opened_tables` が大きければ、 `table_cache` 変数が小さすぎる のでしょう。
- もし `key_reads` が大きければ、 `key_cache` が少なすぎるでしょう。 キャッシュヒットレートは `key_reads`/`key_read_requests` で計算できます。
- If `Handler_read_rnd` is big, then you probably have a lot of queries that require MySQL to scan whole tables or you have joins that don't use keys properly.
- If `Threads_created` is big, you may want to increase the `thread_cache_size` variable.

#### 4.5.5.4 `SHOW VARIABLES`

    SHOW VARIABLES [LIKE wild]

`SHOW VARIABLES` は MySQL システム変数のいくつかの値を示します。 `mysqlshow variables` コマンドでも同じ情報が得られます。 もし標準値が適さないなら、ほとんどの変数を `mysqld` 起動時に コマンドラインのオプションとして与えることにより、変更できます。 「4.1.1 mysqld コマンド行オプション」節参照.

出力は以下のようになりますが、フォーマットや数はいくぶん違うでしょう：

    +-------------------------+---------------------------+
    | Variable_name           | Value                     |
    +-------------------------+---------------------------+
    | ansi_mode               | OFF                       |
    | back_log                | 50                        |
    | basedir                 | /my/monty/                |
    | bdb_cache_size          | 16777216                  |
    | bdb_log_buffer_size     | 32768                     |
    | bdb_home                | /my/monty/data/           |
    | bdb_max_lock            | 10000                     |
    | bdb_logdir              |                           |
    | bdb_shared_data         | OFF                       |
    | bdb_tmpdir              | /tmp/                     |
    | binlog_cache_size       | 32768                     |
    | concurrent_insert       | ON                        |
    | connect_timeout         | 5                         |
    | datadir                 | /my/monty/data/           |
    | delay_key_write         | ON                        |
    | delayed_insert_limit    | 100                       |
    | delayed_insert_timeout  | 300                       |
    | delayed_queue_size      | 1000                      |
    | flush                   | OFF                       |
    | flush_time              | 0                         |
    | have_bdb                | YES                       |
    | have_innodb             | YES                       |
    | have_raid               | YES                       |
    | have_ssl                | NO                        |
    | init_file               |                           |
    | interactive_timeout     | 28800                     |
    | join_buffer_size        | 131072                    |
    | key_buffer_size         | 16776192                  |
    | language                | /my/monty/share/english/  |
    | large_files_support     | ON                        |
    | log                     | OFF                       |
    | log_update              | OFF                       |
    | log_bin                 | OFF                       |
    | log_slave_updates       | OFF                       |
    | long_query_time         | 10                        |
    | low_priority_updates    | OFF                       |
    | lower_case_table_names  | 0                         |
    | max_allowed_packet      | 1048576                   |
    | max_binlog_cache_size   | 4294967295                |
    | max_connections         | 100                       |
    | max_connect_errors      | 10                        |
    | max_delayed_threads     | 20                        |
    | max_heap_table_size     | 16777216                  |
    | max_join_size           | 4294967295                |
    | max_sort_length         | 1024                      |
    | max_tmp_tables          | 32                        |
    | max_write_lock_count    | 4294967295                |
    | myisam_recover_options  | DEFAULT                   |
    | myisam_sort_buffer_size | 8388608                   |
    | net_buffer_length       | 16384                     |
    | net_read_timeout        | 30                        |
    | net_retry_count         | 10                        |
    | net_write_timeout       | 60                        |
    | open_files_limit        | 0                         |
    | pid_file                | /my/monty/data/donna.pid  |
    | port                    | 3306                      |
    | protocol_version        | 10                        |
    | record_buffer           | 131072                    |
    | query_buffer_size       | 0                         |
    | safe_show_database      | OFF                       |
    | server_id               | 0                         |
    | skip_locking            | ON                        |
    | skip_networking         | OFF                       |
    | skip_show_database      | OFF                       |
    | slow_launch_time        | 2                         |
    | socket                  | /tmp/mysql.sock           |
    | sort_buffer             | 2097116                   |
    | table_cache             | 64                        |
    | table_type              | MYISAM                    |
    | thread_cache_size       | 4                         |
    | thread_stack            | 65536                     |
    | tmp_table_size          | 1048576                   |
    | tmpdir                  | /tmp/                     |
    | version                 | 3.23.29a-gamma-debug      |
    | wait_timeout            | 28800                     |
    +-------------------------+---------------------------+

これらのオプションは以下のように決めてください。 buffer size, buffer length, stack size は byte 単位で与えます。 これらの値の後ろに ``K'` や ``M'` を追加すると、キロバイト、 メガバイトになります。 例えば、`16M` は16メガバイトを示します。大文字小文字の区別はなく、 `16M` と `16m` は同じ意味になります。

``ansi_mode`.`
  もし `mysqld` が `--ansi` オプションで起動されているなら、`ON`. 「1.4.3 ANSI モードでの MySQL の実行」節参照.
``back_log``
  MySQL が持てる未解決の接続要求の数です。これは MySQL スレッドがものすごく多くの接続要求をとても短い時間に得た時に、働き ます。接続のチェックと新しいスレッドの開始はメインスレッドにすこし時間 (しかしほんのわずか)がかかります。back_log は、MySQL が瞬間的に新 しい要求への回答を停止する前に、この短い時間の間にスタックできる接続数です。 短い期間に多くの接続を期待する場合にだけ、これを増加する必要があります。 いいかえるなら、これは TCP/IP 接続の入力 listen キューのサイズです。 オペレーティングシステムはこのキューの大きさを制限しています。 UNIX システムコール `listen(2)` のマニュアルページに、さらに詳細があります。 この値を最大限にしたい場合、お使いのOSのドキュメントを見てください。 `back_log` をこのOSの制限値より多く取ってもは全く効果ありません。
``basedir``
  The value of the `--basedir` option.
``bdb_cache_size``
  The buffer that is allocated to cache index and rows for `BDB` tables. If you don't use `BDB` tables, you should start `mysqld` with `--skip-bdb` to not waste memory for this cache.
``bdb_log_buffer_size``
  The buffer that is allocated to cache index and rows for `BDB` tables. If you don't use `BDB` tables, you should set this to 0 or start `mysqld` with `--skip-bdb` to not waste memory for this cache.
``bdb_home``
  The value of the `--bdb-home` option.
``bdb_max_lock``
  The maximum number of locks (1000 by default) you can have active on a BDB table. You should increase this if you get errors of type `bdb: Lock table is out of available locks` or `Got error 12 from ...` when you have do long transactions or when `mysqld` has to examine a lot of rows to calculate the query.
``bdb_logdir``
  The value of the `--bdb-logdir` option.
``bdb_shared_data``
  Is `ON` if you are using `--bdb-shared-data`.
``bdb_tmpdir``
  The value of the `--bdb-tmpdir` option.
``binlog_cache_size`. The size of the cache to hold the SQL`
  statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance. 「6.7.1 `BEGIN/COMMIT/ROLLBACK` 構文」節参照.
``character_set``
  The default character set.
``character_sets``
  The supported character sets.
``concurrent_inserts``
  もし `ON` (これはデフォルトです) なら、MySQL は、 `SELECT` クエリが実行されている `MyISAM` テーブルに対して、 同時に `INSERT` が使用できるようにします。 このオプションは `mysqld` のオプションに `--safe` か `--skip-new` を 指定することで `OFF` にできます。
``connect_timeout``
  `mysqld` サーバーが接続パケットを待つ秒数。 (`Bad handshake` を返すま での秒数)
``datadir``
  The value of the `--datadir` option.
``delay_key_write``
  もし enabled であれば(これがデフォルト)、MySQL は `CREATE TABLE` 文の `DELAY_KEY_WRITE` オプションを尊重します。 `DELAY_KEY_WRITE`オプションを指定されて作られたテーブルのキーバッファは、 毎回のインデックスの更新にはフラッシュされず、ただテーブルが閉じられたときにだけ フラッシュされます。 これはキーの書き出しを速くしますが、もしこれを使用するなら、 全てのテーブルを `myisamchk --fast --force` で自動的に検査するようにすべき です。 もし `mysqld` を `--delay-key-write_for_all_tables` オプション付きで 起動した場合、これは、全てのテーブルが `delay_key_write` オプション指定されて 作成されたものとして扱われる事に注意してください。 このフラグは、`mysqld` を `--skip-new` や `--safe-mode` オプション で起動すれば無効にすることも出来ます。
``delayed_insert_limit``
  `delayed_insert_limit` 個のレコードを挿入した後、 `INSERT DELAYED` ハンドラーは待たされている `SELECT` 文がないかチェックします。 もしあるなら、 挿入を続ける前にそれらの実行を許します。
``delayed_insert_timeout``
  どれぐらい `INSERT DELAYED` スレッドが `INSERT` 文を待つべきか。
``delayed_queue_size``
  What size queue (in rows) should be allocated for handling `INSERT DELAYED`. If the queue becomes full, any client that does `INSERT DELAYED` will wait until there is room in the queue again.
``flush``
  This is `ON` if you have started MySQL with the `--flush` option.
``flush_time``
  これがもし、非ゼロにセットされたなら、毎 `flush_time` 秒ごとに 全てのテーブルが閉じられます。 (リソースの解放とDiskへのsyncのために) We only recommend this option on Win95, Win98, or on systems where you have very little resources.
``have_bdb``
  `YES` if `mysqld` supports Berkeley DB tables. `DISABLED` if `--skip-bdb` is used.
``have_innodb``
  `YES` if `mysqld` supports InnoDB tables. `DISABLED` if `--skip-innodb` is used.
``have_raid``
  `YES` if `mysqld` supports the `RAID` option.
``have_ssl``
  `YES` if `mysqld` supports SSL (encryption) on the client/server protocol.
``init_file``
  サーバー起動時に、`--init-file` オプションに与えたファイルの名前です。 このファイルには、サーバー起動時に実行したい SQL 文を書いておきます。
``interactive_timeout``
  The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the `CLIENT_INTERACTIVE` option to `mysql_real_connect()`. See also `wait_timeout`.
``join_buffer_size``
  このバッファは(インデックス無しの)完全な結合に使用されます。それは2つの テーブル間の完全な結合ごとに1回割り当てられます。インデックスの追加がで きない時、より速い完全な結合を得るために、これを増加してください。通常、 速い結合を得る一番良い方法は、インデックスを追加することです。
``key_buffer_size``
  インデックス・ブロックはバッファされ、そして全てのスレッドに共有されます。 `key_buffer_size` はインデックス・ブロックのためのバッファ・サイズです。 Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common. If you, however, make this too big (more than 50% of your total memory?) your system may start to page and become REALLY slow. Remember that because MySQL does not cache data read, that you will have to leave some room for the OS filesystem cache. You can check the performance of the key buffer by doing `show status` and examine the variables `Key_read_requests`, `Key_reads`, `Key_write_requests`, and `Key_writes`. The `Key_reads/Key_read_request` ratio should normally be < 0.01. The `Key_write/Key_write_requests` is usually near 1 if you are using mostly updates/deletes but may be much smaller if you tend to do updates that affect many at the same time or if you are using `delay_key_write`. 「4.5.5 `SHOW` 構文」節参照. To get even more speed when writing many rows at the same time, use `LOCK TABLES`. 「6.7.2 `LOCK TABLES/UNLOCK TABLES` 構文」節参照.
``language``
  The language used for error messages.
``large_file_support``
  If `mysqld` was compiled with options for big file support.
``locked_in_memory``
  If `mysqld` was locked in memory with `--memlock`
``log``
  If logging of all queries is enabled.
``log_update``
  If the update log is enabled.
``log_bin``
  If the binary log is enabled.
``log_slave_updates``
  If the updates from the slave should be logged.
``long_query_time``
  もしあるクエリがこの値(秒)より時間がかかれば、`Slow_queries` カウンター が増やされます。 If you are using `--log-slow-queries`, the query will be logged to the slow query logfile. 「4.9.5 The Slow Query Log」節参照.
``lower_case_table_names``
  If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. 「6.1.3 名前のケース依存性」節参照.
``max_allowed_packet``
  一つのパケットの最大サイズ。メッセージバッファは `net_buffer_length` バイト に初期化されますが、 `max_allowed_packet`まで大きくすることができます。このデフォルト値は、 大きなパケット、間違ったパケットをを受けるには小さい値です。 大きな `BLOB` を使用している場合は、これを増加する必要があります。使用した い最大の `BLOB` と同じくらい大きくするべきです。 The current protocol limits `max_allowed_packet` to 16M.
``max_binlog_cache_size``
  If a multi-statement transaction requires more than this amount of memory, one will get the error "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage".
``max_binlog_size``
  Available after 3.23.33. If a write to the binary (replication) log exceeds the given value, rotate the logs. You cannot set it to less than 1024 bytes, or more than 1 GB. Default is 1 GB.
``max_connections``
  許される同時クライアントの数。これを増加する場合は、`mysqld` が持つファイ ルディスクリプタの数を増やす必要があるでしょう。 後述のファイルデスクリプターの制限の説明を参照のこと。 「A.2.5 `Too many connections` Error」節参照.
``max_connect_errors``
  もしあるホストからの接続中断がこの値を以上になった場合、これ以後、 そのホストからの接続を拒絶します。`FLUSH HOSTS` コマンドで ホストの拒否を解除できます。
``max_delayed_threads``
  この値を超えて `INSERT DELAYED` を扱うスレッドを起動できません。 もし全ての `INSERT DELAYED` スレッドが使用されていて、さらに新しいテーブルに データを挿入しようとすると、そのレコードは `DELAYED` が与えられていない 場合と同様に挿入されます。
``max_heap_table_size``
  Don't allow creation of heap tables bigger than this.
``max_join_size``
  `max_join_size` より多いレコードを触るとエラーが返ります。長い時間をかけて 百万行を返すような `WHERE` なしの結合を作成するようなユーザを持って いる場合にこれを設定してください。
``max_sort_length``
  `BLOB` または `TEXT` 項目上でソートする時に使用するバイト数。 (最初の `max_sort_length` バイトだけがそれぞれの値で使用でき、残りは無視さ れます)
``max_user_connections``
  The maximum number of active connections for a single user (0 = no limit).
``max_tmp_tables``
  (このオプションはまだなにも行いません). クライアントが同時にオープンできるテーブル数の最大値。
``max_write_lock_count``
  After this many write locks, allow some read locks to run in between.
``myisam_recover_options``
  The value of the `--myisam-recover` option.
``myisam_sort_buffer_size``
  The buffer that is allocated when sorting the index when doing a `REPAIR` or when creating indexes with `CREATE INDEX` or `ALTER TABLE`.
``myisam_max_extra_sort_file_size`.`
  If the creating of the temporary file for fast index creation would be this much bigger than using the key cache, then prefer the key cache method. This is mainly used to force long character keys in large tables to use the slower key cache method to create the index. NOTE that this parameter is given in megabytes!
``myisam_max_sort_file_size``
  The maximum size of the temporary file MySQL is allowed to use while recreating the index (during `REPAIR`, `ALTER TABLE` or `LOAD DATA INFILE`. If the file size would be bigger than this, the index will be created through the key cache (which is slower). NOTE that this parameter is given in megabytes!
``net_buffer_length``
  通信バッファがクエリ間でこのサイズにリセットされます。これは通常は変更す べきではありませんが、とても小さなメモリしかない場合は、これを期待される クエリのサイズに設定してください。 ( これは、クライアントから送られてくるSQL文の長さ分あればいいでしょう。 もし構文がこの値をこえた場合、バッファは自動的に大きくなります。 ただし `max_allowed_packet` バイトまでです)
``net_read_timeout``
  Number of seconds to wait for more data from a connection before aborting the read. Note that when we don't expect data from a connection, the timeout is defined by `write_timeout`. See also `slave_read_timeout`.
``net_retry_count``
  If a read on a communication port is interrupted, retry this many times before giving up. This value should be quite high on `FreeBSD` as internal interrupts are sent to all threads.
``net_write_timeout``
  Number of seconds to wait for a block to be written to a connection before aborting the write.
``open_files_limit``
  If this is not 0, then `mysqld` will use this value to reserve file descriptors to use with `setrlimit()`. If this value is 0 then `mysqld` will reserve `max_connections*5` or `max_connections + table_cache*2` (whichever is larger) number of files. You should try increasing this if `mysqld` gives you the error 'Too many open files'.
``pid_file``
  The value of the `--pid-file` option.
``port``
  The value of the `--port` option.
``protocol_version``
  The protocol version used by the MySQL server.
``record_buffer``
  順序スキャンを行う各スレッドが、スキャンするテーブル毎に、このサイズのバッ ファを割り当てます。多くの順序スキャンを行う場合は、これを増加させてくだ さい。
``record_rnd_buffer``
  When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of `record_buffer`.
``query_buffer_size``
  The initial allocation of the query buffer. If most of your queries are long (like when inserting blobs), you should increase this!
``safe_show_databases``
  Don't show databases for which the user doesn't have any database or table privileges. This can improve security if you're concerned about people being able to see what databases other users have. See also `skip_show_databases`.
``server_id``
  The value of the `--server-id` option.
``skip_locking``
  Is OFF if `mysqld` uses external locking.
``skip_networking``
  Is ON if we only allow local (socket) connections.
``skip_show_databases``
  これは、 `PROCESS_PRIV` 権限を持っていないユーザーが `SHOW DATABASES` する事を阻止します。 もし、他人のデータベースや テーブルを見ようとする人がいる事を、あなたが心配するならば、 これはセキュリティを強化できます。 See also `safe_show_databases`.
``slave_read_timeout``
  Number of seconds to wait for more data from a master/slave connection before aborting the read.
``slow_launch_time``
  If creating the thread takes longer than this value (in seconds), the `Slow_launch_threads` counter will be incremented.
``socket``
  The Unix socket used by the server.
``sort_buffer``
  ソートを行う必要がある各スレッドがこのサイズのバッファを割り当てます。よ り速い `ORDER BY` または `GROUP BY` のためにはこれを増やしてく ださい。 「A.4.4 MySQL が一時ファイルを格納する場所」節参照.
``table_cache``
  全てのスレッドについてのオープンテーブルの数。これを増加する場合は、 `mysqld`が要求するオープンファイルディスクリプタの数も 増加することに注意しないといけません。 MySQL はユニークテーブル毎に2つのファイルディスクリプタを必要と します。 See below for comments on file descriptor limits. You can check if you need to increase the table cache by checking the `Opened_tables` variable. 「4.5.5 `SHOW` 構文」節参照. If this variable is big and you don't do `FLUSH TABLES` a lot (which just forces all tables to be closed and reopenend), then you should increase the value of this variable. Make sure that your operating system can handle the number of open file descriptors implied by the `table_cache` setting. If `table_cache` is set too high, MySQL may run out of file descriptors and refuse connections, fail to perform queries, and be very unreliable. テーブルキャッシュがどのように働くかはこちらを参照 「5.4.6 MySQL はどのようにテーブルのオープン & クローズを行なうか？」節.
``table_type``
  The default table type
``thread_cache_size``
  How many threads we should keep in a cache for reuse. When a client disconnects, the client's threads are put in the cache if there aren't more than `thread_cache_size` threads from before. All new threads are first taken from the cache, and only when the cache is empty is a new thread created. This variable can be increased to improve performance if you have a lot of new connections. (Normally this doesn't give a notable performance improvement if you have a good thread implementation.) By examing the difference between the `Connections` and `Threads_created` you can see how efficient the current thread cache is for you.
``thread_concurrency``
  On Solaris, `mysqld` will call `thr_setconcurrency()` with this value. `thr_setconcurrency()` permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.
``thread_stack``
  各スレッドのスタックの大きさ。`crash-me` によって検出される多く の制限がこれに依存します。デフォルトでは、通常のオペレーションに対して 十分とってあります。 「5.1.4 The MySQL Benchmark Suite」節参照.
``timezone``
  The timezone for the server.
``tmp_table_size``
  メモリー内の 一時テーブルがこの値を超えようとした場合、MySQL は 自動的に、これを、disk ベースの `MyISAM` テーブルに変換します。 多くの先進的な `GROUP BY` クエリを行う場合は、 この `tmp_table_size` を増加してください。
``tmpdir``
  The directory used for temporary files and temporary tables.
``version``
  The version number for the server.
``wait_timeout``
  サーバーがコネクションを閉じるまでにアクティブなコネクションを待つ秒数。 See also `interactive_timeout`.

The manual section that describes tuning MySQL contains some information of how to tune the above variables. 「5.5.2 サーバーパラメーターのチューニング」節参照.

#### 4.5.5.5 `SHOW LOGS`

`SHOW LOGS` shows you status information about existing log files. It currently only displays information about Berkeley DB log files.

- `File` shows the full path to the log file
- `Type` shows the type of the log file (`BDB` for Berkeley DB log files)
- `Status` shows the status of the log file (`FREE` if the file can be removed, or `IN USE` if the file is needed by the transaction subsystem)

#### 4.5.5.6 `SHOW PROCESSLIST`

`SHOW PROCESSLIST` はどのスレッドが走っているかを表示します。 `mysqlshow processlist` コマンドでも同じ情報が得られます。 もし process 権限があるなら、全てのスレッドがみれます。 しかし権限がないなら、自分のスレッドしか見れません。 「4.5.4 `KILL` 構文」節参照. `FULL` オプションを使用しない場合、各クエリの最初の100文字だけが表示 されます。

This command is very useful if you get the 'too many connections' error message and want to find out what's going on. MySQL reserves one extra connection for a client with the `Process_priv` privilege to ensure that you should always be able to login and check the system (assuming you are not giving this privilege to all your users).

#### 4.5.5.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 |
    +---------------------------------------------------------------------+

#### 4.5.5.8 `SHOW CREATE TABLE`

Shows a `CREATE TABLE` statement that will create the given 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` will quote table and column names according to `SQL_QUOTE_SHOW_CREATE` option. 「5.5.6 `SET` 構文」節.

## 4.6 MySQL Localization and International Usage

### 4.6.1 データとソートに使用されるキャラクターセット

デフォルトでは、MySQL は スウェーデン語／フィンランド語に一致する ISO8859-1 (Latin1) キャラクターセットをソートに使用します。これは USA と西 ヨーロッパに適したキャラクターセットです。

All standard MySQL binaries are compiled with `--with-extra-charsets=complex`. This will add code to all standard programs to be able to handle `latin1` and all multi-byte character sets within the binary. Other character sets will be loaded from a character-set definition file when needed.

キャラクターセットは名前として許される文字と、`ORDER BY` と `GROUP BY` コマンドによってソートされる方法を決定します。 キャラクターセットは、名前として使用してもよい文字と `SELECT` 構文中の `ORDER BY` と `GROUP BY` コマンドを用いたソート方法を決定します。

You can change the character set with the `--default-character-set` option when you start the server. The character sets available depend on the `--with-charset=charset` and `--with-extra-charset= list-of-charset | complex | all` options to `configure`, and the character set configuration files listed in ``SHAREDIR/charsets/Index'`. 「2.3.3 典型的な `configure` オプション」節参照.

もし MySQL が実行中にキャラクタ・セットを変更するならば、 （これはソートの順番も変わります）、全てのテーブルに対して myisamchk -r -q を実行しなくてはなりません。 インデックスがただしい順番で並んでいないかもしれないからです。

クライアントが MySQL サーバに接続したとき、サーバは使用している デフォルトのキャラクタ・セットをクライアントに送ります。 これを受け取ったクライアントは、キャラクタセットを切り替えます。

SQL クエリの文字列をエスケープする場合には、 `mysql_real_escape_string()` を 使用するべきです。 `mysql_real_escape_string()` は、最初のパラメタとして MySQL へのコネクション・ハンドルを与える以外は、 古い `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.6.2 Non-English Error Messages

`mysqld` は次の言語でエラーメッセージを提供できます: チェコ語, デンマーク語, オランダ語, 英語(デフォルト), Estonia, フランス語, ドイツ語, ギリシャ語, ハンガリー語, イタリア語, 日本語, 韓国語, ノルウェー語, 新ノルウェー 語,ポーランド語, ポルトガル語, スペイン語そしてスウェーデン語。

ある言語で `mysqld` を開始するためには `--language=lang` また は `-L lang` スイッチの一つを使います:

    shell> mysqld --language=swedish

or:

    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.6.3 新しいキャラクターセットの追加

他のキャラクタ・セットを MySQL に追加するには、 以下の手順で行ないます。

そのキャラクタセットが、simple か complex かを決めます。 もしそのキャラクタ・セットがソートを行なうために特別な文字参照の ルーチンを必要としなくて、マルチバイト文字のサポートも必要としないのであれば、 そのキャラクタ・セットは simple です。 もしどちらかの特徴を必要とするのであれば、それは complex です。

例えば、`latin1` と `danish` は simple キャラクタ・セットで、 `big5` や `czech` は complex キャラクタ・セットです。

以下のセクションでは、あなたがキャラクタ・セットに `MYSET` という名前を つけていると仮定します。

simple complex キャラクタ・セットの場合には以下のようにします：

1. MYSET を ``sql/share/charsets/Index'` ファイルの最後に追加。 一意な番号を与えます。
2. ``sql/share/charsets/MYSET.conf'` ファイルを作成. (``sql/share/charsets/latin1.conf'` をベースにしてよいでしょう). The syntax for the file very simple:
   - Comments start with a '#' character and proceed to the end of the line.
   - Words are separated by arbitrary amounts of whitespace.
   - When defining the character set, every word must be a number in hexadecimal format
   - The `ctype` array takes up the first 257 words. The `to_lower`, `to_upper` and `sort_order` arrays take up 256 words each after that.
   「4.6.4 The character definition arrays」節参照.
3. Add the character set name to the `CHARSETS_AVAILABLE` and `COMPILED_CHARSETS` lists in `configure.in`.
4. Reconfigure, recompile, and test.

complex キャラクタ・セットの場合には以下のようにします：

1. ``strings/ctype-MYSET.c'` ファイルを MySQL のソースディレクトリ以下 に作成します。
2. MYSET を ``sql/share/charsets/Index'` ファイルの最後に追加。 一意な番号を与えます。
3. 必要な定義されるものを調べるために、既存の ``ctype-*.c'` ファイルの一つを見てく ださい。このファイル中で使用する配列の名前は、 `ctype_MYSET`, `to_lower_MYSET` のようにしなければいけないことに注意し てください。 This corresponds to the arrays in the simple character set. 「4.6.4 The character definition arrays」節参照. For a complex character set
4. ``ctype-*.c'` ファイルの先頭付近に、以下のようなコメントを書きます：

       /*
        * 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 ライブラリに自動的に キャラクタセットを含めるために、このコメントを使用します。 The strxfrm_multiply and mbmaxlen lines will be explained in the following sections. Only include them if you the string collating functions or the multi-byte character set functions, respectively.
5. 以下の関数を作成しなくてはなりません：
   - `my_strncoll_MYSET()`
   - `my_strcoll_MYSET()`
   - `my_strxfrm_MYSET()`
   - `my_like_range_MYSET()`
   「4.6.5 String Collating Support」節参照.
6. キャラクタ・セット名を、`configure.in` 中の `CHARSETS_AVAILABLE` と `COMPILED_CHARSETS` に追加します。
7. Reconfigure, recompile, and test.

The file ``sql/share/charsets/README'` includes some more instructions.

If you want to have the character set included in the MySQL distribution, mail a patch to internals@lists.mysql.com.

### 4.6.4 The character definition arrays

`to_lower[]` と `to_upper[]` は、それぞれのキャラクターセットに於ける 大文字、小文字の対応を定義した、単純な配列です。 例えば：

    to_lower['A'] should contain 'a'
    to_upper['a'] should contain 'A'

`sort_order[]` は文字がどのようにソートされるべきかのマップです。多くのセッ トでは、これは `to_upper[]` と同じです (ケース非依存ソート)。 MySQL は `sort_order[character]` の値を元に文字をソートします。 For more complicated sorting rules, see the discussion of string collating below. 「4.6.5 String Collating Support」節参照.

`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.6.5 String Collating Support

If the sorting rules for your language are too complex to be handled with the simple `sort_order[]` table, you need to use the string collating functions.

Right now the best documentation on this is the character sets that are already implemented. Look at the big5, czech, gbk, sjis, and tis160 character sets for examples.

You must specify the `strxfrm_multiply_MYSET=N` value in the special comment at the top of the file. `N` should be set to the maximum ratio the strings may grow during `my_strxfrm_MYSET` (it must be a positive integer).

### 4.6.6 マルチバイト文字のサポート

If your want to add support for a new character set that includes multi-byte characters, you need to use the multi-byte character functions.

Right now the best documentation on this is the character sets that are already implemented. Look at the euc_kr, gb2312, gbk, sjis and ujis character sets for examples. These are implemented in the `ctype-'charset'.c` files in the ``strings'` directory.

You must specify the `mbmaxlen_MYSET=N` value in the special comment at the top of the source file. `N` should be set to the size in bytes of the largest character in the set.

## 4.7 MySQL Server-Side Scripts and Utilities

### 4.7.1 Overview of the Server-Side Scripts and Utilities

All MySQL clients that communicate with the server using the `mysqlclient` library use the following environment variables:

Name | Description
`MYSQL_UNIX_PORT` | The default socket; used for connections to `localhost`
`MYSQL_TCP_PORT` | The default TCP/IP port
`MYSQL_PWD` | The default password
`MYSQL_DEBUG` | Debug-trace options when debugging
`TMPDIR` | The directory where temporary tables/files are created

Use of `MYSQL_PWD` is insecure. 「4.2.7 MySQL サーバーに接続」節参照.

The ``mysql'` client uses the file named in the `MYSQL_HISTFILE` environment variable to save the command-line history. The default value for the history file is ``$HOME/.mysql_history'`, where `$HOME` is the value of the `HOME` environment variable. 「H Environment Variables」節参照.

All MySQL programs take many different options. However, every MySQL program provides a `--help` option that you can use to get a full description of the program's different options. For example, try `mysql --help`.

You can override default options for all standard client programs with an option file. 「4.1.2 my.cnf オプションファイル」節.

The list below briefly describes the MySQL programs:

`myisamchk`
  Utility to describe, check, optimize, and repair MySQL tables. Because `myisamchk` has many functions, it is described in its own chapter. 「4 MySQL Database Administration」節参照.
`make_binary_distribution`
  Makes a binary release of a compiled MySQL. This could be sent by FTP to ``/pub/mysql/Incoming'` on `support.mysql.com` for the convenience of other MySQL users.
`msql2mysql`
  A shell script that converts `mSQL` programs to MySQL. It doesn't handle all cases, but it gives a good start when converting.
`mysqlaccess`
  A script that checks the access privileges for a host, user, and database combination.
`mysqladmin`
  Utility for performing administrative operations, such as creating or dropping databases, reloading the grant tables, flushing tables to disk, and reopening log files. `mysqladmin` can also be used to retrieve version, process, and status information from the server. 「4.8.3 mysqladmin, MySQL サーバーの管理」節参照.
`mysqlbug`
  The MySQL bug report script. This script should always be used when filing a bug report to the MySQL list.
`mysqld`
  The SQL daemon. This should always be running.
`mysqldump`
  Dumps a MySQL database into a file as SQL statements or as tab-separated text files. Enhanced freeware originally by Igor Romanenko. 「4.8.5 mysqldump, データベースとテーブルから、構造とデータをダンプ」節参照.
`mysqlimport`
  Imports text files into their respective tables using `LOAD DATA INFILE`. 「4.8.7 mysqlimport, テキストファイルからデータを取り込む」節参照.
`mysqlshow`
  Displays information about databases, tables, columns, and indexes.
`mysql_install_db`
  Creates the MySQL grant tables with default privileges. This is usually executed only once, when first installing MySQL on a system.
`replace`
  A utility program that is used by `msql2mysql`, but that has more general applicability as well. `replace` changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings. For example, this command swaps `a` and `b` in the given files:

      shell> replace a b b a -- file1 file2 ...

### 4.7.2 safe_mysqld, the wrapper around mysqld

`safe_mysqld` is the recommended way to start a `mysqld` daemon on Unix. `safe_mysqld` adds some safety features such as restarting the server when an error occurs and logging run-time information to a log file.

If you don't use `--mysqld=#` or `--mysqld-version=#` `safe_mysqld` will use an executable named `mysqld-max` if it exists. If not, `safe_mysqld` will start `mysqld`. This makes it very easy to test to use `mysqld-max` instead of `mysqld`; Just copy `mysqld-max` to where you have `mysqld` and it will be used.

Normally one should never edit the `safe_mysqld` script, but instead put the options to `safe_mysqld` in the `[safe_mysqld]` section in the `my.cnf` file. `safe_mysqld` will read all options from the `[mysqld]`, `[server]` and `[safe_mysqld]` sections from the option files. 「4.1.2 my.cnf オプションファイル」節参照.

Note that all options on the command line to `safe_mysqld` are passed to `mysqld`. If you wants to use any options in `safe_mysqld` that `mysqld` doesn't support, you must specify these in the option file.

Most of the options to `safe_mysqld` are the same as the options to `mysqld`. 「4.1.1 mysqld コマンド行オプション」節参照.

`safe_mysqld` supports the following options:

`--basedir=path`
`--core-file-size=#`
  Size of the core file `mysqld` should be able to create. Passed to `ulimit -c`.
`--datadir=path`
`--defaults-extra-file=path`
`--defaults-file=path`
`--err-log=path`
`--ledir=path`
  Path to `mysqld`
`--log=path`
`--mysqld=mysqld-version`
  Name of the `mysqld` version in the `ledir` directory you want to start.
`--mysqld-version=version`
  Similar to `--mysqld=` but here you only give the suffix for `mysqld`. For example if you use `--mysqld-version=max`, `safe_mysqld` will start the `ledir/mysqld-max` version. If the argument to `--mysqld-version` is empty, `ledir/mysqld` will be used.
`--no-defaults`
`--open-files-limit=#`
  Number of files `mysqld` should be able to open. Passed to `ulimit -n`. Note that you need to start `safe_mysqld` as root for this to work properly!
`--pid-file=path`
`--port=#`
`--socket=path`
`--timezone=#`
  Set the timezone (the `TZ`) variable to the value of this parameter.
`--user=#`

The `safe_mysqld` script is written so that it normally is able to start a server that was installed from either a source or a binary version of MySQL, even if these install the server in slightly different locations. `safe_mysqld` expects one of these conditions to be true:

- The server and databases can be found relative to the directory from which `safe_mysqld` is invoked. `safe_mysqld` looks under its working directory for ``bin'` and ``data'` directories (for binary distributions) or for ``libexec'` and ``var'` directories (for source distributions). This condition should be met if you execute `safe_mysqld` from your MySQL installation directory (for example, ``/usr/local/mysql'` for a binary distribution).
- If the server and databases cannot be found relative to the working directory, `safe_mysqld` attempts to locate them by absolute pathnames. Typical locations are ``/usr/local/libexec'` and ``/usr/local/var'`. The actual locations are determined when the distribution was built from which `safe_mysqld` comes. They should be correct if MySQL was installed in a standard location.

Because `safe_mysqld` will try to find the server and databases relative to its own working directory, you can install a binary distribution of MySQL anywhere, as long as you start `safe_mysqld` from the MySQL installation directory:

    shell> cd mysql_installation_directory
    shell> bin/safe_mysqld &

If `safe_mysqld` fails, even when invoked from the MySQL installation directory, you can modify it to use the path to `mysqld` and the pathname options that are correct for your system. Note that if you upgrade MySQL in the future, your modified version of `safe_mysqld` will be overwritten, so you should make a copy of your edited version that you can reinstall.

### 4.7.3 mysqld_multi, program for managing multiple MySQL servers

`mysqld_multi` is meant for managing several `mysqld` processes running in different UNIX sockets and TCP/IP ports.

The program will search for group(s) named [mysqld#] from my.cnf (or the given --config-file=...), where # can be any positive number starting from 1. These groups should be the same as the usual `[mysqld]` group (e.g. options to mysqld, see MySQL manual for detailed information about this group), but with those port, socket etc. options that are wanted for each separate `mysqld` processes. The number in the group name has another function; it can be used for starting, stopping, or reporting some specific `mysqld` servers with this program. See the usage and options below for more information.

    Usage: mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
    or     mysqld_multi [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]

The GNR above means the group number. You can start, stop or report any GNR, or several of them at the same time. (See --example) The GNRs list can be comma separated, or a dash combined, of which the latter means that all the GNRs between GNR1-GNR2 will be affected. Without GNR argument all the found groups will be either started, stopped, or reported. Note that you must not have any white spaces in the GNR list. Anything after a white space is ignored.

`mysqld_multi` supports the following options:

`--config-file=...`
  Alternative config file. NOTE: This will not affect this program's own options (group `[mysqld_multi]`), but only groups [mysqld#]. Without this option everything will be searched from the ordinary my.cnf file.
`--example`
  Give an example of a config file.
`--help`
  Print this help and exit.
`--log=...`
  Log file. Full path to and the name for the log file. NOTE: If the file exists, everything will be appended.
`--mysqladmin=...`
  `mysqladmin` binary to be used for a server shutdown.
`--mysqld=...`
  `mysqld` binary to be used. Note that you can give `safe_mysqld` to this option also. The options are passed to `mysqld`. Just make sure you have `mysqld` in your environment variable `PATH` or fix `safe_mysqld`.
`--no-log`
  Print to stdout instead of the log file. By default the log file is turned on.
`--password=...`
  Password for user for `mysqladmin`.
`--tcp-ip`
  Connect to the MySQL server(s) via the TCP/IP port instead of the UNIX socket. This affects stopping and reporting. If a socket file is missing, the server may still be running, but can be accessed only via the TCP/IP port. By default connecting is done via the UNIX socket.
`--user=...`
  MySQL user for `mysqladmin`.
`--version`
  Print the version number and exit.

Some notes about `mysqld_multi`:

- Make sure that the MySQL user, who is stopping the `mysqld` services (e.g using the `mysqladmin`) have the same password and username for all the data directories accessed (to the 'mysql' database) And make sure that the user has the 'Shutdown_priv' privilege! If you have many data- directories and many different 'mysql' databases with different passwords for the MySQL 'root' user, you may want to create a common 'multi_admin' user for each using the same password (see below). Example how to do it:

      shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
      "GRANT SHUTDOWN ON *.* TO multi_admin@localhost IDENTIFIED BY 'multipass'"
       「4.2.5  特権システムはどのように動くか？」節参照.

  You will have to do the above for each `mysqld` running in each data directory, that you have (just change the socket, -S=...)
- `pid-file` is very important, if you are using `safe_mysqld` to start `mysqld` (e.g. --mysqld=safe_mysqld) Every `mysqld` should have its own `pid-file`. The advantage using `safe_mysqld` instead of `mysqld` directly here is, that `safe_mysqld` 'guards' every `mysqld` process and will restart it, if a `mysqld` process fails due to signal kill -9, or similar. (Like segmentation fault, which MySQL should never do, of course ;) Please note that `safe_mysqld` script may require that you start it from a certain place. This means that you may have to CD to a certain directory, before you start the `mysqld_multi`. If you have problems starting, please see the `safe_mysqld` script. Check especially the lines:

      --------------------------------------------------------------------------
      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
      --------------------------------------------------------------------------
       「4.7.2  safe_mysqld, the wrapper around mysqld」節参照.

  The above test should be successful, or you may encounter problems.
- Beware of the dangers starting multiple `mysqlds` in the same data directory. Use separate data directories, unless you KNOW what you are doing!
- The socket file and the TCP/IP port must be different for every `mysqld`.
- The first and fifth `mysqld` group were intentionally left out from the example. You may have 'gaps' in the config file. This gives you more flexibility. The order in which the `mysqlds` are started or stopped depends on the order in which they appear in the config file.
- When you want to refer to a certain group using GNR with this program, just use the number in the end of the group name ( [mysqld# <== ).
- You may want to use option '--user' for `mysqld`, but in order to do this you need to be root when you start the `mysqld_multi` script. Having the option in the config file doesn't matter; you will just get a warning, if you are not the superuser and the `mysqlds` are started under YOUR UNIX account. IMPORTANT: Make sure that the `pid-file` and the data directory are read+write(+execute for the latter one) accessible for THAT UNIX user, who the specific `mysqld` process is started as. DON'T use the UNIX root account for this, unless you KNOW what you are doing!
- MOST IMPORTANT: Make sure that you understand the meanings of the options that are passed to the `mysqlds` and why WOULD YOU WANT to have separate `mysqld` processes. Starting multiple `mysqlds` in one data directory WILL NOT give you extra performance in a threaded system!

「4.1.4 同一マシン上に複数の MySQL サーバーを走らせる」節参照.

This is an example of the config file on behalf of `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/safe_mysqld
    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

「4.1.2 my.cnf オプションファイル」節参照.

### 4.7.4 myisampack, MySQL の圧縮された読み込み専用テーブルジェネレータ

`myisampack` is used to compress MyISAM tables, and `pack_isam` is used to compress ISAM tables. Because ISAM tables are deprecated, we will only discuss `myisampack` here, but everything said about `myisampack` should also be true for `pack_isam`.

`myisampack` はテーブル内の各項目を別々に圧縮するように働きます。展開のため の情報は、テーブルがオープンされた時にメモリに読まれます。これは、正確に1レコー ドだけを展開する必要があるような、個々のレコードへのアクセス時にとても良 い性能を与えます。MSDOS 上の Stacker 使用時のように、ディスクブロックは そんなに大きくありません。 通常、`myisampack` はデータファイルを 40〜70% にパックします。

a much larger disk block as when using Stacker on MS-DOS. Usually, `myisampack` packs the data file 40%-70%.

MySQL は圧縮されたテーブルでメモリマップ (`mmap()`) を使用します。 `mmap()` が働かない場合は、通常のファイルの読み書きを使用します。

There are currently two limitations with `myisampack`:

- パック後、テーブルは読み込み専用になります。
- `myisampack` can also pack `BLOB` or `TEXT` columns. The older `pack_isam` could not do this.

これらの制限の修正は TODO にありますが、優先度は低いです。

`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` を途中で kill した場合、 ``.TMD'` ファイルが消されて いない事があります。通常、`myisampack` は ``tbl_name.TMD'` ファイルが 既に存在する場合はエラーで終了します。 `--force` を使用すると、 `myisampack` はそのような場合でもテーブルをパックします。
`-?, --help`
  ヘルプメッセージを出力して終了。
`-j big_tbl_name, --join=big_tbl_name`
  全てのテーブルをコマンドラインで指定した `big_tbl_name` 一つに まとめます。結合される全てのテーブル定義は同じでなければなりません (同じ項目名、同じ項目型、同じインデックス、等)
`-p #, --packlength=#`
  Specify the record length storage size, in bytes. The value should be 1, 2, or 3. (`myisampack` stores all rows with length pointers of 1, 2, or 3 bytes. In most normal cases, `myisampack` can determine the right length value before it begins packing the file, but it may notice during the packing process that it could have used a shorter length. In this case, `myisampack` will print a note that the next time you pack the same file, you could use a shorter record length.)
`-s, --silent`
  Silent mode. Write output only when errors occur.
`-t, --test`
  Don't actually pack table, just test packing it.
`-T dir_name, --tmp_dir=dir_name`
  Use the named directory as the location in which to write the temporary table.
`-v, --verbose`
  Verbose mode. Write information about progress and packing result.
`-V, --version`
  Display version information and exit.
`-w, --wait`
  Wait and retry if table is in use. If the `mysqld` server was invoked with the `--skip-locking` option, it is not a good idea to invoke `myisampack` if the table might be updated during the packing process.

The sequence of commands shown below illustrates a typical table compression session:

    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

The information printed by `myisampack` is described below:

`normal`
  The number of columns for which no extra packing is used.
`empty-space`
  The number of columns containing values that are only spaces; these will occupy 1 bit.
`empty-zero`
  The number of columns containing values that are only binary 0's; these will occupy 1 bit.
`empty-fill`
  The number of integer columns that don't occupy the full byte range of their type; these are changed to a smaller type (for example, an `INTEGER` column may be changed to `MEDIUMINT`).
`pre-space`
  The number of decimal columns that are stored with leading spaces. In this case, each value will contain a count for the number of leading spaces.
`end-space`
  The number of columns that have a lot of trailing spaces. In this case, each value will contain a count for the number of trailing spaces.
`table-lookup`
  The column had only a small number of different values, which were converted to an `ENUM` before Huffman compression.
`zero`
  The number of columns for which all values are zero.
`Original trees`
  The initial number of Huffman trees.
`After join`
  The number of distinct Huffman trees left after joining trees to save some header space.

After a table has been compressed, `myisamchk -dvv` prints additional information about each field:

`Type`
  The field type may contain the following descriptors:
  `constant`
    All rows have the same value.
  `no endspace`
    Don't store endspace.
  `no endspace, not_always`
    Don't store endspace and don't do end space compression for all values.
  `no endspace, no empty`
    Don't store endspace. Don't store empty values.
  `table-lookup`
    The column was converted to an `ENUM`.
  `zerofill(n)`
    The most significant `n` bytes in the value are always 0 and are not stored.
  `no zeros`
    Don't store zeros.
  `always zero`
    0 values are stored in 1 bit.
`Huff tree`
  The Huffman tree associated with the field.
`Bits`
  The number of bits used in the Huffman tree.

After you have run `pack_isam`/`myisampack` you must run `isamchk`/`myisamchk` to re-create the index. At this time you can also sort the index blocks and create statistics needed for the MySQL optimizer to work more efficiently:

    myisamchk -rq --analyze --sort-index table_name.MYI
    isamchk   -rq --analyze --sort-index table_name.ISM

After you have installed the packed table into the MySQL database directory you should do `mysqladmin flush-tables` to force `mysqld` to start using the new table.

If you want to unpack a packed table, you can do this with the `--unpack` option to `isamchk` or `myisamchk`.

### 4.7.5 mysqld-max, An extended mysqld server

`mysqld-max` is the MySQL server (`mysqld`) configured with the following configure options:

Option | Comment
--with-server-suffix=-max | Add a suffix to the `mysqld` version string.
--with-bdb | Support for Berkeley DB (BDB) tables
--with-innodb | Support for InnoDB tables.
CFLAGS=-DUSE_SYMDIR | Symbolic links support for Windows.

You can find the MySQL-max binaries at http://www.mysql.com/downloads/mysql-max-3.23.html.

The Windows MySQL 3.23 binary distribution includes both the standard `mysqld.exe` binary and the `mysqld-max.exe` binary. http://www.mysql.com/downloads/mysql-3.23.html. 「2.1.2 Windows への MySQL のインストール」節参照.

Note that as Berkeley DB and InnoDB are not available for all platforms, some of the `Max` binaries may not have support for both of these. You can check which table types are supported by doing the following query:

    mysql> show variables like "have_%";
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | have_bdb      | YES   |
    | have_innodb   | NO    |
    | have_isam     | YES   |
    | have_raid     | NO    |
    | have_ssl      | NO    |
    +---------------+-------+

The meaning of the values are:

Value | Meaning.
YES | The option is activated and usable.
NO | MySQL is not compiled with support for this option.
DISABLED | The xxxx option is disabled because one started `mysqld` with `--skip-xxxx` or because one didn't start `mysqld` with all needed options to enable the option. In this case the `hostname.err` file should contain a reason for why the option is disabled.

NOTE: To be able to create InnoDB tables you MUST edit your startup options to include at least the `innodb_data_file_path` option. 「7.6.2 InnoDB 起動オプション」節参照.

To get better performance for BDB tables, you should add some configuration options for these too. 「7.5.3 BDB startup options」節参照.

`safe_mysqld` will automatically try to start any `mysqld` binary with the `-max` prefix. This makes it very easy to test out a another `mysqld` binary in an existing installation. Just run `configure` with the options you want and then install the new `mysqld` binary as `mysqld-max` in the same directory where your old `mysqld` binary is. 「4.7.2 safe_mysqld, the wrapper around mysqld」節参照.

The `mysqld-max` RPM uses the above mentioned `safe_mysqld` feature. It just installs the `mysqld-max` executable and `safe_mysqld` will automatically use this executable when `safe_mysqld` is restarted.

The following table shows which table types our standard MySQL-Max binaries includes:

System | BDB | InnoDB
AIX 4.3 | N | Y
HP-UX 11.0 | N | Y
Linux-Alpha | N | Y
Linux-Intel | Y | Y
Linux-Ia64 | N | Y
Solaris-intel | N | Y
Solaris-sparc | Y | Y
SCO OSR5 | Y | Y
UnixWare | Y | Y
Windows/NT | Y | Y

## 4.8 MySQL Client-Side Scripts and Utilities

### 4.8.1 Overview of the Client-Side Scripts and Utilities

All MySQL clients that communicate with the server using the `mysqlclient` library use the following environment variables:

Name | Description
`MYSQL_UNIX_PORT` | The default socket; used for connections to `localhost`
`MYSQL_TCP_PORT` | The default TCP/IP port
`MYSQL_PWD` | The default password
`MYSQL_DEBUG` | Debug-trace options when debugging
`TMPDIR` | The directory where temporary tables/files are created

Use of `MYSQL_PWD` is insecure. 「4.2.7 MySQL サーバーに接続」節参照.

The ``mysql'` client uses the file named in the `MYSQL_HISTFILE` environment variable to save the command-line history. The default value for the history file is ``$HOME/.mysql_history'`, where `$HOME` is the value of the `HOME` environment variable. 「H Environment Variables」節参照.

All MySQL programs take many different options. However, every MySQL program provides a `--help` option that you can use to get a full description of the program's different options. For example, try `mysql --help`.

You can override default options for all standard client programs with an option file. 「4.1.2 my.cnf オプションファイル」節.

The list below briefly describes the MySQL programs:

`myisamchk`
  Utility to describe, check, optimize, and repair MySQL tables. Because `myisamchk` has many functions, it is described in its own chapter. 「4 MySQL Database Administration」節参照.
`make_binary_distribution`
  Makes a binary release of a compiled MySQL. This could be sent by FTP to ``/pub/mysql/Incoming'` on `support.mysql.com` for the convenience of other MySQL users.
`msql2mysql`
  A shell script that converts `mSQL` programs to MySQL. It doesn't handle all cases, but it gives a good start when converting.
`mysqlaccess`
  A script that checks the access privileges for a host, user, and database combination.
`mysqladmin`
  Utility for performing administrative operations, such as creating or dropping databases, reloading the grant tables, flushing tables to disk, and reopening log files. `mysqladmin` can also be used to retrieve version, process, and status information from the server. 「4.8.3 mysqladmin, MySQL サーバーの管理」節参照.
`mysqlbug`
  The MySQL bug report script. This script should always be used when filing a bug report to the MySQL list.
`mysqld`
  The SQL daemon. This should always be running.
`mysqldump`
  Dumps a MySQL database into a file as SQL statements or as tab-separated text files. Enhanced freeware originally by Igor Romanenko. 「4.8.5 mysqldump, データベースとテーブルから、構造とデータをダンプ」節参照.
`mysqlimport`
  Imports text files into their respective tables using `LOAD DATA INFILE`. 「4.8.7 mysqlimport, テキストファイルからデータを取り込む」節参照.
`mysqlshow`
  Displays information about databases, tables, columns, and indexes.
`mysql_install_db`
  Creates the MySQL grant tables with default privileges. This is usually executed only once, when first installing MySQL on a system.
`replace`
  A utility program that is used by `msql2mysql`, but that has more general applicability as well. `replace` changes strings in place in files or on the standard input. Uses a finite state machine to match longer strings first. Can be used to swap strings. For example, this command swaps `a` and `b` in the given files:

      shell> replace a b b a -- file1 file2 ...

### 4.8.2 コマンドラインツール　（ `mysql` ）

`mysql` はシンプルな SQL shell です(GNU `readline` を持っています). これは対話モードと、非対話モードを持っています。 対話モードで使用された場合、 クエリの結果は ASCII テーブルのフォーマットで与えられます。 非対話モードで使用された場合(例えばフィルターとして)、結果はタブ区切りの フォーマットで返ります。 (出力フォーマットはコマンドラインのオプションで変更できます) 以下のようにしてスクリプトを実行できます：

    shell> mysql database < script.sql > output.tab

もしクライアントでメモリー不足の問題が出た場合、`--quick` オプションを 使用します！ これは `mysql` に、結果セットを取得する際に、 `mysql_store_result()` ではなく `mysql_use_result()` を 使用させます。

`mysql` の使用はとても簡単です： `mysql database` や `mysql --user=user_name --password=your_password d atabase` のようにしてはじめます。 SQL 文を入力し、一文を ``;'`, ``\g'` or ``\G'` で終え、 RETURN/ENTER を押します。

`mysql` は以下のオプションをサポートします：

`-?, --help`
  help を表示して終了
`-A, --no-auto-rehash`
  自動リハッシュをしない。 テーブルとフィールドの取得には 'rehash' を 使用しなくてはなりません。 これは `mysql` の起動を速くします。
`-B, --batch`
  結果をタブ区切り、１レコードは１行で出力します。 history ファイルは使用しません。
`--character-sets-dir=...`
  Directory where character sets are located.
`-C, --compress`
  サーバー・クライアント間の通信を圧縮します
`-#, --debug[=...]`
  デバッグログ。 デフォルトは 'd:t:o,/tmp/mysql.trace'
`-D, --database=...`
  使用するデータベース。 これは `my.cnf` ファイルが便利です
`--default-character-set=...`
  Set the default character set.
`-e, --execute=...`
  コマンドを実行して終了。 (Output like with --batch)
`-E, --vertical`
  垂直にレコードを出力します。 このオプションを指定していなくても、 SQL 文を `\G` で終了した場合、同じように垂直に出力します。
`-f, --force`
  SQL エラーがおきたとしても、処理を続けます
`-g, --no-named-commands`
  Named commands are disabled. Use \* form only, or use named commands only in the beginning of a line ending with a semicolon (;). Since Version 10.9, the client now starts with this option ENABLED by default! With the -g option, long format commands will still work from the first line, however.
`-G, --enable-named-commands`
  Named commands are enabled. Long format commands are allowed as well as shortened \* commands.
`-i, --ignore-space`
  関数名の後ろについたスペースを無視します
`-h, --host=...`
  指定したホストに接続します
`-H, --html`
  結果を HTML フォーマットで返します
`-L, --skip-line-numbers`
  エラーの起きた行の番号を書きません。 これはエラーメッセージを含んだ結果を 比較する場合に便利です。
`--no-pager`
  Disable pager and print to stdout. See interactive help (\h) also.
`--no-tee`
  Disable outfile. See interactive help (\h) also.
`-n, --unbuffered`
  それぞれのクエリ毎にバッファをフラッシュします
`-N, --skip-column-names`
  結果に、フィールド名を書き出しません。
`-O, --set-variable var=option`
  変数に値をセットします。 `--help` lists variables.
`-o, --one-database`
  デフォルトのデータベースのみ更新します。 これは update ログファイルを 使用して更新する場合、他のデータベースの更新を避けたい時に便利です。
``--pager[=...]``
  Output type. Default is your `ENV` variable `PAGER`. Valid pagers are less, more, cat [> filename], etc. See interactive help (\h) also. This option does not work in batch mode. Pager works only in UNIX.
`-p[password], --password[=...]`
  サーバーに接続する際のパスワード。 もしパスワードがコマンドラインに 指定されていなかった場合、tty 上でパスワードが問い合わされます。 `-p` を使用する場合、このオプションとパスワードの間には スペースが不要だということに注意してください。
`-P --port=...`
  接続に使用する TCP/IP ポート番号
`-q, --quick`
  結果をキャッシュせず、一レコードづつ出力します。 これはもし出力を中止した場合、サーバーを遅くします。 ヒストリファイルは使用しません。
`-r, --raw`
  エスケープ処理をしないで値を書き出します。 `--batch` とともに使用されます
`-s, --silent`
  静粛モード
`-S --socket=...`
  接続に使用する ソケットファイル
`-t --table`
  表の形式で出力します。 これは batch モード以外でのデフォルトです。
`-T, --debug-info`
  Print some debug information at exit.
`--tee=...`
  Append everything into outfile. See interactive help (\h) also. Does not work in batch mode.
`-u, --user=#`
  ログインユーザー名
`-U, --safe-updates[=#], --i-am-a-dummy[=#]`
  キーを使用する `UPDATE` and `DELETE` のみを行います。 これは後述します。 このオプションをもし `my.cnf` に書いている場合は、 `--safe-updates=0` でこのオプションをリセットできます。
`-v, --verbose`
  冗長出力。 (-v -v -v は表形式の出力を与える)
`-V, --version`
  バージョンを表示して終了
`-w, --wait`
  もし接続が落ちた場合、中断しないで、待って、再試行します。

You can also set the following variables with `-O` or `--set-variable`:

Variable Name | Default | Description
connect_timeout | 0 | Number of seconds before timeout connection.
max_allowed_packet | 16777216 | Max packetlength to send/receive from to server
net_buffer_length | 16384 | Buffer for TCP/IP and socket communication
select_limit | 1000 | Automatic limit for SELECT when using --i-am-a-dummy
max_join_size | 1000000 | Automatic limit for rows in a join when using --i-am-a-dummy.

もしコマンドラインで '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.
    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.
    quit    (\q)    Quit mysql.
    rehash  (\#)    Rebuild completion hash.
    source  (\.)    Execute a SQL script file. Takes a file name as an argument.
    status  (\s)    Get status information from the server.
    tee     (\T)    Set outfile [to_outfile]. Append everything into given outfile.
    use     (\u)    Use another database. Takes database name as argument.

From the above, pager only works in UNIX.

`status` コマンドは、今使用している 接続とサーバーについての情報をいくつか表示します。 もし `--safe-updates` モードで使用している場合、 `status` は あなたのクエリに影響する `mysql` 変数の値を表示します。

初心者に便利な起動オプション(MySQL バージョン 3.23.11 で導入されました)は、 `--safe-updates` あるいは `--i-am-a-dummy` です。 ( これは `DELETE FROM table_name` を `WHERE` 節を忘れて 実行しようとした場合のためにあります。) このオプションが使用されると、 `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` コマンドからセット可能です。 「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` は 中断されます。

Some useful hints about the `mysql` client:

Some data is much more readable when displayed vertically, instead of the usual horizontal box type output. For example longer text, which includes new lines, is often much easier to be read with vertical output.

    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)

- For logging, you can use the `tee` option. The `tee` can be started with option `--tee=...`, or from the command line interactively with command `tee`. All the data displayed on the screen will also be appended into a given file. This can be very useful for debugging purposes also. The `tee` can be disabled from the command line with command `notee`. Executing `tee` again starts logging again. Without a parameter the previous file will be used. Note that `tee` will flush the results into the file after each command, just before the command line appears again waiting for the next command.
- Browsing, or searching the results in the interactive mode in UNIX less, more, or any other similar program, is now possible with option `--pager[=...]`. Without argument, `mysql` client will look for environment variable PAGER and set `pager` to that. `pager` can be started from the interactive command line with command `pager` and disabled with command `nopager`. The command takes an argument optionally and the `pager` will be set to that. Command `pager` can be called without an argument, but this requires that the option `--pager` was used, or the `pager` will default to stdout. `pager` works only in UNIX, since it uses the popen() function, which doesn't exist in Windows. In Windows, the `tee` option can be used instead, although it may not be as handy as `pager` can be in some situations.
- A few tips about `pager`: You can use it to write to a file:

      mysql> pager cat > /tmp/log.txt

  and the results will only go to a file. You can also pass any options for the programs that you want to use with the `pager`:

      mysql> pager less -n -i -S

  From the above do note the option '-S'. You may find it very useful when browsing the results; try the option with horizontal output (end commands with '\g', or ';') and with vertical output (end commands with '\G'). Sometimes a very wide result set is hard to be read from the screen, with option -S to less you can browse the results within the interactive less from left to right, preventing lines longer than your screen from being continued to the next line. This can make the result set much more readable. You can swith the mode between on and off within the interactive less with '-S'. See the 'h' for more help about less.
- Last (unless you already understood this from the above examples ;) you can combine very complex ways to handle the results, for example the following would send the results to two files in two different directories, on two different hard-disks mounted on /dr1 and /dr2, yet let the results still be seen on the screen via less:

      mysql> pager cat | tee /dr1/tmp/res.txt | tee /dr2/tmp/res2.txt | less -n -i -S

- You can also combine the two functions above; have the `tee` enabled, `pager` set to 'less' and you will be able to browse the results in unix 'less' and still have everything appended into a file the same time. The difference between `UNIX tee` used with the `pager` and the `mysql` client in-built `tee`, is that the in-built `tee` works even if you don't have the `UNIX tee` available. The in-built `tee` also logs everything that is printed on the screen, where the `UNIX tee` used with `pager` doesn't log quite that much. Last, but not least, the interactive `tee` is more handy to switch on and off, when you want to log something into a file, but want to be able to turn the feature off sometimes.

### 4.8.3 mysqladmin, MySQL サーバーの管理

管理オペレーションを実行するためのユーティリティ。シンタックスは:

    shell> mysqladmin [OPTIONS] command [command-option] command ...

`mysqladmin --help` によって、オプションの一覧を手にいれることができます。

現在の `mysqladmin` は以下のコマンドをサポートします：

`create databasename`
  データベースの作成
`drop databasename`
  データベースとテーブルの全削除。
`extended-status`
  サーバーから拡張ステータスを取得。
`flush-hosts`
  キャッシュされている全ホストをフラッシュ。
`flush-logs`
  全てのログをフラッシュ
`flush-tables`
  全てのテーブルをフラッシュ
`flush-privileges`
  許可テーブルの再読み込み (reload と同じ)
`kill id,id,...`
  mysql スレッドの kill.
`password`
  古いパスワードを New-password に変更
`ping`
  `mysqld` が生きているかチェック
`processlist`
  現在活動中の mysql スレッドを表示
`reload`
  許可テーブルの再読み込み
`refresh`
  全テーブルをフラッシュし、ログファイルを一度閉じて開きます。
`shutdown`
  サーバーをダウンさせます。
`slave-start`
  Start slave replication thread.
`slave-stop`
  Stop slave replication thread.
`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

The `mysqladmin status` command result has the following columns:

Uptime | MySQL サーバーの起動秒数
Threads | 稼働中のスレッド数 (clients).
Questions | `mysqld` が開始してからのクライアントからのクエリ数
Slow queries | `long_query_time` 秒より時間のかかったクエリの数 「4.9.5 The Slow Query Log」節参照.
Opens | `mysqld` が開いたテーブル数
Flush tables | Number of `flush ...`, `refresh`, and `reload` commands.
Open tables | 現在開かれているテーブルの数
Memory in use | `mysqld` のコードによって直接割り当てられたメモリ (only available when MySQL is compiled with --with-debug=full).
Max memory used | `mysqld` のコードによって直接割り当てられる最大メモリー量 (only available when MySQL is compiled with --with-debug=full).

If you do `myslqadmin shutdown` on a socket (in other words, on a the computer where `mysqld` is running), `mysqladmin` will wait until the MySQL `pid-file` is removed to ensure that the `mysqld` server has stopped properly.

### 4.8.4 Using `mysqlcheck` for Table Maintenance and Crash Recovery

Since MySQL version 3.23.38 you will be able to use a new checking and repairing tool for `MyISAM` tables. The difference to `myisamchk` is that `mysqlcheck` should be used when the `mysqld` server is running, where as `myisamchk` should be used when it is not. The benefit is that you no longer have to take the server down for checking or repairing your tables.

`mysqlcheck` uses MySQL server commands `CHECK`, `REPAIR`, `ANALYZE` and `OPTIMIZE` in a convenient way for the user.

There are three alternative ways to invoke `mysqlcheck`:

    shell> mysqlcheck [OPTIONS] database [tables]
    shell> mysqlcheck [OPTIONS] --databases DB1 [DB2 DB3...]
    shell> mysqlcheck [OPTIONS] --all-databases

So it can be used in a similar way as `mysqldump` when it comes to what databases and tables you want to choose.

`mysqlcheck` does have a special feature compared to the other clients; the default behavior, checking tables (-c), can be changed by renaming the binary. So if you want to have a tool that repairs tables by default, you should just copy `mysqlcheck` to your harddrive with a new name, `mysqlrepair`, or alternatively make a symbolic link to `mysqlrepair` and name the symbolic link as `mysqlrepair`. If you invoke `mysqlrepair` now, it will repair tables by default.

The names that you can use to change `mysqlcheck` default behavior are here:

    mysqlrepair:   The default option will be -r
    mysqlanalyze:  The default option will be -a
    mysqloptimize: The default option will be -o

The options available for `mysqlcheck` are listed here, please check what your version supports with `mysqlcheck --help`.

`-A, --all-databases`
  Check all the databases. This will be same as --databases with all databases selected
`-1, --all-in-1`
  Instead of making one query for each table, execute all queries in 1 query separately for each database. Table names will be in a comma separated list.
`-a, --analyze`
  Analyze given tables.
`--auto-repair`
  If a checked table is corrupted, automatically fix it. Repairing will be done after all tables have been checked, if corrupted ones were found.
`-#, --debug=...`
  Output debug log. Often this is 'd:t:o,filename'
`--character-sets-dir=...`
  Directory where character sets are
`-c, --check`
  Check table for errors
`-C, --check-only-changed`
  Check only tables that have changed since last check or haven't been closed properly.
`--compress`
  Use compression in server/client protocol.
`-?, --help`
  Display this help message and exit.
`-B, --databases`
  To check several databases. Note the difference in usage; In this case no tables are given. All name arguments are regarded as database names.
`--default-character-set=...`
  Set the default character set
`-F, --fast`
  Check only tables that hasn't been closed properly
`-f, --force`
  Continue even if we get an sql-error.
`-e, --extended`
  If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will run an extended repair on the table, which may not only take a long time to execute, but may produce a lot of garbage rows also!
`-h, --host=...`
  Connect to host.
`-m, --medium-check`
  Faster than extended-check, but only finds 99.99 percent of all errors. Should be good enough for most cases.
`-o, --optimize`
  Optimize table
`-p, --password[=...]`
  Password to use when connecting to server. If password is not given it's solicited on the tty.
`-P, --port=...`
  Port number to use for connection.
`-q, --quick`
  If you are using this option with CHECK TABLE, it prevents the check from scanning the rows to check for wrong links. This is the fastest check. If you are using this option with REPAIR TABLE, it will try to repair only the index tree. This is the fastest repair method for a table.
`-r, --repair`
  Can fix almost anything except unique keys that aren't unique.
`-s, --silent`
  Print only error messages.
`-S, --socket=...`
  Socket file to use for connection.
`--tables`
  Overrides option --databases (-B).
`-u, --user=#`
  User for login if not current user.
`-v, --verbose`
  Print info about the various stages.
`-V, --version`
  Output version information and exit.

### 4.8.5 mysqldump, データベースとテーブルから、構造とデータをダンプ

データベース、あるいは、バックアップ、他のSQLサーバー(MySQL サーバであ る必要はない)へのデータを移動を目的としたデータのまとまり、これらをダンプする ためのユーティリティ。ダンプは、テーブルの作成のための SQL 文を含みます。

サーバでバックアップを行なう場合、`mysqlhotcopy` を代わりに使用するこ とを考慮すべきです。 「4.8.6 mysqlhotcopy, Copying MySQL Databases and Tables」節参照.

    shell> mysqldump [OPTIONS] database [tables]
    OR     mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
    OR     mysqldump [OPTIONS] --all-databases [OPTIONS]

もしテーブルを指定せず、`--databases` や `--all-databases` を 使用しなかったなら、データベースの全てのテーブルがダンプされます。

`mysqldump --help` によって、オプションの一覧を手にいれることができます。

もし `mysqldump` を `--quick` や `--opt` なしで実行するならば、 `mysqldump` は結果を表示する前に、結果をメモリに全てロードすることに 注意してください。 これは大きなデータベースをダンプする際に問題になるでしょう。

Note that if you are using a new copy of the `mysqldump` program and you are going to do a dump that will be read into a very old MySQL server, you should not use the `--opt` or `-e` options.

`mysqldump` は以下のオプションをサポートします：

`--add-locks`
  Add `LOCK TABLES` before and `UNLOCK TABLE` after each table dump. (To get faster inserts into MySQL.)
`--add-drop-table`
  Add a `drop table` before each create statement.
`-A, --all-databases`
  Dump all the databases. This will be same as `--databases` with all databases selected.
`-a, --all`
  Include all MySQL-specific create options.
`--allow-keywords`
  Allow creation of column names that are keywords. This works by prefixing each column name with the table name.
`-c, --complete-insert`
  Use complete insert statements (with column names).
`-C, --compress`
  Compress all information between the client and the server if both support compression.
`-B, --databases`
  To dump several databases. Note the difference in usage. In this case no tables are given. All name arguments are regarded as database names. `USE db_name;` will be included in the output before each new database.
`--delayed`
  Insert rows with the `INSERT DELAYED` command.
`-e, --extended-insert`
  Use the new multiline `INSERT` syntax. (Gives more compact and faster inserts statements.)
`-#, --debug[=option_string]`
  Trace usage of the program (for debugging).
`--help`
  Display a help message and exit.
`--fields-terminated-by=...`
`--fields-enclosed-by=...`
`--fields-optionally-enclosed-by=...`
`--fields-escaped-by=...`
`--lines-terminated-by=...`
  These options are used with the `-T` option and have the same meaning as the corresponding clauses for `LOAD DATA INFILE`. 「6.4.8 `LOAD DATA INFILE` 構文」節参照.
`-F, --flush-logs`
  Flush log file in the MySQL server before starting the dump.
`-f, --force,`
  Continue even if we get a SQL error during a table dump.
`-h, --host=..`
  Dump data from the MySQL server on the named host. The default host is `localhost`.
`-l, --lock-tables.`
  Lock all tables before starting the dump. The tables are locked with `READ LOCAL` to allow concurrent inserts in the case of `MyISAM` tables.
`-n, --no-create-db`
  'CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name;' will not be put in the output. The above line will be added otherwise, if --databases or --all-databases option was given.
`-t, --no-create-info`
  Don't write table creation information (The `CREATE TABLE` statement.)
`-d, --no-data`
  Don't write any row information for the table. This is very useful if you just want to get a dump of the structure for a table!
`--opt`
  Same as `--quick --add-drop-table --add-locks --extended-insert --lock-tables`. Should give you the fastest possible dump for reading into a MySQL server.
`-pyour_pass, --password[=your_pass]`
  The password to use when connecting to the server. If you specify no ``=your_pass'` part, `mysqldump` you will be prompted for a password.
`-P port_num, --port=port_num`
  The TCP/IP port number to use for connecting to a host. (This is used for connections to hosts other than `localhost`, for which Unix sockets are used.)
`-q, --quick`
  Don't buffer query, dump directly to stdout. Uses `mysql_use_result()` to do this.
`-r, --result-file=...`
  Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\n' from being converted to '\n\r' (new line + carriage return).
`-S /path/to/socket, --socket=/path/to/socket`
  The socket file to use when connecting to `localhost` (which is the default host).
`--tables`
  Overrides option --databases (-B).
`-T, --tab=path-to-some-directory`
  Creates a `table_name.sql` file, that contains the SQL CREATE commands, and a `table_name.txt` file, that contains the data, for each give table. NOTE: This only works if `mysqldump` is run on the same machine as the `mysqld` daemon. The format of the `.txt` file is made according to the `--fields-xxx` and `--lines--xxx` options.
`-u user_name, --user=user_name`
  The MySQL user name to use when connecting to the server. The default value is your Unix login name.
`-O var=option, --set-variable var=option`
  Set the value of a variable. The possible variables are listed below.
`-v, --verbose`
  Verbose mode. Print out more information on what the program does.
`-V, --version`
  Print version information and exit.
`-w, --where='where-condition'`
  Dump only selected records. Note that QUOTES are mandatory:

      "--where=user='jimf'" "-wuserid>1" "-wuserid<1"

`-O net_buffer_length=#, where # < 16M`
  When creating multi-row-insert statements (as with option `--extended-insert` or `--opt`), `mysqldump` will create rows up to `net_buffer_length` length. If you increase this variable, you should also ensure that the `max_allowed_packet` variable in the MySQL server is bigger than the `net_buffer_length`.

The most normal use of `mysqldump` is probably for making a backup of whole databases. 「4.4.1 データベースのバックアップ」節参照.

    mysqldump --opt database > backup-file.sql

You can read this back into MySQL with:

    mysql database < backup-file.sql

or

    mysql -e "source /patch-to-backup/backup-file.sql" database

However, it's also very useful to populate another MySQL server with information from a database:

    mysqldump --opt database | mysql --host=remote-host -C database

It is possible to dump several databases with one command:

    mysqldump --databases database1 [database2 database3...] > my_databases.sql

If all the databases are wanted, one can use:

    mysqldump --all-databases > all_databases.sql

### 4.8.6 mysqlhotcopy, Copying MySQL Databases and Tables

`mysqlhotcopy` is a perl script that uses `LOCK TABLES`, `FLUSH TABLES` and `cp` or `scp` to quickly make a backup of a database. It's the fastest way to make a backup of the database, of single tables but it can only be run on the same machine where the database directories are.

    mysqlhotcopy db_name [/path/to/new_directory]

    mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory

    mysqlhotcopy db_name./regex/

`mysqlhotcopy` supports the following options:

`-?, --help`
  Display a help screen and exit
`-u, --user=#`
  User for database login
`-p, --password=#`
  Password to use when connecting to server
`-P, --port=#`
  Port to use when connecting to local server
`-S, --socket=#`
  Socket to use when connecting to local server
`--allowold`
  Don't abort if target already exists (rename it _old)
`--keepold`
  Don't delete previous (now renamed) target when done
`--noindices`
  Don't include full index files in copy to make the backup smaller and faster The indexes can later be reconstructed with `myisamchk -rq.`.
`--method=#`
  Method for copy (`cp` or `scp`).
`-q, --quiet`
  Be silent except for errors
`--debug`
  Enable debug
`-n, --dryrun`
  Report actions without doing them
`--regexp=#`
  Copy all databases with names matching regexp
`--suffix=#`
  Suffix for names of copied databases
`--checkpoint=#`
  Insert checkpoint entry into specified db.table
`--flushlog`
  Flush logs once all tables are locked.
`--tmpdir=#`
  Temporary directory (instead of /tmp).

You can use `perldoc mysqlhotcopy` to get a more complete documentation for `mysqlhotcopy`.

`mysqlhotcopy` reads the groups `[client]` and `[mysqlhotcopy]` from the option files.

To be able to execute `mysqlhotcopy` you need write access to the backup directory, `SELECT` privilege to the tables you are about to copy and the MySQL `Reload` privilege (to be able to execute `FLUSH TABLES`).

### 4.8.7 mysqlimport, テキストファイルからデータを取り込む

`mysqlimport` は、`LOAD DATA INFILE` SQL 構文を、 コマンドラインインターフェースで提供します。 `mysqlimport` のオプションのほとんどが、 `LOAD DATA INFILE` への同じオプションに対応します。 「6.4.8 `LOAD DATA INFILE` 構文」節参照.

`mysqlimport` の実行は以下のようにします:

    shell> mysqlimport [options] database textfile1 [textfile2....]

`mysqlimport` は、コマンドラインの引数に与えられたファイル名の拡張子を取り、 拡張子を取った後の名前を、ファイルの内容を取り込むテーブルの名前とします。 例えば、``patient.txt'`, ``patient.text'`, ``patient'` という ファイルは全て、`patient` とという名前のテーブルに取り込まれます。

`mysqlimport` は以下のオプションをサポートします:

`-c, --columns=...`
  This option takes a comma-separated list of field names as an argument. The field list is used to create a proper `LOAD DATA INFILE` command, which is then passed to MySQL. 「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` の対応する文節と同じ意味になります 「6.4.8 `LOAD DATA INFILE` 構文」節参照.
`-f, --force`
  エラーを無視します。例えば、テキストファイルを取り込むテーブルがない場合、 残りのファイルの処理に移ります。 `--force` がなければ、 テーブルがなければ `mysqlimport` は終了します。
`--help`
  ヘルプを表示して終了。
`-h host_name, --host=host_name`
  名前を指定された MySQL サーバーにデータを取り入れます。 デフォルトでは `localhost`.
`-i, --ignore`
  `--replace` オプションの説明を見てください。
`-l, --lock-tables`
  それぞれのテキストファイルを処理する前に、書き込まれる 全てのテーブルをロックします。 これは確実に、すべてのテーブルをサーバ上で同期させます。
`-L, --local`
  クライアントからの入力ファイルを読みます。 デフォルトでは、`localhost` に接続した場合、テキストファイルは サーバー上にあると仮定されます。(`localhost` はデフォルト値)
`-pyour_pass, --password[=your_pass]`
  サーバーに接続するときに使用するパスワード。 もし ``=your_pass'` のところにパスワードを書かなければ、 `mysqlimport` はパスワードのためのプロンプトをだします。
`-P port_num, --port=port_num`
  ホストに接続するための TCP/IP ポート番号。 (これは `localhost` を除くホストへの接続に使用します。 `localhost` へは、UNIX ソケットを使用します。)
`-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`
  バージョンを表示して終了。

Here is a sample run using `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.8.8 Showing Databases, Tables, and Columns

`mysqlshow` can be used to quickly look at which databases exist, their tables, and the table's columns.

With the `mysql` program you can get the same information with the `SHOW` commands. 「4.5.5 `SHOW` 構文」節参照.

`mysqlshow` is invoked like this:

    shell> mysqlshow [OPTIONS] [database [table [column]]]

- If no database is given, all matching databases are shown.
- If no table is given, all matching tables in the database are shown.
- If no column is given, all matching columns and column types in the table are shown.

Note that in newer MySQL versions, you only see those database/tables/columns for which you have some privileges.

If the last argument contains a shell or SQL wild-card (`*`, `?`, `%` or `_`) then only what's matched by the wild card is shown. This may cause some confusion when you try to display the columns for a table with a `_` as in this case `mysqlshow` only shows you the table names that match the pattern. This is easily fixed by adding an extra `%` last on the command line (as a separate argument).

### 4.8.9 perror, Explaining Error Codes

`perror` can be used to print error message(s). `perror` can be invoked like this:

    shell> perror [OPTIONS] [ERRORCODE [ERRORCODE...]]

    For example:

    shell> perror 64 79
    Error code  64:  Machine is not on the network
    Error code  79:  Can not access a needed shared library

`perror` can be used to display a description for a system error code, or an MyISAM/ISAM table handler error code. The error messages are mostly system dependent.

### 4.8.10 How to Run SQL Commands from a Text File

The `mysql` client typically is used interactively, like this:

    shell> mysql database

However, it's also possible to put your SQL commands in a file and tell `mysql` to read its input from that file. To do so, create a text file ``text_file'` that contains the commands you wish to execute. Then invoke `mysql` as shown below:

    shell> mysql database < text_file

You can also start your text file with a `USE db_name` statement. In this case, it is unnecessary to specify the database name on the command line:

    shell> mysql < text_file

「4.8 MySQL Client-Side Scripts and Utilities」節参照.

## 4.9 The MySQL Log Files

MySQL has several different log files that can help you find out what's going on inside `mysqld`:

The error log | Problems encountering starting, running or stopping `mysqld`.
The isam log | Logs all changes to the ISAM tables. Used only for debugging the isam code.
The query log | Established connections and executed queries.
The update log | Deprecated: Stores all statements that changes data
The binary log | Stores all statements that changes something. Used also for replication
The slow log | Stores all queries that took more than `long_query_time` to execute or didn't use indexes.

All logs can be found in the `mysqld` data directory. You can force `mysqld` to reopen the log files (or in some cases switch to a new log) by executing `FLUSH LOGS`. 「4.5.3 `FLUSH` 構文」節参照.

### 4.9.1 The Error Log

`mysqld` writes all errors to the stderr, which the `safe_mysqld` script redirects to a file called `'hostname'.err`. (On Windows, `mysqld` writes this directly to ``\mysql\data\mysql.err'`).

This contains information indicating when `mysqld` was started and stopped and also any critical errors found when running. If `mysqld` dies unexpectedly and `safe_mysqld` needs to restart `mysqld`, `safe_mysqld` will write a `restarted mysqld` row in this file. This log also holds a warning if `mysqld` notices a table that needs to be automatically checked or repaired.

On some operating systems, the error log will contain a stack trace for where `mysqld` died. This can be used to find out where `mysqld` died. 「G.1.4 Using a stack trace」節参照.

### 4.9.2 The General Query Log

If you want to know what happens within `mysqld`, you should start it with `--log[=file]`. This will log all connections and queries to the log file (by default named ``'hostname'.log'`). This log can be very useful when you suspect an error in a client and want to know exactly what `mysqld` thought the client sent to it.

By default, the `mysql.server` script starts the MySQL server with the `-l` option. If you need better performance when you start using MySQL in a production environment, you can remove the `-l` option from `mysql.server` or change it to `--log-bin`.

The entries in this log are written as `mysqld` receives the questions. This may be different than the order in which the statements are executed. This is in contrast to the update log and the binary log which are written after the query is executed, but before any locks are released.

### 4.9.3 更新ログ

NOTE: The update log is replaced by the binary log. 「4.9.4 The Binary Update Log」節参照. With this you can do anything that you can do with the update log.

`--log-update=file_name`オプションを使用して`mysqld`を起動すると、 データを更新した全てのSQLコマンドをログファイルに書きます。 もし file_name が与えられなかった場合は、ホスト名がデフォルトで使用されます。 もし file_name にディレクトリパスが含まれなかった場合は、 このファイルはデータディレクトリに書かれます。 もし file_name が拡張を持たなかったなら、`mysqld` は `file_name.###` という形でログファイルを作成します。 このログファイルはデータディレクトリにかかれ、 その名前は `file_name.###` という形式の名前になっています。

`###` は `mysqladmin refresh` か `mysqladmin flush-logs` を実行す る度に、 あるいは `FLUSH LOGS` 構文を実行したり、サーバーをリスタートする度に 自動的に増える数字です。

NOTE: For the above scheme to work, you should NOT create your own files with the same filename as the update log + some extensions that may be regarded as a number, in the directory used by the update log!

もし `--log` か `-l` オプションを使用した場合、ログファイルの名前は `mysqld` は全部のログを ``hostname.log'` に書き出します。 この場合、リスタートやりフレッシュを行っても新しくログファイルを作りません。 (一度クローズして再度オープンします。)

    mv hostname.log hostname-old.log
    mysqladmin flush-logs
    cp hostname-old.log to-backup-directory
    rm hostname-old.log

更新ログは、実際に更新されたデータのステートメントだけを書くため、きびきびと動作 します。 `WHERE` を使用した `UPDATE` か `DELETE` で結果が得られなかった場合、 ログは書き出されません。 すでにセットされている値に、もう一度項目を更新するような `UPDATE` もスキッ プされます。

The update logging is done immediately after a query completes but before any locks are released or any commit is done. This ensures that the log will be logged in the execution order.

ログファイルの更新に従ってデータベースを更新したい場合は、次を行います (更新ログファイル名を ``file_name.###'` と仮定します):

    shell> ls -1 -t -r file_name.[0-9]* | xargs cat | mysql

`ls` は全てのログファイルを正しく並べるために使用しています。

これは、クラッシュ後にバックアップした状態まで戻りたい、あるいは、 バックアップした後からクラッシュするまでの間のデータの更新を行いたい、 そんな場合に使えます。

### 4.9.4 The Binary Update Log

The intention is that the binary log should replace the update log, so we recommend you to switch to this log format as soon as possible!

The binary log contains all information that is available in the update log in a more efficient format. It also contains information about how long every query that updated the database took.

The binary log is also used when you are replicating a slave from a master. 「4.10 MySQL のレプリケーション」節参照.

When started with the `--log-bin[=file_name]` option, `mysqld` writes a log file containing all SQL commands that update data. If no file name is given, it defaults to the name of the host machine followed by `-bin`. If file name is given, but it doesn't contain a path, the file is written in the data directory.

If you supply an extension to `--log-bin=filename.extension`, the extension will be silenty removed.

To the binary log filename `mysqld` will append an extension that is a number that is incremented each time you execute `mysqladmin refresh`, execute `mysqladmin flush-logs`, execute the `FLUSH LOGS` statement or restart the server.

You can use the following options to `mysqld` to affect what is logged to the binary log:

`binlog-do-db=database_name` | Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned. (Example: `binlog-do-db=some_database`)
`binlog-ignore-db=database_name` | Tells the master that updates to the given database should not be logged to the binary log (Example: `binlog-ignore-db=some_database`)

To be able to know which different binary log files have been used, `mysqld` will also create a binary log index file that contains the name of all used binary log files. By default this has the same name as the binary log file, with the extension `'.index'`. You can change the name of the binary log index file with the `--log-bin-index=[filename]` option.

If you are using replication, you should not delete old binary log files until you are sure that no slave will ever need to use them. One way to do this is to do `mysqladmin flush-logs` once a day and then remove any logs that are more than 3 days old.

You can examine the binary log file with the `mysqlbinlog` command. For example, you can update a MySQL server from the binary log as follows:

    mysqlbinlog log-file | mysql -h server_name

You can also use the `mysqlbinlog` program to read the binary log directly from a remote MySQL server!

`mysqlbinlog --help` will give you more information of how to use this program!

If you are using `BEGIN [WORK]` or `SET AUTOCOMMIT=0`, you must use the MySQL binary log for backups instead of the old update log.

The binary logging is done immediately after a query completes but before any locks are released or any commit is done. This ensures that the log will be logged in the execution order.

All updates (`UPDATE`, `DELETE` or `INSERT`) that change a transactional table (like BDB tables) are cached until a `COMMIT`. Any updates to a non-transactional table are stored in the binary log at once. Every thread will, on start, allocate a buffer of `binlog_cache_size` to buffer queries. If a query is bigger than this, the thread will open a temporary file to handle the bigger cache. The temporary file will be deleted when the thread ends.

The `max_binlog_cache_size` can be used to restrict the total size used to cache a multi-transaction query.

If you are using the update or binary log, concurrent inserts will not work together with `CREATE ... INSERT` and `INSERT ... SELECT`. This is to ensure that you can recreate an exact copy of your tables by applying the log on a backup.

### 4.9.5 The Slow Query Log

When started with the `--log-slow-queries[=file_name]` option, `mysqld` writes a log file containing all SQL commands that took more than `long_query_time` to execute. The time to get the initial table locks are not counted as execution time.

The slow query log is logged after the query is executed and after all locks has been released. This may be different than the order in which the statements are executed.

If no file name is given, it defaults to the name of the host machine suffixed with `-slow.log`. If a filename is given, but doesn't contain a path, the file is written in the data directory.

The slow query log can be used to find queries that take a long time to execute and are thus candidates for optimization. With a large log, that can become a difficult task. You can pipe the slow query log through the `mysqldumpslow` command to get a summary of the queries which appear in the log.

You are using `--log-long-format` then also queries that are not using indexes are printed. 「4.1.1 mysqld コマンド行オプション」節参照.

### 4.9.6 Log File Maintenance

MySQL has a lot of log files which make it easy to see what is going. 「4.9 The MySQL Log Files」節参照. One must however from time to time clean up after `MysQL` to ensure that the logs don't take up too much disk space.

MySQL をログファイルとともに使用する場合、 あなたは、時々古いログファイルを リムーブ/バックアップ し、 MySQL に新しいファイルにログを取るように指示したいと思うことでしょう。 「4.4.1 データベースのバックアップ」節参照.

`Redhat` Linux においては、`mysql-log-rotate` スクリプトを これに使用できます。 もし RPM ディストリビューションの MySQL を インストールしたなら、このスクリプトは自動でインストールされているはずです。 Note that you should be careful with this if you are using the log for replication!

他のシステムでは、自分自身で短いスクリプトをインストールします。 `cron` でログファイルを扱うようにします。

`mysqladmin flush-logs` コマンドか `FLUSH LOGS` SQL文で、 MySQL に新しいログファイルを使用させることが出来ます。 もしあなたが MySQL Version 3.21 を使用しているなら、 `mysqladmin refresh` を使用しなくてはなりません。

上記のコマンドは、以下のように動作します：

- If standard logging (`--log`) or slow query logging (`--log-slow-queries`) is used, closes and reopens the log file. (``mysql.log'` and ```hostname`-slow.log'` as default).
- もし更新ログ (`--log-update`) を使用しているなら、 更新ログを閉じ、新しいログファイルを開きます。そのさい、 ログファイルについている番号は増えます。

もし更新ログだけを使用しているなら、あなたは、ログを flush するだけでよくて、 その時、バックアップのため古い更新ログファイルを移動します。 もし普通のログを使っていれば、あなたは以下のようにすることができます:

    shell> cd mysql-data-directory
    shell> mv mysql.log mysql.old
    shell> mysqladmin flush-logs

こうしておいて、``mysql.old'` をバックアップし削除します。

## 4.10 MySQL のレプリケーション

この章は MySQL の様々なレプリケーション機能を説明します。レプリケーション で有効なオプションのリファレンスとしても役立ちます。レプリケーションの紹介 と、その実装方法を学べます。終りの方には、いくつかの FAQ と問題の説明とそ の解決方法もあります。

### 4.10.1 紹介

一方通行レプリケーションは、堅牢さと速度の両方を増加させるために使用できま す。堅牢さについて、２つのシステムを持つことができ、マスターで問題が発生し た場合にバックアップに切り替えられます。速度の増加は、更新でないクエリの一 部をレプリカサーバに送ることで、成立します。もちろん、これは更新でないクエ リが多い時にだけ働くのですが、通常はそうなります。

バージョン 3.23.15 から、MySQL はワンウェイ・レプリケーションを サポートしました。 1つのサーバーがマスターの役をつとめ，もう一方は、スレーブの役をつとめます。 1つのサーバーはマスターとして動くことも、他に対するスレーブとして動作することも 可能です。 マスターサーバーは update のバイナリログを保持しています( 「4.9.4 The Binary Update Log」節参照.)。 また、インデックスファイルは、バイナリログのローテーションの切り出し記録を残すた めに保持されます。 The slave, upon connecting, informs the master where it left off since the last successfully propagated update, catches up on the updates, and then blocks and waits for the master to notify it of the new updates.

もしデータベースの複製を行なうなら、このデータベースに対する全ての更新は マスター上で行なわなくてはならないことに注意！

レプリケーションを使用することのもう一つの恩恵は、マスターの代わりに、スレー ブでバックアップを行なうことで、システムのライブバックアップを取ることがで きるということです。 「4.4.1 データベースのバックアップ」節参照。

### 4.10.2 レプリケーション実装概要

MySQL レプリケーションは、サーバがデータベースへのすべての変更のトラックを バイナリログ ( 「4.9.4 The Binary Update Log」節参照) に保持し、スレーブサーバがデータのコピー 上で同じクエリを実行できるように、マスターサーバのバイナリログから保存され たクエリを読み込むということを基本にします。

バイナリログは単に固定点(バイナリロギングを有効にした瞬間)からの記録である ことを理解することがとても重要です。セットアップするすべてのスレー ブで、マスターからすべてのデータのコピーが必要です。マスター上でバイナリロ ギングを有効にした瞬間に存在していたように。 スレーブのデータがマスターに存在するデータと違う状態でスレーブを起動したならば、 バイナリログが開始されたときに、スレーブは失敗するでしょう。

MySQL の将来のバージョン(4.0)では、新しいスレーブサーバーのために、 (できる限り、)データのスナップショットを不要にするつもりでいます。 ロックをしなくても live backup を通してスレーブをセットアップできるように。 しかし現時点では、スナップショットを取る間は、マスターを read lock を使って全ての書き込みから保護したり、 シャットダウンしたりする必要があります。

一旦スレーブが適切に構成され、実行していれば、スレーブは単にマスターに接続して、 更新が処理されるのを待つでしょう。 もしマスターがなくなったり、または、スレーブがマスターとの接続性を失えば、 スレーブは再接続できるまで `master-connect-retry` 秒毎に接続を試み、 そして、更新の監視を再開します。

各スレーブはそれが止まった場所のトラックを保持します。マスターサーバはいく つのスレーブが存在し、どれがいつ更新を行なったかについての知識はありません。

次の節はマスター／スレーブ設定過程を詳細に説明します。

### 4.10.3 レプリケーションの設定方法

以下は、現在の MySQL サーバ上に完全なレプリケーションを設定する方法の簡単 な記述です。あなたがすべてのデータベースのレプリケーションを行ないたくて、 事前にレプリケーションを設定していないと仮定します。以下に示すステップを完 了するためには、マスターサーバを少しシャットダウンすることが必要になります。

1. マスターとスレーブに、最新の MySQL (同じバージョン) をインストールしま す。 バージョン 3.23.29 以上を使用すること。 これより前のバージョンでは、バイナリログのフォーマットが違い、また、新しい バージョンで直っているバグも含まれます。 最新のバージョンで確かめるまでは、バグレポートを送らないでください。
2. マスター上に、レプリケーション用の特別なユーザーを登録します。 このユーザーには `FILE` 権限が必要です。全てのスレーブからこのユーザーで 接続できるようにします。 もしユーザーがレプリケーションのみ(推奨)を行なうなら、 他の権限は与える必要は有りません。 例えば、`repl` という名前のユーザー(マスターにアクセス可能なユーザー)を 作成するには、次のようにします：

       GRANT FILE ON *.* TO repl@"%" IDENTIFIED BY '<password>';

3. マスター上の MySQL を停止。

       mysqladmin -u root -p<password> shutdown

4. マスターサーバーにある全てのデータのスナップショットを取る。 (Unixでは) もっとも簡単な方法は tar を使用してデータディレクトリの アーカーブを作成することです。 正確なデータディレクトリの場所はインストール方法に依存します。

       tar -cvf /tmp/mysql-snapshot.tar /path/to/data-dir

   Windows ユーザは WinZip か似たソフトウェアを使用してデータディレクトリのアー カイブを作成することができます。
5. マスターの `my.cnf` ファイル中の `[mysqld]` セクションに、 `log-bin` と `server-id=unique number` を加えます。 ここで指定するマスターの id 番号とスレーブの id 番号は違うものでなくてはなりませ ん。 `server-id` は IPアドレスのような何かを考慮してください - これはレプ リケーションパートナーのコミュニティ内で、サーバの実体を一意に識別します。

       [mysqld]
       log-bin
       server-id=1

6. マスター上の MySQL を再起動します。
7. スレーブの `my.cnf` ファイルに、次を追加します：

       master-host=<hostname of the master>
       master-user=<replication user name>
       master-password=<replication user password>
       master-port=<TCP/IP port for master>
       server-id=<some unique number between 2 and 2^32-1>

   システムに関連したものは <> 内の値で置き換えてあります。 `server-id` には、サーバーそれぞれで違う番号にしなくてはなりません。 (同じ複製のグループ内で)。 もし server-id を指定しなければ、 `master-host` が無い場合には 1 に なり、それ以外の場合には 2 に自動的になります。 マスターで `server-id` の記入漏れがあった場合、 マスターはスレーブからの接続を拒否します。 スレーブ上での記入漏れの場合には、スレーブはマスターへの接続を拒否します。 従って、`server-id` の省略はバイナリログのバックアップのためにだけ良 いことです。
8. スレーブのデータディレクトリにデータのスナップショットをコピーします。 ファイルとディレクトリのユーザーとパーミッションは確実に正しいものに してください。 これらのファイルに対して、 MySQL を実行している アカウントで、読み書きできるようにする必要があります。
9. スレーブの再起動。

上記を行なった後、スレーブはマスターに接続し、スナップショット以後の 更新をキャッチするはずです。

もしスレーブに `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` ファイルを見ることができます。 `master.info` ファイルはスレーブに使用され、 これは、マスターのバイナリログのいくつまで処理したかを保持しています。 このファイルを消したり編集したりしては いけません。 (あなたがやろうとしていることが確実に分かるまでは)。 そういうやむを得ない場合には、 `CHANGE MASTER TO` コマンドの使用の方が良いです。

### 4.10.4 レプリケーション機能と既知の問題

以下はサポートされていることとサポートされていないことの説明です:

- レプリケーションは `AUTO_INCREMENT`, `LAST_INSERT_ID`, `TIMESTAMP` 値を正しく扱います。
- 更新中の `RAND()` はうまく複製できません。 `RAND()` での更新を複製する場合は、`RAND(some_non_rand_expr)` を 使用してください。 例えば、`UNIX_TIMESTAMP()` を `RAND()` の引数に使用するとか。
- マスターとスレーブは同じキャラクタ・セット (`--default-character-set`) を使 用しなくてはなりません。 もし違った場合、スレーブ上で duplicate key errors が出るかもしれません。 これは、マスター上で一意のキーであったとしても、 違う キャラクタ・セット ではそうとはみなされない事があるからです。
- `LOAD DATA INFLIE` は更新の伝達時にマスターサーバ上にまだ存在していれ ば、ただしく処理されます。`LOAD LOCAL DATA INFILE` はスキップされます。
- ユーザー変数を使用したクエリは、(まだ) replication-safe ではありません。
- `FLUSH` コマンドはバイナリログに記録されません。 もちろん、スレーブに複製されません。 これは `FLUSH` が通常は何もデータを変更しないからです。 しかし、仮に `MySQL` の権限データベースを複製していて、 `GRANT` 文ではなくて直接 `MySQL` 権限テーブルを変更した場合には、 権限を反映させるために、スレーブ上で `FLUSH PRIVILEGES` を行なわなくては なりません。
- 3.23.29 以降の一時テーブルは正しく複製されます。ただし、スレーブサーバ(ス レーブスレッドではない)をシャットダウンした時に、いくつかの一時テーブルが オープンされていて、続く更新で使用される場合を除きます。この問題を扱うため に、スレーブをシャットダウンするには、`SLAVE STOP` を行ない、それから `Slave_open_temp_tables` 変数が 0 かどうかをチェックし、そして、 `mysqladmin shutdown` を発行してください。数値が 0 でない場合は、スレー ブスレッドを `SLAVE START` で再起動して、次回に幸運かどうかを見てくだ さい。cleaner solution は、バージョン 4.0 まで待つ必要があります。それ以前 のバージョンの一時テーブルは正しく複製されません - アップグレードするか 一 時テーブルでのすべてのクエリの前にクライアント上で `SET SQL_LOG_BIN=0` の実行をお勧めします。
- MySQL は 1 つのマスターと複数のスレーブの構成のみをサポートします。 4.x では、何かが現在のマスターを故障させた場合に、自動的にマスターを変更す る voting アルゴリズムを追加するでしょう。また、異なるスレーブに select ク エリを送ることで、負荷分散を行なうための手助けとなるような 'エージェント ' プロセスも導入するでしょう。
- バージョン 3.23.26 から、`log-slave-updates` を有効にすることで、 マスターとスレーブの関係を輪っか状にすることが可能です。 しかし、多くのクエリは、この種のセットアップでは正しく動作しません。 違うシーケンス、違うサーバーで行なわれる更新によって引き起こる 潜在的な問題に対応するように、クライアントコードを注意して書かない限りは。 これは以下のようなセットアップを意味します：

      A -> B -> C -> A

  このセットアップはテーブル間での更新に何も衝突が無い場合にのみ、動作します。 仮に A と C でデータを insert するとき、C にinsertするレコードのキーと 競合するようなレコードを A に insert してはいけません。 同じレコードを、２つのサーバーで更新すべきではありません。 もしそこで更新が適用される順番が重要なら。 ログのフォーマットは バージョン 3.23.36 で変更になりました。 3.23.36 以前のスレーブは、3.23.36 以上のログファイルを読むことができません。
- もしスレーブ上でクエリがエラーになると、スレーブのスレッドは停止され、 `.err` ファイルにメッセージが現われます。 この場合、スレーブを手動で接続し、エラーの原因を修正し(例えば、テーブルが無いと か)、 その後、 `SLAVE START` SQLコマンドを実行します (このコマンドはバージョン 3.23.16 以上から)。 バージョン 3.23.15 までは、サーバーを再起動しなくてはなりません。
- もしマスターへの接続が失われた場合、スレーブは直ちにリトライし、 それでも失敗した場合は、 `master-connect-retry` 秒毎（デフォルトでは 60秒）に リトライを繰り返します。 このため、マスターをシャットダウンして、しばらくあとに再起動することは安全 です。スレーブはネットワーク接続性の停止も処理できます。
- スレーブのシャットダウンも安全にできます。レプリケーションを止めた位置を 保存するようにしているからです。 きれいでないシャットダウンは問題を引き起こすでしょう。システムが落ちる前に もしディスクキャッシュがシンクされない場合には特に。 もしあなたが良い UPS を持っているならば、安全性を高めることができるでしょう。
- もしマスターが非標準のポートを使用している場合、 `my.cnf` ファイルに `master-port` パラメターを書くことにより、 ポート番号を指定できます。
- バージョン 3.23.15 では、すべてのテーブルとデータベースが複製されます。バー ジョン 3.23.16 からは `my.cnf` 内の `replicate-do-db` 命令でデー タベースのセットに、または `replicate-ignore-db` でデータベースのセッ トを除外して、複製を制限できます。注意: バージョン 3.23.23 になるまでは、 複製から除外されたデータベースで `LOAD DATA INFILE` を行なうと、正し く扱えないというバグがありました。
- バージョン 3.23.16 から、マスター上で、`SET SQL_LOG_BIN = 0` でレプリケーシ ョン(バイナリ) ログを止めることができます。 `SET SQL_LOG_BIN = 1` で再びログを採取することができます。 これを行なう場合には、process 権限が必要です。
- バージョン 3.23.19 から、何かがおかしくなって、残っている複製をクリーンナップし て、まったくの最初から開始したいときのために、 `FLUSH MASTER` と `FLUSH SLAVE` コマンドが用意されました。 バージョン 3.23.26 から、これらの名前を `RESET MASTER` と `RESET SLAVE` に変更しました。 互換性のために、古い `FLUSH` もまだ動作します。 （訳注： このコマンドは、bin log を 001 からに強制してしまうため、 場合によっては複製をおかしくすることも有る。使用には注意。）
- バージョン 3.23.21 から、 `LOAD TABLE FROM MASTER` をネットワーク越しの バックアップと、レプリケーションのイニシャライズに使用できるようになりました。 ただし、我々は これに関して調査しているという、いくつかのバグ報告を受けているので、 これが安定するまでは、この機能はあくまでもテストとして使用することを 勧めます。
- バージョン 3.23.23 から、 `CHANGE MASTER TO` を使用して、 マスターを変更したりポジションを変更したりできるようになりました。
- バージョン 3.23.23 から、 `binlog-ignore-db` を使用して、 バイナリログを取らないデータベースを指定できるようになりました。
- バージョン 3.23.26 から、 `replicate-rewrite-db` を使用して、 マスター上のデータベースの名前を、スレーブ上では違う名前にするように、 スレーブに指示することができるようになりました。
- バージョン 3.23.28 から、 スレーブが実行している最中に、 古いログを取り去るために、 `PURGE MASTER LOGS TO 'log-name'` が使用できます。

### 4.10.5 my.cnf 内のレプリケーションオプション

レプリケーションを使用する場合は、我々は MySQL Version 3.23.30 以降を 推奨します。 これより古いバージョンでも動きますが、古い物はバグがあったり機能が無かったりしま す。

マスターとスレーブの両方に、 `server-id` オプションが必要です。 これは一意のレプリケーションid をセットします。 マスター、スレーブそれぞれのために、一意な値を、1 から 2^32-1 までの間から 選ばねばなりません。 例: `server-id=3`

以下の表は、MASTER で使用できるオプションを示したものです:

オプション | 説明

`log-bin=filename`

バイナリ update log のファイル名を指定します。 もしこれに拡張子を指定した場合には (例えば `log-bin=/mysql/logs/replication.log` )、 バージョン 3.23.34 までの MySQL では、`FLUSH LOGS` を行なった場合に正しく レプリケーションを行ないません。 この問題は バージョン 3.23.35 で修正されています。 もしこのような log 名を使用するならば、binlog においては `FLUSH LOGS` は無 視されます。 （訳注： これは、バージョン3.23.34までの話です。3.23.36 以上では動作します。） log を clear するには、`FLUSH MASTER` の実行をします。 `FLUSH SLAVE` を全てのスレーブ上で実行することも忘れてはいけません。 バージョン 3.23.36 以上では、`RESET MASTER` と `RESET SLAVE` を使用す べきです。 （訳注： `RESET` はログを本当に全部消してしまうので、注意が必要。）

`log-bin-index=filename` | `FLUSH LOGS` コマンドの実行のためには、どのログが現在使用されているもので、 どれがローテートされたもので、どの順番なのか、ということを知る必要があります。 この情報はバイナリログindexファイルに記述されます。 デフォルトでは `hostname`.index というファイルになります。 違う名前にしたい場合に、このオプションを使用します。 Example: `log-bin-index=db.index`.
`sql-bin-update-same` | 設定されると、`SQL_LOG_BIN` に値を設定すると自動的に `SQL_LOG_UPDATE` を同じ値に設定します。逆も同様です。
`binlog-do-db=database_name` | 現在のデータベースが 'database_name' の場合、バイナリログに更新をログすべ きことをマスターに伝えます。他のすべてのデータベースは無視されます。注意 : これを使用する場合は、現在のデータベースでだけ更新を行なうことを確実にす べきです。 Example: `binlog-do-db=some_database`.
`binlog-ignore-db=database_name` | 現在のデータベースが 'database_name' である更新をバイナリログに格納すべき でないと、マスターに伝えます。注意: これを使用する場合は、現在のデータベー スでだけ更新を行なうことを確実にすべきです。 Example: `binlog-ignore-db=some_database`

次のテーブルは SLAVE に使用できるオプションです:

Option | Description
`master-host=host` | マスタのホスト名か IP アドレス。 もし設定されていないと、スレーブはスタートしません。 Example: `master-host=db-master.mycompany.com`.
`master-user=username` | スレーブスレッドがマスターに接続する時に自分を認証するためのユーザ。ユーザ は `FILE` 権限を持つ必要があります。マスターユーザが設定されない場合 は、`test` が適用されます。 Example: `master-user=scott`.
`master-password=password` | スレーブスレッドがマスターサーバに接続する時に認証するパスワード。設定され ない場合は、空のパスワードが適用されます。 Example: `master-password=tiger`.
`master-port=portnumber` | マスターが listen しているポート。設定されない場合は、`MYSQL_PORT` の コンパイル時の設定が適用されます。`configure` オプションで何もしてな ければ、これは 3306 です。 Example: `master-port=3306`.
`master-connect-retry=seconds` | マスターが落ちたり接続が失われた場合に、スレーブスレッドがマスターへの接続 を再試行するまでに休眠する秒数。デフォルトは 60。 Example: `master-connect-retry=60`.
`master-info-file=filename` | 複製処理がマスターのどこまで行なったかを覚えておくファイルの場所。デフォル トはデータディレクトリの master.info です。Sasha: The only reason I see for ever changing the default is the desire to be rebelious. Example: `master-info-file=master.info`.
`replicate-do-table=db_name.table_name` | 指定されたテーブルに複製を制限することをスレーブスレッドに伝えます。一つ以 上のテーブルを指定するには、この命令を複数回(各テーブルに１回ずつ)使用しま す。This will work for cross-database updates, in contrast to `replicate-do-db`. Example: `replicate-do-table=some_db.some_table`.
`replicate-ignore-table=db_name.table_name` | 指定されたテーブルを複製しないことをスレーブスレッドに伝えます。一つ以上の テーブルを無視するように指定するには、この命令を複数回(各テーブルに１回ず つ)使用します。This will work for cross-datbase updates, in contrast to `replicate-ignore-db`. Example: `replicate-ignore-table=db_name.some_table`.
`replicate-wild-do-table=db_name.table_name` | 指定されたワイルドカードパターンに適合するテーブルに複製を制限することをス レーブスレッドに伝えます。一つ以上のテーブルを指定するには、この命令を複数 回(各テーブルに１回ずつ)使用します。This will work for cross-database updates. Example: `replicate-wild-do-table=foo%.bar%` は foo で始まるすべての データベースの bar で始まるテーブルだけに更新を複製します。
`replicate-wild-ignore-table=db_name.table_name` | 与えられたワイルドカードパターンに適合するテーブルを複製しないことをスレー ブスレッドに伝えます。一つ以上のテーブルを無視するように指定するには、この 命令を複数回(各テーブルに１回ずつ)使用します。This will work for cross-database updates. Example: `replicate-wild-ignore-table=foo%.bar%` は foo で始まるデー タベースの bar で始まるテーブルを更新しません。
`replicate-ignore-db=database_name` | 指定されたデータベースを複製しないことをスレーブスレッドに伝えます。一つ以 上のデータベースを無視するように指定するには、この命令を複数回(各データベー スに１回ずつ)使用します。This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use `replicate-wild-ignore-table=db_name.%` Example: `replicate-ignore-db=some_db`.

`replicate-do-db=database_name`

指定されたデータベースに複製を制限することをスレーブスレッドに伝えます。一 つ以上のデータベースを指定するには、この命令を複数回(各データベースに１回 ずつ)使用します。 Note that this will only work if you do not use cross-database queries such as `UPDATE some_db.some_table SET foo='bar'` while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use `replicate-wild-do-table=db_name.%` Example: `replicate-do-db=some_db`.

`log-slave-updates` | スレーブスレッドからの更新をバイナリログに記録するように、スレーブに告げます。 デフォルトは Off です。 もしスレーブのデイジーチェーン(daisy-chain)を考えているならば、 これを on にする必要があります。
`replicate-rewrite-db=from_name->to_name` | オリジナルと異なる名前のデータベースを更新します。 Example: `replicate-rewrite-db=master_db_name->slave_db_name`.

`slave-skip-errors=err_code1,err_code2,..`

Available only in 3.23.47 and later. Tells the slave thread to continue replication when a query returns an error from the provided list. Normally, replication will discontinue when an error is encountered giving the user a chance to resolve the inconsistency in the data manually. Do not use this option unless you fully understand why you are getting the errors. If there are no bugs in your replication setup and client programs, and no bugs in MySQL itself, you should never get an abort with error.Indiscriminate use of this option will result in slaves being hopelessly out of sync with the master and you having no idea how the problem happened. For error codes, you should use the numbers provided by the error message in your slave error log and in the output of `SHOW SLAVE STATUS`. Full list of error messages can be found in the source distribution in `Docs/mysqld_error.txt`. You can ( but should not) also use a very non-recommended value of `all` which will ignore all error messages and keep barging along regardless. Needless to say, if you use it, we make no promises regarding your data integrity. Please do not complain if your data on the slave is not anywhere close to what it is on the master in this case - you have been warned. Example: `slave-skip-errors=1062,1053` or `slave-skip-errors=all`

`skip-slave-start` | 起動時にスレーブを開始しないようにスレーブサーバに伝えます。ユーザは後で `SLAVE START` で開始できます。
`slave_read_timeout=#` | 読み込みがアボートする前にマスターからデータを待つ秒数。

### 4.10.6 レプリケーションに関連する SQL コマンド

レプリケーションは SQL インタフェースを通じて制御できます。以下はコマンド のサマリです:

Command | Description
`SLAVE START` | スレーブスレッドを開始します。(スレーブ)
`SLAVE STOP` | スレーブスレッドを停止します。(スレーブ)
`SET SQL_LOG_BIN=0` | ユーザが process 権限を持っている場合に更新ログを無効にします。そう でなければ無視されます。(マスター)
`SET SQL_LOG_BIN=1` | ユーザが process 権限を持っている場合更新ロギングを再度有効にします。 そうでなければ無視されます。(マスター)
`SET SQL_SLAVE_SKIP_COUNTER=n` | マスターからの次の `n` イベントをスキップします。スレーブスレッ ドが実行していない場合にだけ正当です。そうでなければエラーになります。レプ リケーションの不調からの復旧に有用です。
`RESET MASTER` | インデックスファイルにリストされたすべてのバイナリログを削除し、 binlog インデックスファイルを空にリセットします。3.23.26 バージョンより前 では、`FLUSH MASTER` (Master)
`RESET SLAVE` | スレーブにマスターログのレプリケーション位置を忘れさせます。 3.23.26 バージョンより前ではこのコマンドは `FLUSH SLAVE` と呼ばれてい ました(Slave)
`LOAD TABLE tblname FROM MASTER` | マスターからスレーブにテーブルのコピーをダウンロードします。 (Slave)

`CHANGE MASTER TO master_def_list`

マスターパラメータを `master_def_list` に指定された値に変更し、 スレーブスレッドを再起動します。`master_def_list` はコンマで区切られ た `master_def` のリストです。`master_def` は次のうちの一つです : `MASTER_HOST`, `MASTER_USER`, `MASTER_PASSWORD`, `MASTER_PORT`, `MASTER_CONNECT_RETRY`, `MASTER_LOG_FILE`, `MASTER_LOG_POS`。Example:

    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;

変更する必要のある値だけを指定する必要があります。省略した値は同じ値を維持 します。ホストまたはポートを変更した時を除きます。この場合、スレーブは異な るホストまたは異なるポートに接続しているのでマスターが異なっているとみなし ます。従って、古いログと位置の値はどこにも該当しません。そして、自動的に空 文字列と 0 にそれぞれリセットされます (開始値)。注意: スレーブを再起動する 場合、最後のマスターを覚えています。これが望ましくない場合、 ``master.info'` ファイルを再起動前に削除すべきです。すると、スレーブは `my.cnf` またはコマンドラインからそのマスターを読み込みます。 (Slave)

`SHOW MASTER STATUS` | マスターの binlog のステータス情報を提供します。(Master)
`SHOW SLAVE STATUS` | スレーブスレッドの基本的なパラメータのステータス情報を提供します。(Slave)
`SHOW MASTER LOGS` | バージョン 3.23.28 以降だけで有効です。マスター上のバイナリログをリストします。どれくらい行くべきかを見つけるためには、このコマンドを `PURGE MASTER LOGS TO` よりも先に使用すべきです。

`PURGE MASTER LOGS TO 'logname'`

バージョン 3.23.28 からの機能。 index ファイルに書かれているログファイルのうち、 指定されたログよりも前のログファイルを全て消します。 index ファイルのリストからもエントリを消します。 そして、指定されたログを一番最初の物とします。 例えば：

    PURGE MASTER LOGS TO 'mysql-bin.010'

（訳注： このコマンドの場合、mysql-bin.001 〜 mysql-bin.009 までの ファイルは消され、mysql.index ファイルの中身は、mysql-bin.010 のみ、 記述される状態になるということ。） 削除しようとしているログの一つを現在読み込み中の実行中スレーブがある場合、 このコマンドは何も行なわず、エラーで失敗します。しかし、休眠中のスレーブが あり、それが読もうとしているログの一つをパージしてしまうと、スレーブは複製 できなくなります。このコマンドはスレーブが複製中には安全に実行できます - それらを停止する必要はありません。 最初に `SHOW SLAVE STATUS` で、どのログが on になっているか、すべての スレーブをチェックする必要があります。それからマスターで `SHOW MASTER LOGS` でログのリストを行ない、すべてのスレーブに共通の最も古いログ を見つけ(すべてのスレーブが最新の場合、リストの最後のログになります)、削除 しようとするすべてのログをバックアップし、目的のログをパージします。

### 4.10.7 Replication FAQ

Q: Why do I sometimes see more than one `Binlog_Dump` thread on the master after I have restarted the slave?

A: `Binlog_Dump` is a continuous process that is handled by the server in the following way:

- Catch up on the updates.
- Once there are no more updates left, go into `pthread_cond_wait()`, from which we can be awakened either by an update or a kill.
- On wake up, check the reason. If we are not supposed to die, continue the `Binlog_dump` loop.
- If there is some fatal error, such as detecting a dead client, terminate the loop.

So if the slave thread stops on the slave, the corresponding `Binlog_Dump` thread on the master will not notice it until after at least one update to the master (or a kill), which is needed to wake it up from `pthread_cond_wait()`. In the meantime, the slave could have opened another connection, which resulted in another `Binlog_Dump` thread.

The above problem should not be present in Version 3.23.26 and later versions. In Version 3.23.26 we added `server-id` to each replication server, and now all the old zombie threads are killed on the master when a new replication thread connects from the same slave

Q: replication log をどうやってローテートするの?

A: バージョン 3.23.28 からでは、`PURGE MASTER LOGS TO` コマンド を使用するべきです。 実行前には、どのログが消せれるか確認し、場合によっては バックアップを取っておきます。 In earlier versions the process is much more painful, and cannot be safely done without stopping all the slaves in the case that you plan to re-use log names. You will need to stop the slave threads, edit the binary log index file, delete all the old logs, restart the master, start slave threads, and then remove the old log files.

Q: How do I upgrade on a hot replication setup?

A: If you are upgrading pre-3.23.26 versions, you should just lock the master tables, let the slave catch up, then run `FLUSH MASTER` on the master, and `FLUSH SLAVE` on the slave to reset the logs, then restart new versions of the master and the slave. Note that the slave can stay down for some time - since the master is logging all the updates, the slave will be able to catch up once it is up and can connect.

After 3.23.26, we have locked the replication protocol for modifications, so you can upgrade masters and slave on the fly to a newer 3.23 version and you can have different versions of MySQL running on the slave and the master, as long as they are both newer than 3.23.26.

Q: What issues should I be aware of when setting up two-way replication?

A: MySQL replication currently does not support any locking protocol between master and slave to guarantee the atomicity of a distributed (cross-server) update. In in other words, it is possible for client A to make an update to co-master 1, and in the meantime, before it propagates to co-master 2, client B could make an update to co-master 2 that will make the update of client A work differently than it did on co-master 1. Thus when the update of client A will make it to co-master 2, it will produce tables that will be different than what you have on co-master 1, even after all the updates from co-master 2 have also propagated. So you should not co-chain two servers in a two-way replication relationship, unless you are sure that you updates can safely happen in any order, or unless you take care of mis-ordered updates somehow in the client code.

You must also realize that two-way replication actually does not improve performance very much, if at all, as far as updates are concerned. Both servers need to do the same amount of updates each, as you would have one server do. The only difference is that there will be a little less lock contention, because the updates originating on another server will be serialized in one slave thread. This benefit, though, might be offset by network delays.

Q: How can I use replication to improve performance of my system?

A: You should set up one server as the master, and direct all writes to it, and configure as many slaves as you have the money and rackspace for, distributing the reads among the master and the slaves. You can also start the slaves with `--skip-bdb`, `--low-priority-updates` and `--delay-key-write-for-all-tables` to get speed improvements for the slave. In this case the slave will use non-transactional `MyISAM` tables instead of `BDB` tables to get more speed.

Q: What should I do to prepare my client code to use performance-enhancing replication?

A: If the part of your code that is responsible for database access has been properly abstracted/modularized, converting it to run with the replicated setup should be very smooth and easy - just change the implementation of your database access to read from some slave or the master, and to always write to the master. If your code does not have this level of abstraction, setting up a replicated system will give you an opportunity/motivation to it clean up. You should start by creating a wrapper library /module with the following functions:

- `safe_writer_connect()`
- `safe_reader_connect()`
- `safe_reader_query()`
- `safe_writer_query()`

`safe_` means that the function will take care of handling all the error conditions.

You should then convert your client code to use the wrapper library. It may be a painful and scary process at first, but it will pay off in the long run. All applications that follow the above pattern will be able to take advantage of one-master/many slaves solution. The code will be a lot easier to maintain, and adding troubleshooting options will be trivial. You will just need to modify one or two functions, for example, to log how long each query took, or which query, among your many thousands, gave you an error. If you have written a lot of code already, you may want to automate the conversion task by using Monty's `replace` utility, which comes with the standard distribution of MySQL, or just write your own Perl script. Hopefully, your code follows some recognizable pattern. If not, then you are probably better off re-writing it anyway, or at least going through and manually beating it into a pattern.

Note that, of course, you can use different names for the functions. What is important is having unified interface for connecting for reads, connecting for writes, doing a read, and doing a write.

Q: When and how much can MySQL replication improve the performance of my system?

A: MySQL replication is most beneficial for a system with frequent reads and not so frequent writes. In theory, by using a one master/many slaves setup you can scale by adding more slaves until you either run out of network bandwidth, or your update load grows to the point that the master cannot handle it.

In order to determine how many slaves you can get before the added benefits begin to level out, and how much you can improve performance of your site, you need to know your query patterns, and empirically (by benchmarking) determine the relationship between the throughput on reads (reads per second, or `max_reads`) and on writes `max_writes`) on a typical master and a typical slave. The example below will show you a rather simplified calculation of what you can get with replication for our imagined system.

Let's say our system load consists of 10% writes and 90% reads, and we have determined that `max_reads` = 1200 - 2 * `max_writes`, or in other words, our system can do 1200 reads per second with no writes, our average write is twice as slow as average read, and the relationship is linear. Let us suppose that our master and slave are of the same capacity, and we have N slaves and 1 master. Then we have for each server (master or slave):

`reads = 1200 - 2 * writes` (from bencmarks)

`reads = 9* writes / (N + 1)` (reads split, but writes go to all servers)

`9*writes/(N+1) + 2 * writes = 1200`

`writes = 1200/(2 + 9/(N+1)`

So if N = 0, which means we have no replication, our system can handle 1200/11, about 109 writes per second (which means we will have 9 times as many reads due to the nature of our application).

If N = 1, we can get up to 184 writes per second.

If N = 8, we get up to 400.

If N = 17, 480 writes.

Eventually as N approaches infinity (and our budget negative infinity), we can get very close to 600 writes per second, increasing system throughput about 5.5 times. However, with only 8 servers, we increased it almost 4 times already.

Note that our computations assumed infinite network bandwidth, and neglected several other factors that could turn out to be significant on your system. In many cases, you may not be able to make a computation similar to the one above that will accurately predict what will happen on your system if you add N replication slaves. However, answering the following questions should help you decided whether and how much, if at all, the replication will improve the performance of your system:

- What is the read/write ratio on your system?
- How much more write load can one server handle if you reduce the reads?
- How many slaves do you have bandwidth for on your network?

Q: 冗長性/高可用性を提供するようにレプリケーションを使用するには？

A: 現在有効な機能で、マスターとスレーブ(またはいくつかのスレーブ 達)をセットアップする必要があります。マスターが生きているかどうかを監視し、 アプリケーションとマスターのスレーブに失敗時に変更を指示するスクリプトを書 きます。以下はいくつかの提案です:

- `CHANGE MASTER TO` コマンドを使用して、スレーブにマスターを変更するよ うに通知します。
- マスターの場所が通知されるアプリケーションを保持する良い方法は、マスターの エントリをダイナミック DNS によって持つことです。bind では `nsupdate` を使って DNS を動的に更新できます。
- スレーブを `log-bin` オプション付きで `log-slave-updates` 無しで 実行すべきです。この方法で、`STOP SLAVE`; `RESET MASTER`、他のス レーブ上で `CHANGE MASTER TO` を実行すると、すぐにスレーブがマスター になるように準備ができます。 It will also help you catch spurious updates that may happen because of misconfiguration of the slave (ideally, you want to configure access rights so that no client can update the slave, except for the slave thread) combined with the bugs in your client programs (they should never update the slave directly).

我々は現在自動マスター選択システムを MySQL に統合するように働いていますが、 準備ができるまでは、あなた自身のモニタリングツールを作成する必要があります。

### 4.10.8 Troubleshooting Replication

If you have followed the instructions, and your replication setup is not working, first eliminate the user error factor by checking the following:

- Is the master logging to the binary log? Check with `SHOW MASTER STATUS`. If it is, `Position` will be non-zero. If not, verify that you have given the master `log-bin` option and have set `server-id`.
- Is the slave running? Check with `SHOW SLAVE STATUS`. The answer is found in `Slave_running` column. If not, verify slave options and check the error log for messages.
- If the slave is running, did it establish connection with the master? Do `SHOW PROCESSLIST`, find the thread with `system user` value in `User` column and `none` in the `Host` column, and check the `State` column. If it says `connecting to master`, verify the privileges for the replication user on the master, master host name, your DNS setup, whether the master is actually running, whether it is reachable from the slave, and if all that seems ok, read the error logs.
- If the slave was running, but then stopped, look at SHOW SLAVE STATUS output and check the error logs. It usually happens when some query that succeeded on the master fails on the slave. This should never happen if you have taken a proper snapshot of the master, and never modify the data on the slave outside of the slave thread. If it does, it is a bug, read below on how to report it.
- If a query on that succeeded on the master refuses to run on the slave, and a full database resync ( the proper thing to do ) does not seem feasible, try the following:
  - First see if there is some stray record in the way. Understand how it got there, then delete it and run `SLAVE START`
  - If the above does not work or does not apply, try to understand if it would be safe to make the update manually ( if needed) and then ignore the next query from the master.
  - If you have decided you can skip the next query, do `SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;` to skip a query that does not use auto_increment, or last_insert_id or `SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE START;` otherwise. The reason auto_increment/last_insert_id queries are different is that they take two events in the binary log of the master.
  - If you are sure the slave started out perfectly in sync with the master, and no one has updated the tables involved outside of slave thread, report the bug, so you will not have to do the above tricks again.
- Make sure you are not running into an old bug by upgrading to the most recent version.
- If all else fails, read the error logs. If they are big, `grep -i slave /path/to/your-log.err` on the slave. There is no generic pattern to search for on the master, as the only errors it logs are general system errors - if it can, it will send the error to the slave when things go wrong.

When you have determined that there is no user error involved, and replication still either does not work at all or is unstable, it is time to start working on a bug report. We need to get as much info as possible from you to be able to track down the bug. Please do spend some time and effort preparing a good bug report. Ideally, we would like to have a test case in the format found in `mysql-test/t/rpl*` directory of the source tree. If you submit a test case like that, you can expect a patch within a day or two in most cases, although, of course, you mileage may vary depending on a number of factors.

Second best option is a just program with easily configurable connection arguments for the master and the slave that will demonstrate the problem on our systems. You can write one in Perl or in C, depending on which language you know better.

If you have one of the above ways to demonstrate the bug, use `mysqlbug` to prepare a bug report and send it to bugs@lists.mysql.com. If you have a phantom - a problem that does occur but you cannot duplicate "at will":

- Verify that there is no user error involved. For example, if you update the slave outside of the slave thread, the data will be out of sync, and you can have unique key violations on updates, in which case the slave thread will stop and wait for you to clean up the tables manually to bring them in sync.
- Run slave with `log-slave-updates` and `log-bin` - this will keep a log of all updates on the slave.
- Save all evidence before resetting the replication. If we have no or only sketchy information, it would take us a while to track down the problem. The evidence you should collect is:
  - All binary logs on the master
  - All binary log on the slave
  - The output of `SHOW MASTER STATUS` on the master at the time you have discovered the problem
  - The output of `SHOW SLAVE STATUS` on the master at the time you have discovered the problem
  - Error logs on the master and on the slave
- Use `mysqlbinlog` to examine the binary logs. The following should be helpful to find the trouble query, for example:

      mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head

Once you have collected the evidence on the phantom problem, try hard to isolate it into a separate test case first. Then report the problem to bugs@lists.mysql.com with as much info as possible.

Go to the first, previous, next, last section, table of contents.