MySQL でレプリケーション フィルターを動的に変更する方法

MySQL でレプリケーション フィルターを動的に変更する方法

MySQLはレプリケーションフィルターを動的に変更します

今日遭遇した問題についてお話しします。今日は、かなり異常なビジネス上の要求に対処していました。簡単に説明します。

1. オンライン Alibaba Cloud RDS にはゲーム ログ ライブラリがあります。その中のテーブルは日次テーブル形式になっており、データ量は比較的大きいです。バックアップを実行するたびに、オンライン RDS はアラームを発生させ、アラームの内容は IO リソースが過剰に占有されているというものです。

2. このRDSにはローカルECS読み取り専用スレーブデータベースがあります。この読み取り専用スレーブデータベースは、オンラインRDSデータベースのデータをリアルタイムで同期します。この読み取り専用スレーブデータベースは、ビジネス側でクエリに使用されます。

3. ビジネス側は、これらのデータはすべてまだ有用であると述べました。読み取り専用スレーブ データベースのデータは利用可能である必要があり、オンライン RDS のデータは削除可能であり、2 週間保持するだけで済みます。

シナリオは次のようになります。DBA はアラームの問題を解決したいと考えており、ビジネス側は完全なデータを確保したいと考えています。この問題を解決するにはどうすればいいでしょうか?

この質問を見たとき、私は悪態をつきたくなりました。この要件は不合理です。1 つのデータベースを削除して、別のデータベースに保存しておくなんて、どうやってできるのでしょうか。それに、それらはすべてログ データです。コールド バックアップを作成してから、オンラインのものを削除すればいいのではないでしょうか。しかし、状況を緩和する余地はなかったので、この問題をどうやって解決するかを考え始めました。私が考えた解決策は次のとおりです。

1. 容量を拡張し、パフォーマンスを向上します。データ量が多いのでディスクを拡張します。IO使用率が高いのでパフォーマンスを向上させます。これは最も直接的な解決策ですが、最も高価な解決策でもあり、最初に切断されます。

2. 最初にバックアップし、次に削除して復元します。事前に日次テーブルデータをRDSマスターデータベースにバックアップし、データを削除します。このとき、スレーブデータベースも同期的にデータを削除し、最初のステップでバックアップしたデータをスレーブデータベースに復元します。この方法は、データが失われないことが保証されるため実行可能です。しかし、操作はかなり複雑で、手順が多すぎて、あまり便利ではありません。

3. replicate-ignore-table パラメータを使用して、指定したテーブルをフィルタリングします。このパラメータを設定すると、指定されたデータ テーブルのすべての操作をフィルターできます。このパラメータの説明については、公式ドキュメントを見てみましょう。リンクはこちらです: https://dev.mysql.com/doc/refman/5.7/en/replication-options-slave.html#option_mysqld_replicate-wild-ignore-table

説明は次のとおりです。

レプリケーションフィルタを作成し、指定されたワイルドカードパターンに一致するテーブルがあるステートメントをスレーブスレッドが複製しないようにします。無視するテーブルを複数指定するには、このオプションを複数回使用します。

上記は、このパラメータを使用して、設定したルールに一致する特定のテーブルに対する操作を除外するフィルタを作成できることを意味します (わかりにくいようです)。つまり、フィルタリング ルールを設定し、テーブル a をルールに追加すると、テーブル a に対する操作はスレーブ データベースに同期されなくなります。

これは私たちのニーズに沿ったものです。つまり、テーブルをフィルタリングするように設定すると、テーブルを削除してもデータベースからテーブルが削除されず、目的の結果が得られます。この機能をテストしてみましょう:

まず、データベース test_ignore を作成し、その中にテーブルを作成します。

メインデータベースでの操作:

mysql:test_ignore >>テーブルを表示;
空のセット (0.00 秒)

mysql:test_ignore >>テーブルaaaを作成します(id int not null);
クエリは正常、影響を受けた行は 0 行 (0.19 秒)

mysql:test_ignore >>テーブルaabを作成します(id int not null);
 クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql:test_ignore >>テーブルaacを作成します(id int not null);
 クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql:test_ignore >>テーブルaadを作成します(id int not null);
 クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql:test_ignore >>テーブルaaeを作成します(id int not null);
 クエリは正常、影響を受けた行は 0 行 (0.01 秒)

図書館からの眺め:

mysql:test_ignore >>テーブルを表示;
+-----------------------+
| テスト中のテーブルを無視 |
+-----------------------+
|ああ|
| アブ |
| 日本語
| アード |
| アエー |
+-----------------------+
セット内の行数は 5 です (0.00 秒)

同期されていることがわかりました。この時点で、マスターとスレーブの同期状態が確立されています。ここでマスター データベース上のテーブルを削除すると、スレーブ データベース上のテーブルも確実に削除され、これは望ましい結果ではありません。

