MySQL の WriteSet 並列レプリケーションの簡単な分析

MySQL の WriteSet 並列レプリケーションの簡単な分析

【歴史的背景】

私は 3 年間 MySQL-DBA として働いてきましたが、MySQL が「基本的に利用可能」、「MySQL は限界的なシステムで使用可能」から「ああ、やばい! なぜ MySQL を使わないのか」へと進化するのを目の当たりにしてきました。

諺にある通りです! 「データベースの運命は、歴史的プロセスとそれ自身の闘争の両方にかかっています!」ここでは「歴史的プロセス」については説明しません。「自己闘争」については、並列レプリケーションのいくつかの重要な時間ノードについてのみお話ししたいと思います。

一般的に、MySQL はこれまで並列レプリケーションの 3 つの重要なタイム ノード、「データベース間の同時実行」、「グループ コミット」、および「書き込みセット」を経験してきました。各世代には独自の才能があり、以前の波は浜辺で死んでいくと言えます。一般的に、後続の世代は以前の世代よりもはるかに優れています。

[ライブラリ間の同時実行]

データベース間の同時実行の理論的根拠は、インスタンス内に複数のライブラリ (スキーマ) が存在する可能性があり、異なるライブラリ間に依存関係がないことです。そのため、スレーブ側ではライブラリ (スキーマ) ごとに個別の SQL スレッドが開始されます。このように、マルチスレッド並列レプリケーションによってマスター スレーブ レプリケーションの効率を向上させることができます。

この理論は良さそうですが、実際には 1 つのインスタンスに対してビジネス ライブラリは 1 つしかないため、ライブラリ間のこのような同時実行は役に立ちません。つまり、この方法は比較的少数のシナリオに適用可能であり、この欠点は「グループ送信」まで解決されませんでした。

【グループ応募】

グループコミットの理論的根拠は次のとおりです。複数のトランザクションを同時にコミットできる場合、これは間接的にこれらのトランザクションのロックに競合がないことを示します。つまり、それぞれが異なるロックを保持し、互いに影響しません。論理的には、複数のトランザクションをグループと見なし、スレーブ上の「グループ」単位で実行するために SQL スレッドに割り当てます。これにより、複数の SQL スレッドを並列に実行できます。並列処理の粒度はデータベースに基づいていないため、「データベース間の同時実行」よりも効果があります。

これには実際にはいくつかの問題があります。データベース上である程度の同時実行性が必要であり、そうでない場合、各グループにトランザクションが 1 つしか存在しない可能性があり、これはシリアルと変わりません。この問題を解決するために、MySQL は送信前に待機する 2 つのパラメータを提供します。これにより、グループ内のトランザクションが可能な限り多くなり、並列レプリケーションの効率が向上します。

binlog_group_commit_sync_no_delay_count 」は、より低い基準を設定します。つまり、コミットする前にグループに十分なトランザクションが存在する必要があります。これにより、グループに十分なトランザクションが存在しない状態が防止されます。

複数のトランザクションの場合、MySQL は時間に基づいて別のパラメータ「 binlog_group_commit_sync_delay 」も提供します。このパラメータは、最大で待機する時間を示します。この時間が経過すると、トランザクションが完了していなくてもトランザクションはコミットされます。

個人的な経験です! 特に、これら 2 つのパラメータの適切な値を見つけるのは困難です。今日適切であっても、数日後にビジネスが変化すると不適切になる可能性があります。MySQL が独自に適応効果を実現できれば素晴らしいでしょう。この適応効果は WriteSet を通じてのみ実現できます (WriteSet はこれら 2 つのパラメータを自動的に調整することによって実現されるのではなく、まったく異なるソリューション アプローチを使用します)。

【書き込みセット】

WriteSet はどのような問題を解決しますか?もちろん、「グループ提出」の問題も解決! これは何も言わないのと同じなので、例を挙げてみましょう (より学術的な例です)。1 日目に id == 1 の行を更新し、2 日目に id == 2 の行を更新し、3 日目にスレーブが来てデータを同期したとします。 「グループ コミット」の性質上、これら 2 つの更新は異なる「グループ」にパッケージ化されます。つまり、2 つのグループが存在することになります。各グループには 1 つのトランザクションしかないため、論理的にはシリアルです。

DBA としては、これら 2 つは互いに競合せず、同じグループにパッケージ化してもデータの不整合は発生しないため、実際に同じグループにパッケージ化できることがわかります。 つまり、2つの選択肢がある

方法 1): 姉さん、あなたは大胆にも「binlog_group_commit_sync_no_delay_count」を 2 に設定しました。つまり、グループには少なくとも 2 つのトランザクションが含まれている必要があり、「 binlog_group_commit_sync_delay 」を 24 時間以上に設定します。本当にやるなら家に帰ってください。データベースが遅すぎて (最初の更新は 1 日待たされました) 完了しません!

方法 2): MySQL に、最近変更された内容を記録する小さなノートブックを使用するように指示します。今変更するデータが以前のデータと競合しない場合は、同じグループにパッケージ化できます。前の例を引き続き使用すると、2 日目に変更された値の ID は == 2 であるため、1 日目と競合せず、2 日目の更新と 1 日目の更新を同じグループに完全にパッケージ化できます。この方法では、グループ内に 2 つのトランザクションが存在し、スレーブが 3 日目にそれらを再生すると、並列効果が発生します。

