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


19 Solving some common problems with MySQL

19.1 データベースの複製

One way replication can be used both to increase robustness and speed. For robustness you have two systems and switch to the backup if you get problems you witch to the backup. The extra speed is achieved by sending a part of the non updating queries to the replica server. Of course this only works if non updating queries dominate, but that is the normal case.

One way replication is planned for the near future. This will be implemented so that slave servers will be synchronized with low priority updates and delayed inserts up to date (this will give readers higher priority than writers).

MySQL doesn't (yet) have database replication, but here are some info on how do to it.

データベースを複製する最も一般的な方法は、更新ログを使用することです。 「9.2 更新ログ」節参照。これは、あるデータベースがマスター(主)として動作して (全てのデータ変更がここで行われます)、一つ以上の他のものがスレーブ(従)と して動作することを要求します。スレーブを更新するには mysql < update_log を実行します。 スレーブデータベースに適切なホスト、ユーザー、パスワードオプションをあたえ、 マスターからの更新ログを入力に使用します。

もし、テーブルからなにも削除することが無い場合、 TIMESTAMP 項を使用すれば、 最後の複製時以後に、新規に挿入されたものや変更されたものだけを ミラーサーバーにコピーできます。(複製時の時間と比較すれば抽出できます)

更新ログ(削除のため)とタイムスタンプ(両側で)の両方を使用する2つの方法の 更新システムを作ることができます。しかしこの場合は、同じデータが両側で変 更された時に、あなたが衝突を操作できなければなりません。あなたはおそらく 何が更新されたかを決定するのを助けるために、古いバージョンを保持したいで しょう。

この場合の複製は SQL ステートメントで行われるため、データベースを更新す るステートメント中で次の関数は使ってはいけません。これらは他の MySQL サーバでは異なる値を返すからです:

全ての時刻関数は、必要な場合にミラーにタイムスタンプを送るようにして、安 全に使用できます。LAST_INSERT_ID() も安全に使用できます。

19.2 データベースのバックアップ

MySQL テーブルはファイルとして格納されるため、バックアップを行 うのは簡単です。矛盾のないバックアップを得るためには、LOCK TABLES を関連するテーブルで行ってください。 「7.24 LOCK TABLES/UNLOCK TABLES 構文」節参照. 読み込みロックだ けが必要なので、そのテーブルでデータベースディレクトリのファイルのコピー が行われている間も、他のスレッドはクエリを継続できます。もしくは、SQL レ ベルのバックアップを行いたいのであれば、SELECT INTO OUTFILE を使 用できます。

他の方法は mysqldump プログラムを使用することです:

  1. フルバックアップをとるには:
    shell> mysqldump --tab=/path/to/some/dir --opt --full
    
    若しサーバーがいっさいデータの変更をしないのであれば、 単に全てのテーブルファイル(`*.frm', `*.MYD', `*.MYI' files)を コピーするだけでも構いません。
  2. mysqld を止め、そして --log-update オプションをつけて起動します。 `hostname.n' という名前でログファイルが作成されます。ここで n は数字で、 これは mysqladmin refresh, mysqladmin flush-logs を実行する度に増えていきます。 FLUSH LOGS 構文を使用したり、サーバーを再起動しても増えます。 これらログファイルは、 mysqldump 実行後に行われたデータベースの変更を 複製するための情報を与えてくれます。

もしリストアをしなければならない場合、まず最初に myisamchk -r を実行して テーブルの修復を試みてください。 ほとんどの場合、99.9% 修復はできるはずです。 もし myisamchk が失敗した場合、以下のようにします:

  1. オリジナルの mysqldump バックアップデータをリストアします。
  2. 以下のコマンドのようにして、更新ログに記録されている変更を適用します。
    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 は、'重複インデックス' 衝突があった場合、 新しいレコードを挿入する時に古いレコードが新しいものに置き換えられることを意味します。

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

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

複数のサーバーをたちあげる場合、簡単な方法として、 TCP/IP ポート、ソケットファイルを変えて、サーバーをコンパイルする方法があります。

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

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

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

現在走っている MySQL サーバーのソケットとポートを知るには、以下のようにします:

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

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

立ち上げスクリプト(おそらく `mysql.server' ファイル)を編集して 複数の MySQL サーバーを立ちあげても構いません。

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

shell> /path/to/safe_mysqld --socket=file-name --port=port_number

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

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

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

shell> /path/to/safe_mysqld --datadir=/new/path/to/datadir \
                --socket=file-name --port=file-name

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


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