当然、次のステップは、replicate-wild-ignore-table パラメータを構成することです。通常は、スレーブ サービスを停止して my.cnf ファイルを構成する必要があります。複数のテーブルを構成する場合は、my.cnf ファイルに複数のワイルドカード レコードを書き込む必要があります。たとえば、この例では、パラメータの値は test_ignore.aa% として設定する必要があります。ここで、% はワイルドカードを表します。つまり、test_ignore データベース内の aa% 形式のテーブル操作はフィルター処理されます。作成したテーブル aaa、aab、aac、aad、aae はすべてこの形状であるため、これらのテーブルに対する操作はスレーブ データベースに同期されません。テストしてみましょう。

まず、現在のレプリケーション ステータスを確認します。

ダブルイエスステータスは、レプリケーション関係に問題がないことを意味します

メインライブラリは以下を運営しています:

mysql :test_ignore >>テーブルaaaを削除します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql :test_ignore >>テーブルaabを削除します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

図書館からの眺め:

mysql:test_ignore >>テーブルを表示;
+-----------------------+
| テスト中のテーブルを無視 |
+-----------------------+
|ああ|
| アブ |
| 日本語
| アード |
| アエー |
+-----------------------+
セット内の行数は 5 です (0.00 秒)

スレーブデータベースのテーブルはまだ存在しており、マスターデータベースの操作がスレーブデータベースに同期されていないことを示しています。設定したパラメータは

replicate-wild-ignore-table=test_ignore.aa%

うまくいきました。この時点で、マスター データベースにテーブルを作成すると、次のようになります。

メインライブラリ
mysql:test_ignore >>テーブルaaf(id int)を作成します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

「ライブラリから」
mysql:test_ignore >>テーブルを表示;
+-----------------------+
| テスト中のテーブルを無視 |
+-----------------------+
|ああ|
| アブ |
| 日本語
| アード |
| アエー |
+-----------------------+
セット内の行数は 5 です (0.00 秒)

aaf もルール test_ignore.aa% に一致するため、スレーブ データベースはマスター データベースのテーブル aaf を同期していないことがわかります。

この機能を使用することで、メイン データベースが削除され、スレーブ データベースにデータが保持されるというビジネス シナリオを非常にうまく解決できます。しかし、この方法には重大な問題があり、スレーブ データベースを毎回再起動する必要があります。2 番目のルールと 3 番目のルールを設定する必要がある場合、スレーブ データベースを 2 回または 3 回再起動する必要があります。このプロセス中、スレーブ データベースはビジネス パーティには表示されません。アクセスできない場合、プログラム エラーが発生する可能性があり、これは耐えられません。

このプロセスを解決する必要がありますが、どのように解決すればよいでしょうか?ダウンタイムなしでレプリケーション フィルターを変更する方法はありますか?公式ドキュメントを探してください。

案の定、この生きている間にもマシンをシャットダウンすることは不可能です。公式文書にはこのような一文があります。

CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE ステートメントを発行して、このようなフィルターを作成することもできます。

この文は一体何なのでしょうか? 一度も使われていないことを意味します。オンラインでコピー フィルターを変更することでフィルターを変更できます。公式ドキュメントの紹介を参照してください:

魔法のような文章を見つけたので、試してみましょう。

mysql:test_ignore >>レプリケーションフィルターを変更 replicate_wild_ignore_table=('test_ig%.aa%');
エラー 3017 (HY000): この操作は実行中のスレーブ SQL スレッドでは実行できません。まず STOP SLAVE SQL_THREAD を実行してください。

mysql:test_ignore >>スレーブを停止します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql:test_ignore >>レプリケーションフィルターを変更 replicate_wild_ignore_table=('test_ig%.aa%');
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql:test_ignore >>スレーブを起動します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

直接使用すると、スレーブ sql_thread を停止する必要があるというプロンプトが表示されます。 よく考えてみると、レプリケーションを停止せずにレプリケーション ルールを変更するのは少し不適切であるように思われます。 レプリケーション全体を停止してから、レプリケーション フィルターを再度変更するだけです。 うまくいきます。 正常に実行され、レプリケーションが有効になります。 操作はスムーズです。

レプリケーション関係のステータスを見てみましょう。

無視されるテーブル ルールは test_ig%.aa% になりました。つまり、test_ig で始まるデータベース内の aa で始まるテーブルに対するすべての操作 (テーブルの変更、削除、作成操作を含む) は、スレーブ データベースに同期されません。

しかし、ここで解決策が出てきます。日次テーブルは一般的にYYYYMMDD形式であることがわかっています。日次テーブルをYYYYMM%形式でフィルタリングし、マスターデータベースで削除するだけです。この操作はスレーブデータベースに同期されないため、この問題はスムーズに解決できます。

