1

バックアップの目的でレプリケートする予定のデータベースがあります (現時点ではパフォーマンスは問題ではありません)。

レプリケーションを正しくセットアップしてテストしたところ、すべて問題ありませんでした。

その後、すべての書き込みが一時テーブルに複製されることに気付きました。これは、実際には、アイドル状態のスレーブで 1 日分のデータの複製に約 2 時間かかったことを意味します。

その理由は、15 分ごとに cronjob を介してデータベース内のデータの一部を再計算し、同期していることを確認するためです (合計で約 3 分かかるため、Web 要求中にこれらの操作を行うことは受け入れられません。代わりに、 Web リクエスト中に何も再計算を試みずに変更を保存し、すべての作業をまとめて実行します)。そのデータを効率的に処理するために、一時テーブルを使用します (多くの相互依存関係があるため)。

ここで、最初の問題は、一時テーブルを使用するトランザクションの処理中にスレーブを再起動すると、一時テーブルが保持されないことです。これは、一時テーブルを使用しないことで回避できますが、これには独自の問題があります。

より深刻な問題は、再計算がすべて行われなければ、スレーブが 30 分以内に簡単に追いつく可能性があることです (再計算は次々に行われるため、15 分ごとにデータを再構築する利点はありません...文字通り、たとえば 1115 でスタックしているのを見ることができますが、すぐに追いついて 1130 でスタックするなど)。

私たちが思いついた解決策の 1 つは、そのすべての再計算をレプリケートされたデータベースから移動して、スレーブがそれをレプリケートしないようにすることです。ただし、最終的に更新するテーブルを削除する必要があり、スレーブを実質的に「去勢」する必要があるという欠点があります。実際に使用する前に、すべてを再計算する必要があります。

誰かが同様の問題を抱えていましたか、またはどのように解決しますか? 明らかな何かが欠けていますか?

4

2 に答える 2

3

私は解決策を思いつきました。Nick が言及した replica-do-db を利用します。誰かが同様の問題を抱えていた場合に備えて、ここに書き留めておきます。

この場合、replicate-(wild-)do* オプションを使用するだけの問題 (私が言ったように、一時テーブルを使用して中央テーブルを再作成します) は、一時テーブルを無視して、データなしで中央テーブルを再作成することです (これにより、最新の中央テーブルに依存するすべてのクエリが異なる結果を生成するため、さらなる問題が発生する可能性があります) または同様の問題がある中央テーブルを無視します。言うまでもなく、これらのオプションを my.cnf に追加した後、mysql を再起動する必要があります。これ以上の再起動を必要とせずに、これらすべてのケース (および将来のケース) をカバーする何かが必要でした。

そこで、データベースを「リアル」データベースと「ワークエリア」データベースに分割することにしました。「実際の」データベースのみがレプリケートされます (replicate-wild-do-table 構文に使用するテーブル名の規則を決めることができると思います)。

すべての一時テーブルの作業は「workarea」データベースで行われ、上記の依存関係の問題を回避するために、INSERT ... SELECT または RENAME TABLE によって中央テーブル (「実際の」データベースにある) にデータを入力しませんが、 tmp テーブルにクエリを実行して、ライブ テーブルで一種の差分を生成します (つまり、新しい行の INSERT ステートメントを生成し、古い行の DELETE ステートメントを生成し、必要に応じて更新します)。

このように複製されるクエリは、まさに必要な更新のみであり、他には何もありません。15 分ごとに発生する再計算クエリの一部 (ほとんど?) は、スレーブに到達することさえできない可能性があります。

于 2008-09-26T11:51:18.600 に答える
2

MySQL では、5.0 の時点で、テーブル ワイルドカードを使用して特定のテーブルを複製できると思います。設定できるコマンドライン オプションは多数ありますが、MySQL 構成ファイルを介してこれを行うこともできます。

[mysqld]
replicate-do-db    = db1
replicate-do-table = db2.mytbl2
replicate-wild-do-table= database_name.%
replicate-wild-do-table= another_db.%

指定したテーブル以外のテーブルを複製しないように指示するという考えです。

于 2008-09-22T18:13:32.780 に答える