MySQLで一意のサーバーIDを生成する方法

MySQLで一意のサーバーIDを生成する方法

序文

MySQL では、server-id を使用してデータベース インスタンスを一意に識別し、それをチェーンまたはデュアル マスター レプリケーション構造で使用して、SQL ステートメントの無限ループを回避することは周知の事実です。この記事では、サーバー ID についての私の理解を共有し、一意のサーバー ID を生成するいくつかの方法を比較検討します。

server_idの目的

つまり、server_id には 2 つの目的があります。

1. バイナリログ イベントの発生元、つまり SQL ステートメントの発生元をマークするために使用されます。

2. IO_thread を使用してメイン ライブラリの binlog をフィルター処理します。 replicate-same-server-id=1 が設定されていない場合、スレーブの io_thread はイベントのソースが自身の server-id と同じであることを検出すると、イベントをスキップし、リレー ログに書き込みません。スレーブ ライブラリの sql_thread は当然イベントを実行しません。これにより、連鎖構造またはデュアルメイン構造における SQL ステートメントの無限ループを回避できます。

注:同じサーバー ID を持つイベントは io_thread レベルでフィルタリングされますが、replicate-(do|ignore)- などのルールは sql_thread レベルでフィルタリングされます。 io_thread と sql_thread の両方にフィルタリング機能があります。

server_id を繰り返すことができないのはなぜですか?

同じクラスター内でサーバー ID が重複すると、奇妙な問題が発生する可能性があります。

次の 2 つのケースを考えてみましょう。

図1: マスターとスレーブのサーバーIDは異なりますが、2つ以上のスレーブが同じサーバーIDを持っています

この場合、レプリケーションは左右に振れます。 2 つのスレーブ ライブラリのサーバー ID が同じ場合、スレーブ ライブラリ 1 がマスター ライブラリに接続されていると、スレーブ ライブラリ 2 もマスター ライブラリに接続する必要があります。同じサーバー ID で以前に接続されていたことがわかった場合は、まず接続をキャンセルしてから再登録します。

次のコード スニペットを参照してください。

int register_slave(THD* thd、uchar* パケット、uint パケット長)
{
 整数 ;
 SLAVE_INFO *si;
...
 (!(si->master_id = uint4korr(p))の場合)
 si->master_id= サーバーID;
 si->thd= thd;
 pthread_mutex_lock(&LOCK_slave_list);
/* 最初に同じサーバー ID を持つ接続を登録解除します */
 スレーブの登録を解除します(thd,0,0); 
/* 再登録 */
 res = my_hash_insert(&slave_list, (uchar*) si);
 pthread_mutex_unlock(&LOCK_slave_list);
 res を返します。
...
}

2 つのスレーブは絶えず登録と登録解除が行われ、大量のリレー ログ ファイルが生成されます。スレーブのステータスを確認すると、リレー ログ ファイル名が絶えず変化し、スレーブのレプリケーション ステータスが「はい」になったり「接続中」になったりしていることがわかります。

図2: チェーン構造またはデュアルマスター構造では、マスターとスレーブのサーバーIDは同じです

スレーブ 1 もリレー データベースです。正しく同期し、リレー ログの内容を独自のバイナリ ログに書き換えることができます。サーバー ID 100 のスレーブ 2 IO スレッドがバイナリログを取得すると、すべての内容が自分自身からのものであることがわかり、これらのイベントを破棄します。そのため、スレーブ 2 はマスターのデータを正しく同期できません。リレー サーバーに直接書き込まれたイベントのみをスレーブ 2 に正しく同期できます。

上記の 2 つのケースから、同じレプリケーション セット内のサーバー ID の一意性を維持することが非常に重要であることがわかります。

server_id の動的変更

偶然、サーバー ID を動的に変更できることを発見しましたが、あまり喜ばないほうがいいでしょう。利点は、上記の図 1 の場合、スレーブの 1 つのサーバー ID を変更するだけでサーバー ID の競合を解決できることです。次の構造に示すように、欠点は非常に隠れています。

