Q:マスタがすでに実行中でそれを停止したくない場合、どのようにスレーブをセットアップしますか。
        A:いくつかの方法があります。マスタのバックアップを作成してあり、スナップショットに対応するバイナリログ名とオフセットを記録(SHOW
        MASTER STATUS
        の出力から)してある場合は、以下を実行します。
      
スレーブに一意のサーバ ID が割り当てられていることを確認する。
各パラメータに適切な値を割り当て、以下のステートメントをスレーブで実行する。
mysql>CHANGE MASTER TO->MASTER_HOST='master_host-name',->MASTER_USER='master_user_name',->MASTER_PASSWORD='master_pass',->MASTER_LOG_FILE='recorded_log_name',->MASTER_LOG_POS=recorded_log_pos;
            スレーブで START SLAVE
            を実行する。
          
マスタのバックアップがない場合、以下の方法ですばやく確実にスレーブのセットアップを実行できます。
            FLUSH TABLES WITH READ LOCK
          
            gtar zcf /tmp/backup.tar.gz
            /var/lib/mysql(または、このバリエーション)
          
            SHOW MASTER
            STATUS(後で必要となるため、出力を必ず記録しておく)
          
            UNLOCK TABLES
          
        代替手段として、上記のバイナリコピーの代わりに、マスタの
        SQL
        ダンプを使用することもできます。これを行うには、マスタで
        mysqldump --master-data
        を実行し、後でその SQL
        ダンプをスレーブで実行します。ただし、これはバイナリコピーよりも時間がかかります。
      
2 つの方法のどちらを使用する場合でも、その後、スナップショットがあり、ログ名およびオフセット値を記録する場合の指示に従ってください。同じスナップショットを使用して複数のスレーブをセットアップできます。いったんマスタのスナップショットを作成すれば、マスタのバイナリログが損傷を受けない限り、数日後でも、場合によっては一ヶ月後でもそのスナップショットを使用してスレーブをセットアップできます。理論的には、待機できる時間は無限です。現実的な制約としては、マスタのディスク空き容量が古いログによって減っていくことと、スレーブがマスタに追いつくのに時間がかかることが挙げられます。
        LOAD DATA FROM MASTER
        を使用することもできます。これはスナップショットを撮り、スレーブにそれをリストアして、スレーブ上のログ名とオフセットを調整することを、全部同時に実行できる便利なコマンドです。将来は、LOAD
        DATA FROM MASTER
        がスレーブセットアップの推奨方法となります。ただし、このコマンドを使用した場合、読み取りロックが長時間掛かる可能性があります。このコマンドはまだ理想とする効率性では実装されていません。大きなテーブルがある場合、現時点での推奨方法は、FLUSH
        TABLES WITH READ LOCK を実行後のローカル
        tar スナップショットです。
      
Q: スレーブは常にマスタに接続しておく必要がありますか。
A: いいえ、その必要はありません。スレーブは何時間でも、あるいは何日間でもシャットダウンしておいたり、非接続にしておいても、再接続してマスタの更新に追いつくことができます。たとえば、マスタとスレーブの関係をダイヤルアップリンクでセットアップし、リンクアップを散発的かつ短時間に設定できます。この場合、何か特殊な対策をとらないと、任意の時点でスレーブがマスタと同期されている保証はありません。将来、少なくとも 1 つのスレーブが同期するまでマスタをブロックするオプションを追加する予定です。
Q: スレーブがマスタと比較してどれだけ遅れているかを知るにはどうすればいいですか。つまり、スレーブによってレプリケートされた最後のクエリの日付を知る方法はありますか。
        A: スレーブが 4.1.1
        以降の場合は、SHOW SLAVE STATUS の
        Seconds_Behind_Master
        カラムを参照します。これより前のバージョンについては、次のようになります。スレーブ
        SQL スレッドが存在する場合、つまりSHOW
        PROCESSLIST で表示される場合(MySQL 3.23
        では、スレーブスレッドが存在する場合、つまりスレーブスレッドが
        SHOW PROCESSLIST
        で表示される場合)(see
        項4.11.3. 「レプリケーションの実装の詳細」)、およびそのスレッドがマスタから読み取ったイベントを最低
        1
        回は実行している場合のみ、スレーブによってレプリケートされた最後のクエリの日付を知ることができます。実際、スレーブ
        SQL
        スレッドがマスタから読み取ったイベントを実行すると、このスレッドは自分の時間をそのイベントのタイムスタンプに修正します(これが、TIMESTAMP
        もレプリケートする理由です)。結果、SHOW
        PROCESSLIST 出力の Time
        カラムでスレーブ SQL
        スレッドに対して表示される秒数は、最後にレプリケートされたイベントのタイムスタンプとスレーブマシンの実際の時刻の差になります。これを使用して、最後にレプリケートされたイベントの日付を特定できます。注意:
        スレーブがマスタから切断されて 1
        時間経過してから再接続した場合、SHOW
        PROCESSLIST の Time
        カラムでスレーブ SQL スレッドが 3600
        の値を表示する場合があります。これは、スレーブが実行しているクエリが、タイムスタンプから
        1 時間経過しているためです。
      