この小さなノートブックは本当に素晴らしいですね。もっと大きくすることはできますか?確かに!パラメーターbinlog_transaction_dependency_history_sizeは、小さなノートブックの容量です。私の MySQL にはこの小さなノートブックがありますか? MySQL が mysql-5.7.22 より新しい場合は、小さなノートブックが組み込まれています。

つまり、「WriteSet」は巨大な「グループ送信」の基盤の上に構築されており、マスター上で自己適応型のパッケージングとグループ化が行われるため、マスターに2つのパラメータを追加するだけで済みます。

binlog_transaction_dependency_tracking = WRITESET # COMMIT_ORDER   
トランザクション書き込みセット抽出 = XXHASH64

理論については説明したので、次は実践を見てみましょう。

【WriteSetの練習】

WriteSet に基づく並列レプリケーション環境の構築方法、つまり、通常の「グループ コミット」よりもマスターに 2 つのパラメータを追加する方法については詳しく説明しません。2 つの並列レプリケーション モードでの動作の変更点のみを説明します。

1): 実行したいターゲットSQLは次のとおりです

データベース tempdb を作成します。
tempdb を使用します。
テーブル person(id int not null auto_increment primary key,name int) を作成します。

person(name) 値(1) に挿入します。
person(name) 値に挿入(2);
person(name) の値に挿入します(3);
person(name) 値に挿入(5);

2): 上記のSQLをグループ送信別にグループ化したものを見てみましょう。

3): write_setがグループ送信を最適化する方法を確認する

各挿入は並列実行できるため、同じグループ(同じlast_committed)にグループ化されていることがわかります。last_committed、sequence_number、これらの2つの値はbinlogに記録されます。binlogを解析するときは、通常、次のオプションを使用します。

mysqlbinlog -vvv --base64-output='デコード行' mysql-bin.000002

【まとめ】

WriteSet は、「グループ コミット」方式に基づいて構築された新しい並列レプリケーション実装です。これは、「グループ コミット」よりも柔軟性があります。もちろん、同時実行性の向上により、WriteSet は「グループ コミット」よりも優れたパフォーマンスを発揮します。一部の WriteSet が競合を解決できない場合は、「グループ コミット」モードにスムーズに移行できます。

上記は、MySQL WriteSet 並列レプリケーションの詳細の簡単な分析です。MySQL WriteSet 並列レプリケーションの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL 並列レプリケーションの簡単な分析
  • MySQL並列レプリケーションの簡単な説明
  • MySQL5.7 並列レプリケーションの原理と実装

<<:  HTMLにリンクを挿入する方法

>>:  nginx での書き換えジャンプの実装

推薦する

Linux環境変数ファイルの簡単な紹介

Linux システムでは、環境変数は適用範囲に応じて、システムレベルの環境変数とユーザーレベルの環境...

JPQLに基づく純粋なSQL文方式の詳細な説明

JPQL は Java Persistence Query Language の略です。 Java ...

MySQLのスローログの開き方と保存形式の詳細な分析

開発プロジェクトでは、MySQL のスロークエリログを通じて効率の問題のある SQL を監視できます...

CentOS7環境でDockerを使ってPHP動作環境を構築する手順を詳しく解説

関連記事: CentOS7でyumを使用してDockerをインストールするDockerを使ってWin...

UbuntuでOpenCVをコンパイルしてインストールする方法

opencv2 の簡単なインストール: conda インストール --channel https:/...

React Native JSIはRNとネイティブ通信のサンプルコードを実装します

目次JSIとはJSIの違いiOS で JSI を使用するiOS 設定RN側の構成jsはパラメータ付き...

Linux ipcsコマンドの使用

1. コマンドの紹介ipcs コマンドは、Linux のプロセス間通信機能の状態を報告するために使用...

トークンの有効期限が切れたときにページを更新するときに繰り返しプロンプトが表示されないようにする Vue について

トークンの有効期限が切れたら、ページを更新します。ページの読み込み時にバックエンドに複数のリクエスト...

MySql ログイン パスワードを忘れた場合とパスワードを忘れた場合の解決策

方法1: MySQL では、次のコマンド ラインで MySQL サーバーを起動することにより、アクセ...

MacOS での MySQL 8.0.18 のインストールと設定方法のグラフィック チュートリアル

この記事では、MacOSでのMySQL 8.0.18のインストールと成功したコマンドライン操作を記録...

Docker メモリ監視とストレステストの方法

起動していたDockerコンテナはメモリを使い果たした状態になっており、再起動せずにコンテナのメモリ...

LinuxサーバのSSHクラッキング防止方法(推奨)

1. Linuxサーバーは、/etc/hosts.denyを設定して、相手のIPがSSH経由でサー...

CSS の読み込みによってブロックが発生しますか?

おそらく誰もが js の実行によって DOM ツリーの解析とレンダリングがブロックされることを知って...

MySQL のデータ削除とデータ テーブル メソッドの例

MySQL でデータやテーブルを削除するのは非常に簡単ですが、削除するとすべてのデータが消えてしまう...

よくある CSS のヒントと経験談 11 選

1. 画像の下にある数ピクセルの空白を削除するにはどうすればよいですか?コードをコピーコードは次のと...