もちろん、この解決策に加えて、次のような他の解決策もあります。

ビジネスで部分的なデータ損失が許容される場合は、binlog を閉じてテーブルを削除し、binlog を開いてスレーブ データベースがマスター データベースのドロップ操作を同期しないようにする方法も使用できます。

すべてのオンライン日次テーブル操作は無視するように構成され、トリガーを使用して日次テーブルの更新がスレーブ データベースに同期されます。

この一連の操作は、実際には問題を根本的に解決するものではありません。本質的にはビジネス設計の問題です。日次テーブルにはドットログが多すぎます。これらのドットログは適切に削減できます。ドットログについては、保存期間を決定する必要があります。期限切れのログは、サーバーの指標とパフォーマンスを確保するために、時間内にクリーンアップする必要があります。

上記は、MySQL でレプリケーション フィルターを動的に変更する方法の詳細です。MySQL でレプリケーション フィルターを動的に変更する方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySql マスタースレーブレプリケーションメカニズムの包括的な分析
  • ディスク容量不足による MySQL レプリケーション障害の解決方法
  • MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明
  • MySQLテーブルをコピーする方法
  • MySQL 8.0.23 のレプリケーション アーキテクチャにおけるスレーブ ノードの自動フェイルオーバー
  • MYSQL データベース GTID はマスタースレーブレプリケーションを実現します (超便利)
  • MySql マスタースレーブレプリケーションの実装原理と構成
  • MySQL の WriteSet 並列レプリケーションの簡単な分析
  • MySQL マスタースレーブレプリケーションの原理と注意点
  • MySQL 並列レプリケーションの簡単な分析
  • MySQL レプリケーション問題の 3 つのパラメータの分析

<<:  Docker データボリュームコンテナの作成と使用状況分析

>>:  スローモーションアニメーション効果を実現するJavaScript

推薦する

MySQL 文字列連結関数 GROUP_CONCAT の詳細な説明

前回の記事では、クロステーブル更新について書きました。自分が書いた SQL を見たとき、自分がバカみ...

JavaScript排他的思考の具体的な実装

前回のブログで、Xiao Xiong は関連する要素の操作方法を更新しましたが、同じ要素のグループが...

Linux カーネル デバイス ドライバーのメモリ管理に関する注意事項

/************************ * Linux メモリ管理 *********...

nginx共有メモリの仕組みの詳細な説明

Nginx の共有メモリは、高いパフォーマンスを実現できる主な理由の 1 つであり、主にファイル キ...

CSS3は小さな矢印のさまざまなグラフィック効果を実現します

CSS を使ってさまざまなグラフィックを実現できるのは素晴らしいことです。画像を切り取る必要はなく、...

WeChatミニプログラムでEchartとサブパッケージを使用するための完全な手順

序文休日は終わっていますが、それは別の形で(お腹に触れることで)私たちに現れます。ミニプログラムでデ...

Linux 名前空間ユーザーの詳細な説明

ユーザー名前空間は Linux 3.8 で追加された新しい名前空間で、ユーザー ID やグループ I...

MySQL 8.0.13 で日付を 0000-00-00 00:00:00 に設定すると発生する問題を解決する

データベース操作を学び始めたばかりです。今日、データを保存していたところ、エラーが発生していることに...

Vueはスクロールバースタイルを実装します

最初はブラウザのスクロールバーのスタイルを変更して効果を実現したいと思っていましたが、情報を調べてみ...

英語の単語の出現頻度を数えるtrコマンドの魔法

置換を削除したり文字列を削除したりできる tr コマンドは、誰もがよく知っています。 英語では、英語...

WindowsにOpenSSHをインストールし、SSHキーを生成してLinuxサーバーにログインします。

SSH の正式名称は Secure SHell です。 SSH を使用すると、送信されるすべてのデ...

Docker の 4 つのネットワーク タイプの主な例

4 つのネットワーク タイプ:なし: コンテナのネットワーク機能を一切設定しません。--net=no...

Nginx 急ぎ購入 電流制限構成 実装分析

ビジネス上のニーズにより、急ぎの購入が発生することが多いため、ロード バランシング フロント エンド...

Pagoda Panel のインストール時にサーバーがデータベースにリモート接続できない問題の解決策

自分のウェブサイトを構築する予定なので、618 プロモーションを利用して Tencent Cloud...

CSS を使用して、画像に 3D の凸型と凹型のエフェクト (フレーム外に凸型、またはフレーム内に凹型) を実現します。

Ⅰ. 問題の説明: CSS を使用して画像の 3D 凸凹効果を実現します。 Ⅱ実施手順は以下のとお...