Q: スレーブが追いつくまでマスタの更新をブロックするにはどうしますか。
A: 以下の手順を実行します。
マスタで、以下のコマンドを実行する。
mysql>FLUSH TABLES WITH READ LOCK;mysql>SHOW MASTER STATUS;
            SHOW
            ステートメントの出力からログ名とオフセットを記録する。
          
            スレーブで以下のコマンドを実行する。ここで、MASTER_POS_WAIT()
            関数の引数であるレプリケーション座標は、前のステップで記録した値。
          
mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
            指定のログファイルおよびオフセットにスレーブが到達するまで、SELECT
            ステートメントによってブロックされる。到達した時点でスレーブはマスタと同期しており、こここでステートメントが戻る。
          
マスタで以下のステートメントを発行し、マスタによる更新処理の再開を許可する。
mysql> UNLOCK TABLES;
Q: 二方向レプリケーションをセットアップするときに注意すべき点はありますか。
A: MySQL レプリケーションでは、現在のところ、分散(サーバ間の)更新の原子性を保証するためのマスタとスレーブ間のロッキングプロトコルをサポートしていません。つまり、クライアント A が co-master 1 に更新を行い、それを co-master 2 に伝播する前に、クライアント B が co-master 2 に更新を行って、クライアント A の更新が co-master 1 で行ったものとは変わってしまう可能性があります。この場合、co-master 2 からの更新がすべて伝播した後であっても、クライアント A の更新が co-master 2 に伝わったとき、co-master 1 とは異なるテーブルが生成されます。このため、どのような順序でも更新が安全に行われるという確証がある場合、またはクライアントコードで更新順序の不正に対処できる場合以外は、二方向レプリケーションで 2 つのサーバをチェーン状に設定しないでください。
また更新については、二方向レプリケーションはそれほどパフォーマンス向上に役立たないことも認識してください。サーバは両方ともそれぞれ、1 つのサーバのときと同じ量の更新を行います。違いは、別のサーバから発生した更新が 1 つのスレーブスレッドでシリアル化されるため、ロックの競合が少なくなることぐらいです。その利点も、ネットワーク遅延によって相殺されてしまいます。
Q: レプリケーションを使用してシステムのパフォーマンスを改善する方法はありますか。
        A: 1
        つのサーバをマスタとしてセットアップし、すべての書き込みをそれにダイレクトします。そして予算とスペースが許容する限り多くのスレーブをセットアップし、マスタと複数のスレーブで読み取りを分散します。--skip-bdb、--low-priority-updates、および
        --delay-key-write=ALL
        でスレーブを起動すると、スレーブの速度が向上します。この場合、スレーブは速度を上げるため、BDB
        テーブルの代わりに非トランザクションの
        MyISAM テーブルを使用します。
      
Q: パフォーマンス改善レプリケーションを使用するアプリケーションを作成したいのですが、クライアントコードはどうすればいいですか。
A: コード内のデータベースアクセスを担当する部分が適切に抽象化つまりモジュール化されていれば、レプリケートのセットアップで実行できるように変換するのはスムーズかつ簡単です。データベースアクセスの実装部分を変更し、すべての書き込みをマスタに、そして読み取りをマスタかスレーブに送信するようにします。ご使用のコードにこのレベルの抽象化がなされていなければ、レプリケーションシステムを 1 からセットアップします。まず以下の関数で、ラッパライブラリまたはモジュールを作成します。
            safe_writer_connect()
          
            safe_reader_connect()
          
            safe_reader_query()
          
            safe_writer_query()
          
        各関数名の safe_
        は、関数がすべてのエラー条件を処理することを意味します。もちろん、関数には別の名前を使用することも可能です。重要なことは、読み取りのための接続、書き込みのための接続、読み取り実行、および書き込み実行で統合インタフェースを持つことです。
      