ここで、何らかの理由でアクティブ マスターがパッシブ マスターとの同期を失い、パッシブ マスターで DDL 変更が行われたとします。その後、DBA は突然、パッシブ マスターのサーバー ID を 400 に変更することを思いつきました。デュアルマスターレプリケーションが開始されると、パッシブマスターで以前に実行されたサーバー ID 200 の DDL 変更が無限ループに陥ります。 alter table t engine=innodb の場合は、停止することは決してありません。しかし、update a=a+1; のような SQL を見つけるのは困難です。もちろん、このシナリオは私の作り話です。プライマリとバックアップの 2 つのバックアップ マシンをデュアル マスターに変換したときに発生する奇妙なスレーブ ラグ問題のより現実的な例を次に示します。http://hatemysql.com/2010/10/15/神奇的奴-lag问题時官方的官方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的官​​方的

これら 2 つの例は、サーバー ID を変更するのは少し危険であり、変更しない方がよいことを説明するためだけに挙げました。では、1 つの手順で生成することは可能でしょうか?

一意のserver_idを生成する

一般的に使用される方法は次のとおりです。

1. 乱数を使用する

MySQL のサーバー ID は 0 から 4294967295 までの 4 バイトの整数であるため、この範囲内のランダムな数字をサーバー ID として使用した場合に競合が発生する可能性は非常に低くなります。

2. タイムスタンプを使用する

日付 +%s を直接使用してサーバー ID を生成します。 1 日が 86400 秒であると計算し、今後 50 年間を計算すると、使用される最大のサーバー ID は 86400*365*50 となり、これはサーバー ID 範囲内に完全に入ります。

3. IPアドレス+ポートを使用する

これは私たちがよく取るアプローチです。たとえば、IP アドレスが 192.168.122.23 でポート番号が 3309 の場合、server-id は 122233309 と記述できます。競合の可能性は比較的小さく、*.*.122.23 または *.*.12.223 が検出され、3309 が同じレプリケーション セットで構築された場合にのみ発生します。

4. 集中型番号ジェネレータを使用する

管理サーバーでは、自己増分 ID を使用してサーバー ID を均一に割り当てます。これにより、競合が起こらないことが保証されますが、中央ノードのメンテナンスが必要になります。

5. 各レプリケーションセットを個別に管理する

各スレーブ データベースのサーバー ID が競合しないように、各レプリケーション セットの MySQL データベースに管理テーブルを追加します。

上記の方法はすべて有効ですが、次の点に注意してください。

  • 方法 4 ではメンテナンスの負担が増し、開発環境、テスト環境、オンライン環境の番号ジェネレータのセットをメンテナンスするのは少々面倒です。これらを混在させると、ネットワーク セグメントが分離されるリスクがあり、番号ジェネレータ データベースの権限の問題を制御するのが難しくなります。したがって、お勧めできません。
  • 方法 5 は自律性を実現しますが、管理コストが少し高くなります。スレーブ データベースは、マスター データベースの server-id テーブルに書き込むことができる必要がありますが、これは複雑です。
  • 5 つの方法すべてに共通する問題は、コールド スタンバイ データを使用して容量を拡張する場合、サーバー ID を手動で変更する必要があることです。そうしないと、コールド スタンバイ ソースのサーバー ID と競合します。さらに、MySQL を起動したときに、バックアップによって拡張されたばかりなのか、それとも以前は正常に動作していたのかはわかりません。したがって、サーバー ID を変更するかどうかはわかりません。この厄介な問題を完全にブロックするために、サーバー ID が DBA に対して完全に透過的であり、競合が発生しないことを願っています。

推奨されるアプローチ