次に、ラッパライブラリを使用するようにクライアントコードを変換します。このプロセスは最初は苦痛かもしれませんが、長期的に見ると損はありません。先ほど説明したアプローチを使用するアプリケーションはすべて、マスタ/スレーブ構成の利点を活用できます。これは、スレーブが複数の場合でも同様です。コードは保守が非常に簡単で、トラブルシューティングオプションの追加も手間がかかりません。1 つか 2 つの関数を修正するだけで、各クエリにかかった時間をログしたり、数千のクエリの中からどのクエリがエラーの原因になったかを特定することなどができます。
        コード作成の経験が豊富であれば、replace
        ユーティリティを使用して変換タスクを自動化することもできます。このユーティリティは
        MySQL
        の標準ディストリビューションに含まれています。また、独自の
        Perl スクリプトを作成することもできます。
        コードが認識可能なパターンに従っていれば理想的です。そうでない場合は、書き換えるのが良いでしょう。あるいは少なくとも、1
        つのパターンになっているようにしてください。
      
Q: MySQL レプリケーションによって、どのような場合にどれだけシステムのパフォーマンスを改善できますか。
A: MySQL レプリケーションは、読み取り頻度が高く、書き込み頻度が低いシステムで最も威力を発揮します。単一マスタと複数スレーブのセットアップを使用することにより、理論的にはネットワーク帯域幅の限界またはマスタが処理できる更新負荷の限界までスレーブを追加することにより、システムを拡張できます。
        追加する利点がなくなるまでいくつのスレーブを追加できるか、またサイトのパフォーマンスをどれだけ改善できるかを判断するには、クエリパターンを知り、実証的に(ベンチマークを使用して)通常のマスタと通常のスレーブの間の読み取り(毎秒ごとの読み取り、または
        max_reads)と書き込みスループットの関係を調べる必要があります。ここでは、例として、仮想システムのレプリケーションでの単純化した計算を示します。
      
        システム負荷が 10% の書き込みと 90%
        の読み取りで構成され、max_reads
        が 1200 - 2 * max_writes
        であると仮定します。
        つまり、書き込みがなければシステムは毎秒
        1200
        の読み取りを実行できます。書き込みの平均は読み取り平均の
        2
        倍かかります。そしてその関係は直線的です。
        マスタと各スレーブの能力は同じで、1
        マスタと N
        スレーブがあると想定します。各サーバ(マスタまたはスレーブ)は以下のようになります。
      
        reads = 1200 - 2 *
        writes(ベンチマークから)
      
        reads = 9* writes / (N + 1)
        (読み取りは分散されるが、書き込みはすべてのサーバで行われる)
      
        9*writes/(N+1) + 2 * writes = 1200
      
        writes = 1200/(2 + 9/(N+1)
      
この分析により、以下の結論を導きだせます。
N = 0(レプリケーションがないことを意味する)の場合、システムは 1200/11、つまり毎秒 109 書き込みを処理できる(アプリケーションの性質上、読み取りが 9 倍になる)。
N = 1 の場合、毎秒 184 の書き込みまで処理できる。
N = 8 の場合、毎秒 400 の書き込みまで処理できる。
N = 17 であれば、480 の書き込みとなる。
N が無限に近づくと(予算も無限大に膨らむが)、毎秒 600 の書き込みに近くなり、システムスループットは 5.5 倍になる。しかし、8 サーバだけで 4 倍近くになっている。
注意: この計算ではシステム帯域を無限として想定しており、現実の場面では重要となるかもしれない要因をいくつか無視しています。多くの場合、N アプリケーションスレーブを追加した場合の結果を正確に予測する上記のような計算を行うのは難しいと言えます。しかし、以下の質問から、レプリケーションによってシステムのパフォーマンスが改善されるかどうか、またどの程度改善されるか、ある程度判断できるでしょう。
システムの読み取りと書き込みの比率はどれくらいか。
読み取りを減らした場合、1 つのサーバで処理できる書き込み負荷をどの程度増やせるか。
ネットワークの帯域幅を使用できるスレーブ数の上限はいくつか。
Q: 冗長性と高可用性を実現するようにレプリケーションを使用するにはどうすればよいですか。
A: 現在使用可能な機能で、1 つのマスタと 1 つのスレーブ(または複数のスレーブ)をセットアップする必要があります。そして、マスタの稼働状態を監視し、失敗時にアプリケーションとスレーブにマスタの変更を指示するスクリプトを作成します。以下のガイドラインを参考にしてください。
            スレーブにマスタを変更するよう指示するには、CHANGE
            MASTER TO コマンドを使用する。
          
            アプリケーションにマスタの場所を認識させておくためには、マスタに動的
            DNS
            エントリを採用すると良い。bind
            で、nsupdate を使用して DNS
            を動的に更新できる。
          
            --log-bin
            オプションを指定し、--log-slave-updates
            なしでスレーブを実行する。STOP
            SLAVE および RESET MASTER
            を実行し、他のスレーブで CHANGE MASTER
            TO
            を実行することにより、スレーブがマスタになる準備ができる。たとえば、以下のセットアップがあると仮定する。`M''
            はマスタ、``S'' はスレーブ、``WC''
            はデータベース読み取りおよび書き込みを発行するクライアントを意味する。データベース読み取りだけを発行するクライアントは、切り替えの必要がないため、ここでは考慮されていない。
          
       WC
        \
         v
 WC----> M
       / | \ 
      /  |  \ 
     v   v   v
    S1   S2  S3
            S1(S2 および S3
            と同様)は、--log-bin
            を使用し、--log-slave-updates
            なしで実行しているスレーブである。S1
            で実行される書き込みは M
            からのレプリケーションのみなので、S1
            のバイナリログは空白である(S1
            は --log-slave-updates
            なしで実行されている)。 何らかの理由で M
            が利用できなくなったため、S1
            を新しいマスタにする(すべての WC を S1
            にダイレクトし、S2 と S3 が S1
            をレプリケートするように設定する)。
          
            すべてのスレーブで、自身のリレーログにあるすべてのクエリを処理したことを確認する。各スレーブで
            STOP SLAVE IO_THREAD
            を発行し、SHOW PROCESSLIST
            の出力で Has read all relay log
            が表示されることを確認する。すべてのスレーブでこれを確認したら、新しい環境に設定できる。すべてのスレーブで
            STOP SLAVE
            を発行し、マスタに昇格するスレーブに
            RESET MASTER
            を、他のスレーブには CHANGE
            MASTER を実行する。
          
            これで、M にアクセスする WC
            はいなくなる。すべての WC に、クエリを S1
            に送信するよう指示する。これ以降、WC
            によって S1 に送信されたクエリはすべて、S1
            のバイナリログに書き込まれる。S1
            のバイナリログには、M
            が終了した時点以降に S1
            に送信されたクエリがすべて正確に含まれる。
            S2(および S3)で、STOP
            SLAVE、CHANGE MASTER TO
            MASTER_HOST='S1'
            を実行する('S1' には S1
            の実際のホスト名が入る)。CHANGE
            MASTER で、S2 または S3 から S1
            に接続するための全情報(ユーザ、パスワード、ポート)を追加する。CHANGE
            MASTER で、S1
            のバイナリログの名前や位置を指定する必要はない。それが最初のバイナリログであり、位置が
            4 であることがわかっており、これらの値は
            CHANGE MASTER
            のデフォルトとなっているからである。最後に、S2
            と S3 で START SLAVE
            を実行すると、以下のようになる。
          
       WC   
      /   
      |  
 WC   |  M(unavailable)
  \   | 
   \  | 
    v v
     S1<--S2  S3  
      ^       |
      +-------+
            M が再稼動したら、S2 および S3 と同じように
            CHANGE MASTER
            を実行するだけで済む。そうすると M は S1
            のスレーブとなり、ダウンしてから実行された
            WC 書き込みをすべてピックアップする。M
            をマスタに戻す(それが一番強力なマシンである、という理由などで)には、S1
            と M
            の立場を逆にして前回の手順を繰り返す。このとき、S1、S2、S3
            を M のスレーブにする前に、M で RESET
            MASTER
            を実行することを忘れてはいけない。そうしないと、M
            が非稼動になる前の古い WC
            書き込みも拾ってしまう。
          
現在、自動マスタ選択システムを MySQL に統合する方向で進んでいますが、それが実現するまでは、自分で監視ツールを作成してください。
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