実はとても簡単です。 ipv4 は 4 バイトの整数で、範囲は server-id と同じです。 MySQL インスタンスを一意に識別できるのは IP アドレス + ポートのみであると考えているため、IP 情報とポート情報の両方を server-id に統合することを常に望んでいます。ただし、同じ IP 上で 2 つの同一ポートを同時に起動することはできないことに注意してください。したがって、server-id は IP アドレスの整数形式のみである必要があります: select INET_ATON('192.168.12.45'), 3232238637!新しく起動されたすべてのインスタンスに対して、MySQL 起動スクリプトはサーバー ID のチェックを強制します。間違ったサーバー ID が見つかった場合は、修正されてから起動されます。この方法には前提条件があります。同じマシン上の複数のインスタンスはマスターとスレーブの関係を持たないようにする必要があります。そうしないと、同じサーバー ID によって問題が発生します。この状況は通常、テスト環境でのみ発生し、オンラインでは基本的に発生しません。この前提が満たされれば、すべての問題は簡単に解決できます。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • MySQL マスタースレーブ同期における server-id の例の詳細な説明

<<:  Vite2とVue3を使用したウェブサイトの国際化を実現するプロセス全体

>>:  Linuxシステムにおけるキー認証に基づくSSHサービスのプロセス

推薦する

10秒以内にMySQLデータベースに数百万件のレコードを挿入する実装

まず、次の質問について考えてみましょう。このような膨大な量のデータをデータベースに挿入するには、通常...

React で Antd の Form コンポーネントを使用してフォーム機能を実装する方法

1. 構造部品1. フォームには、入力コントロール、標準フォーム フィールド、ラベル、ドロップダウン...

Linux の操作とメンテナンスの基本 httpd 静的 Web ページ チュートリアル

目次1. ウェアハウスを使用してhttpd lrzsz解凍ファイルを作成する2. ソースコードファイ...

ウェブサイトをより高く、よりデザイン的に見せる方法

「ウェブサイトを高級感のあるものにするにはどうすればいいでしょうか? それともデザイン重視にすればい...

CenOS6.7 mysql 8.0.22 のインストールと設定方法のグラフィックチュートリアル

CenOS6.7 は MySQL8.0.22 (推奨コレクション) をインストールします1. MyS...

MYSQLについては、データ型と操作テーブルを知る必要があります

データ型と操作データテーブル1.1 MySQL 型: 整数 1.2 MySQL データ型: 浮動小数...

Linux で MongoDB のリモート自動バックアップを実装する方法

序文古いプロジェクトを引き継ぐ苦労 - MongoDB クラスターの学習と構築に関する前回の記事を読...

MySQL 8.0.12 のインストールと設定のグラフィックチュートリアル

MySQL 8.0.12 のダウンロードとインストールのチュートリアルを録画し、全員と共有しました。...

MySQLのSeconds_Behind_Masterの詳細な説明

目次マスターの後ろの秒数オリジナルの実装最終マスタータイムスタンプマスターとのクロック差他の実行時間...

Vue プロジェクトのパッケージ化と最適化の実装手順

目次Vueプロジェクトのパッケージ化、起動、最適化Vueプロジェクトのパッケージ化プロジェクトホステ...

Linux yum コマンドを使用して mysql8.0 をインストールする方法の詳細なチュートリアル

1. 設置前によく掃除する rpm -pa | grep mysql または rpm -qa | g...

JavaScript クロージャの説明

目次1. クロージャとは何ですか? 2. クロージャの役割2.1) メモリ2.2) プライベート変数...

サーバー間のファイル バックアップ ソリューション、サーバー ファイルを別のサーバーに自動的にバックアップする方法は?

多くの組織ではファイル サーバーをバックアップする必要があり、あるサーバーから別のファイル サーバー...

vue+antv でレーダーチャートを実装するためのサンプルコード

1. 依存関係をダウンロードするnpm インストール @antv/データセットnpm インストール ...

Windows 10 での MySQL 8.0 のダウンロードとインストール構成のグラフィック チュートリアル

この記事では、MySQL 8.0のダウンロードとインストールについてご紹介します。具体的な内容は以下...