MySQLデュアルマスター(マスターマスター)アーキテクチャ構成ソリューション

MySQLデュアルマスター(マスターマスター)アーキテクチャ構成ソリューション

企業では、データベースの高可用性は常に最優先事項です。多くの中小企業は、MySQL マスター スレーブ ソリューション、1 つのマスターと複数のスレーブ、読み取りと書き込みの分離などを使用しています。ただし、単一のマスターには単一障害点があり、スレーブ データベースからマスター データベースに切り替えるときに変更を加える必要があります。そのため、デュアルマスターまたはマルチマスターの場合は、高可用性を高めるために MySQL エントリが追加されます。ただし、複数のマスターの場合は、自己増分 ID の問題を考慮する必要があります。これには特別な設定ファイルが必要です。たとえば、デュアル マスターの場合はパリティを使用できます。つまり、マスター間で競合のない自己増分 ID を設定することで、自己増分 ID の競合問題を完全に解決できます。

マスタースレーブ同期複製の原理

始める前に、まずマスター/スレーブ同期レプリケーションの原理を理解しましょう。

コピーは 3 つのステップに分かれています。

1. マスターはバイナリ ログに変更を記録します (これらの記録はバイナリ ログ イベントと呼ばれます)。
2. スレーブはマスターのバイナリ ログ イベントをリレー ログにコピーします。
3. スレーブはリレー ログ内のイベントをやり直し、データを自身のものに反映するように変更します。

次の図はこのプロセスを説明しています。

プロセスの最初の部分は、マスターがバイナリ ログを記録することです。各トランザクションがデータの更新を完了する前に、マスターはこれらの変更をセカンダリ ログに記録します。 MySQL は、トランザクション内のステートメントがインターリーブされている場合でも、トランザクションをバイナリ ログにシリアルに書き込みます。イベントがバイナリ ログに書き込まれた後、マスターはストレージ エンジンにトランザクションをコミットするように通知します。

次のステップは、スレーブがマスターのバイナリ ログを自身のリレー ログにコピーすることです。まず、スレーブはワーカー スレッド (I/O スレッド) を開始します。 I/O スレッドはマスター上で通常の接続を開き、binlog ダンプ プロセスを開始します。 Binlog ダンプ プロセスは、マスターのバイナリ ログからイベントを読み取ります。マスターに追いついた場合は、スリープ状態になり、マスターが新しいイベントを生成するまで待機します。 I/O スレッドはこれらのイベントをリレー ログに書き込みます。

SQL スレーブ スレッドはプロセスの最終ステップを処理します。 SQL スレッドはリレー ログからイベントを読み取り、スレーブのデータを更新してマスターのデータと一致するようにします。スレッドが I/O スレッドと一貫性を保っている限り、リレー ログは通常 OS のキャッシュ内にあるため、リレー ログのオーバーヘッドは小さくなります。

さらに、マスターにはワーカー スレッドもあります。他の MySQL 接続と同様に、スレーブがマスターで接続を開くと、マスターもスレッドを開始します。

MySQL 5.6 より前のバージョンのレプリケーション プロセスには、非常に重要な制限があります。レプリケーションはスレーブ上でシリアル化されるため、マスター上の並列更新操作をスレーブ上で並列に実行することはできません。 MySQL 5.6 バージョンのパラメータ slave-parallel-workers=1 は、マルチスレッド機能を有効にすることを意味します。

MySQL 5.6 からは、データベースのマスター/スレーブ一貫性、障害回復、およびフォールト トレランスを強化するために、グローバル トランザクション ID (GTID) が追加されました。

公式ドキュメント: http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html

MySQL デュアルマスター (マスターマスター) アーキテクチャの考え方は次のとおりです。

1. 両方の MySQL サーバーは読み取りと書き込みが可能で、相互にマスターとバックアップです。デフォルトでは、1 つのサーバー (masterA) のみがデータの書き込みに使用され、もう 1 つのサーバー (masterB) はバックアップとして使用されます。
2. masterA は masterB のマスター データベースであり、masterB は masterA のマスター データベースです。これらは互いにマスターとスレーブです。
3. 2 つのマスター データベース間の高可用性を実現するには、keepalived (VIP を使用して外部サービスを提供する) などのソリューションを使用できます。
4. サービスを提供するすべてのスレーブ サーバーは、マスター B とマスター スレーブ同期を実行します (デュアル マスターと複数のスレーブ)。
5. 高可用性戦略を採用する場合、ダウンタイムによる回復後にマスターAもマスターBもVIPをプリエンプトしないことが推奨されます(非プリエンプティブモード)。
そうすることで、マスター データベースの高可用性をある程度確保できます。マスター データベースがダウンした場合、非常に短時間で別のマスター データベースに切り替えることができるため (マスター データベースのダウンタイムによる業務への影響を可能な限り最小限に抑える)、オンライン マスター データベースに対するマスター スレーブ同期の負荷が軽減されます。

しかし、いくつかの欠点もあります。

1. masterB は常にアイドル状態になる場合があります (一部のクエリを担当するスレーブとして使用できます)。
2. マスター データベースの背後でサービスを提供するスレーブ データベースは、マスター B がデータを同期するまで待機してから、マスター B とデータを同期する必要があります。これにより、ある程度の同期遅延が発生する可能性があります。
アーキテクチャの簡略化された図は次のとおりです。

マスター-マスター環境 (ここでは 2 つのマスターの構成のみを紹介します):

1. CentOS 6.8 64 ビット 2 台のマシン: masterA (192.168.10.11)、masterB (192.168.10.12)

2. 公式MySQL 5.6バージョン

構築プロセス:

1. MySQL サービスをインストールする (ソースコードのインストールを推奨)

1.1 yum インストール依存パッケージ

yum -y インストール make gcc gcc-c++ ncurses-devel bison openssl-devel

1.2 MySQLに必要なユーザーとグループを追加する

グループ追加 -g 27 mysql
adduser -u 27 -g mysql -s /sbin/nologin mysql

1.3 MySQLソースコードパッケージをダウンロードする

mkdir -p /data/packages/src
cd /データ/パッケージ/
http://distfiles.macports.org/cmake/cmake-3.2.3.tar.gz をダウンロードしてください
http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.34.tar.gz をダウンロードしてください

1.4 MySQLデータディレクトリを作成する

mkdir -p /usr/local/mysql/data

1.5 解凍、コンパイル、cmakeとMySQLのインストール

cd /data/packages/src
tar -zxvf ../cmake-3.2.3.tar.gz
cd cmake-3.2.3/
./ブートストラップ
グメイク
インストールする
CD ../
tar xf mysql-5.6.34.tar.gz
mysql-5.6.34 をインストールします
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc \
-DWITH_SSL=バンドル -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MYISAM_STORAGE_ENGINE=1 \
-DMYSQL_TCP_PORT=3306 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DMYSQL_DATADIR=/usr/local/mysql/データ
作成 && インストール

1.6 起動スクリプトを追加する

cp サポートファイル/mysql.server /etc/rc.d/init.d/mysqld

1.7 マスターA設定ファイル /etc/my.cnf を追加する

[クライアント]
ポート = 3306
ソケット = /tmp/mysql.sock

[mysqld]
ベースディレクトリ = /usr/local/mysql
ポート = 3306
ソケット = /tmp/mysql.sock
データディレクトリ = /usr/local/mysql/data
pid ファイル = /usr/local/mysql/data/mysql.pid
ログエラー = /usr/local/mysql/data/mysql.err

サーバーID = 1
自動増分オフセット = 1
auto_increment_increment = 2 #奇数ID

log-bin = mysql-bin #バイナリ機能をオンにします。MASTERサーバーはこのオプションをオンにする必要があります binlog-format=ROW
binlog-row-p_w_picpath=最小
ログスレーブ更新=true
gtidモード=オン
強制GTID一貫性=true
マスター情報リポジトリ=テーブル
リレーログ情報リポジトリ=テーブル
同期マスター情報=1
スレーブ並列ワーカー = 0
同期バイナリログ=0
binlog チェックサム = CRC32
マスター検証チェックサム=1
スレーブSQL検証チェックサム=1
binlog行クエリログイベント=1
#expire_logs_days=5
max_binlog_size=1024M #単一のbinlogファイルの最大値 replicate-ignore-db = mysql #マスターとスレーブ間で同期されていないデータベースを無視 replicate-ignore-db = information_schema
レプリケート-無視-db = パフォーマンススキーマ
複製無視DB = テスト
複製無視DB = zabbix

最大接続数 = 3000
最大接続エラー数 = 30

skip-character-set-client-handshake #アプリケーションが設定する他の文字セットを無視する init-connect='SET NAMES utf8' #接続時に実行されるSQL
character-set-server=utf8 #サーバーのデフォルト文字セット wait_timeout=1800 #リクエストの最大接続時間 interactive_timeout=1800 #前のパラメータと同時に変更した場合にのみ有効になります sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #SQL モード max_allowed_pa​​cket = 10M
バルク挿入バッファサイズ = 8M
クエリキャッシュタイプ = 1
クエリキャッシュサイズ = 128M
クエリキャッシュ制限 = 4M
キーバッファサイズ = 256M
読み取りバッファサイズ = 16K

名前解決をスキップ
遅いクエリログ=1
長いクエリ時間 = 6
slow_query_log_file=スロークエリ.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M

[mysql]
自動再ハッシュなし

[マイサムチク]
キーバッファサイズ = 20M
ソートバッファサイズ = 20M
読み取りバッファ = 2M
書き込みバッファ = 2M

[mysqlホットコピー]
対話タイムアウト

[mysqlダンプ]
素早い
最大許容パケット = 16M

[mysqld_safe]

1.8 特殊パラメータの説明

log-slave-updates = true #レプリケーション イベントを binlog に書き込みます。サーバーはマスターとスレーブの両方になることができます。このオプションを有効にする必要があります。#マスター自己増分 ID
自動増分オフセット = 1
auto_increment_increment = 2 #奇数ID
#masterBはIDを自ら増加させる
自動増分オフセット = 2
auto_increment_increment = 2 #偶数ID

1.9 マスターB設定ファイル /etc/my.cnf を追加する

[クライアント]
ポート = 3306
ソケット = /tmp/mysql.sock

[mysqld]
ベースディレクトリ = /usr/local/mysql
ポート = 3306
ソケット = /tmp/mysql.sock
データディレクトリ = /usr/local/mysql/data
pid ファイル = /usr/local/mysql/data/mysql.pid
ログエラー = /usr/local/mysql/data/mysql.err

サーバーID = 2
自動増分オフセット = 2
auto_increment_increment = 2 #偶数ID

log-bin = mysql-bin #バイナリ機能をオンにします。MASTERサーバーはこのオプションをオンにする必要があります binlog-format=ROW
binlog-row-p_w_picpath=最小
ログスレーブ更新=true
gtidモード=オン
強制GTID一貫性=true
マスター情報リポジトリ=テーブル
リレーログ情報リポジトリ=テーブル
同期マスター情報=1
スレーブ並列ワーカー = 0
同期バイナリログ=0
binlog チェックサム = CRC32
マスター検証チェックサム=1
スレーブSQL検証チェックサム=1
binlog行クエリログイベント=1
#expire_logs_days=5
max_binlog_size=1024M #単一のbinlogファイルの最大値 replicate-ignore-db = mysql #マスターとスレーブ間で同期されていないデータベースを無視 replicate-ignore-db = information_schema
レプリケート-無視-db = パフォーマンススキーマ
複製無視DB = テスト
複製無視DB = zabbix

最大接続数 = 3000
最大接続エラー数 = 30

skip-character-set-client-handshake #アプリケーションが設定する他の文字セットを無視する init-connect='SET NAMES utf8' #接続時に実行されるSQL
character-set-server=utf8 #サーバーのデフォルト文字セット wait_timeout=1800 #リクエストの最大接続時間 interactive_timeout=1800 #前のパラメータと同時に変更した場合にのみ有効になります sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #SQL モード max_allowed_pa​​cket = 10M
バルク挿入バッファサイズ = 8M
クエリキャッシュタイプ = 1
クエリキャッシュサイズ = 128M
クエリキャッシュ制限 = 4M
キーバッファサイズ = 256M
読み取りバッファサイズ = 16K

名前解決をスキップ
遅いクエリログ=1
長いクエリ時間 = 6
slow_query_log_file=スロークエリ.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M

[mysql]
自動再ハッシュなし

[マイサムチク]
キーバッファサイズ = 20M
ソートバッファサイズ = 20M
読み取りバッファ = 2M
書き込みバッファ = 2M

[mysqlホットコピー]
対話タイムアウト

[mysqlダンプ]
素早い
最大許容パケット = 16M

[mysqld_safe]

1.10 MySQLを初期化する

cd /usr/local/mysql
スクリプト/mysql_install_db --user=mysql

1.11 起動スクリプトに実行権限を与え、MySQLを起動する

chmod +x /etc/rc.d/init.d/mysqld
/etc/init.d/mysqld を起動します

2. マスタースレーブ同期を構成する

2.1 マスタースレーブ同期アカウントの追加
マスターAの場合:

mysql> '123456' で識別される 'repl'@'192.168.10.12' に *.* 上のレプリケーション スレーブを許可します。
mysql> 権限をフラッシュします。

マスターBの場合:

mysql> '123456' で識別される 'repl'@'192.168.10.11' に *.* 上のレプリケーション スレーブを許可します。
mysql> 権限をフラッシュします。

2.2 メインデータベースの状態を確認する
マスターAの場合:

mysql> マスターステータスを表示します。

+------------------+----------+--------------+------------------+------------------+

| ファイル | 位置 | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+------------------+

| mysql-bin.000003 | 120 | | | |

+------------------+----------+--------------+------------------+------------------+

セット内の 1 行 (0.00 秒)

マスターBについて

mysql> マスターステータスを表示します。

+------------------+----------+--------------+------------------+------------------+

| ファイル | 位置 | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+------------------+

| mysql-bin.000003 | 437 | | | |

+------------------+----------+--------------+------------------+------------------+

セット内の 1 行 (0.00 秒)

2.3 構成同期情報:

マスターAの場合:

mysql> マスターを master_host='192.168.10.12'、master_port=3306、master_user='repl'、master_password='123456'、master_log_file='mysql-bin.000003'、master_log_pos=437 に変更します。

mysql> スレーブを起動します。

mysql> スレーブステータスを表示します\G;

以下のステータスが表示されれば正常です。

スレーブIO実行中: はい

スレーブSQL実行中: はい

マスターBの場合:

#私はテスト環境にいるので、データが書き込まれないことを保証できます。それ以外の場合、必要な手順は次のとおりです。まず、masterA がテーブルをロックします --> masterA がデータをバックアップします --> masterA がテーブルのロックを解除します --> masterB がデータをインポートします --> masterB がマスタースレーブを設定します --> マスタースレーブ mysql を表示します > マスターを次のように変更します master_host='192.168.10.11'、master_port=3306、master_user='repl'、master_password='123456'、master_log_file='mysql-bin.000003'、master_log_pos=120;

スレーブを起動します。

mysql> スレーブステータスを表示します\G;

以下のステータスが表示されれば正常です。

スレーブIO実行中: はい

スレーブSQL実行中: はい

3. マスタースレーブ同期をテストする

3.1 同期効果をテストするためにmasterAにデータベースを作成する

mysql> データベースを表示します。

+--------------------+

| データベース |

+--------------------+

| 情報スキーマ |

|mysql |

| パフォーマンススキーマ |

| テスト |

+--------------------+

セット内の 4 行 (0.00 秒)

mysql> データベース test01 を作成します。

クエリは正常、1 行が影響を受けました (0.00 秒)

mysql> データベースを表示します。

+--------------------+

| データベース |

+--------------------+

| 情報スキーマ |

|mysql |

| パフォーマンススキーマ |

| テスト |

|テスト01|

+--------------------+

セット内の行数は 5 です (0.00 秒)

mysql>終了

さよなら

[root@masterA データ]#

3.2 masterBに移動して、データベースが同期的に作成されたかどうかを確認します。

mysql> データベースを表示します。

+--------------------+

| データベース |

+--------------------+

| 情報スキーマ |

|mysql |

| パフォーマンススキーマ |

| テスト |

|テスト01|

+--------------------+

セット内の行数は 5 です (0.00 秒)

mysql>終了

さよなら

[root@masterBデータ]#

4. MySQL 5.6のGTID機能を有効にする

MasterA と masterB はそれぞれ次のコマンドを実行します。

mysql> スレーブを停止します。

クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql> マスターを MASTER_AUTO_POSITION=1 に変更します。

クエリは正常、影響を受けた行は 0 行 (0.01 秒)

mysql> スレーブを起動します。

クエリは正常、影響を受けた行は 0 行 (0.00 秒)

5. 遭遇した問題

私が長い間報告してきたマスタースレーブエラー:

最終IOエラー番号: 1236

Last_IO_Error: バイナリ ログからデータを読み取っているときにマスターから致命的なエラー 1236 が発生しました: 'ログ ファイルを開けませんでした'

その後、マスター/スレーブ同期関連のパラメータが変更され、その理由は my.cnf に次のパラメータが追加されたためであることが確認されました。

ログ bin = mysql bin

リレーログ = mysql-bin

通常のマスター間同期中のバイナリ ログ ファイルには、2 セットのバイナリ ログがあることが示されます。したがって、上記の 2 つのパラメータにより、2 セットのバイナリ ファイルを生成することができなくなり、バイナリ ファイルの混乱と損失につながると考えられます。

これで、MySQL デュアルマスター (マスターマスター) アーキテクチャ構成ソリューションに関するこの記事は終了です。MySQL デュアルマスターに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLの論理アーキテクチャに関する深い理解
  • MySQL の全体的なアーキテクチャの紹介
  • MySQL 20 の高性能アーキテクチャ設計原則 (収集する価値あり)
  • MySQL 4 の一般的なマスタースレーブレプリケーションアーキテクチャ
  • MySQL 学習のまとめ: InnoDB ストレージ エンジンのアーキテクチャ設計の予備的な理解
  • MySQL アーキテクチャのナレッジポイントの概要
  • Mysql論理アーキテクチャの詳細な説明
  • MySQL データベース アーキテクチャの詳細

<<:  Docker を使用した ElasticSearch:7.8.0 クラスターのインストールに関する詳細なチュートリアル

>>:  TypeScript を使用して Vue3 で axios をカプセル化する詳細な例

推薦する

VUEはタイムライン再生コンポーネントを実装します

この記事の例では、タイムライン再生コンポーネントを実装するためのVUEの具体的なコードを参考までに共...

docker-compose ネットワーク設定についての簡単な説明

ネットワーク使用チュートリアル公式サイト docker-compose.yml リファレンスドキュメ...

MySQLデータの挿入、更新、削除の詳細

目次1. 挿入2. 更新3. 削除1. 挿入 顧客に挿入( 顧客.顧客住所、 顧客.cust_cit...

MySQL で二重引用符の位置が誤っていたために起きた殺人事件の詳細な分析

1. はじめに最近、開発者が誤ってデータを削除したり更新したりするケースがよくあります。今回もまた問...

jsを使ってシンプルなディスククロックを実現する

この記事では、参考までに、シンプルなディスククロックを実装するためのjsの具体的なコードを紹介します...

MySQLの明示的な型変換の簡単な分析

CAST関数前回の記事では、型変換を表示するために使用する CAST 関数について説明しました。暗黙...

MySQL がテーブルを読み取れないエラー (MySQL 1018 エラー) の解決方法

1. エラーの再現MySQL データベースにはアクセスできますが、データベース テーブルを読み取るこ...

Vue + 要素を使用して背景データをオプションに動的に表示する

必要:ハードコードされたデータの代わりに、セレクター内のオプション値の動的な表示を実装します。私のロ...

MySQLはカスタム関数を使用して親IDまたは子IDを再帰的に照会します

背景: MySQL では、レベルに制限がある場合、たとえば、ツリーの最大深度を事前に決定できる場合、...

Linux rpm および yum コマンドとその使用法の詳細な説明

RPM パッケージ管理インターネット ダウンロード パッケージのパッケージ化およびインストール ツー...

Webデザイナーの成長体験

<br />まず最初に、私はこのグループの中では完全な新人だということを述べなければなり...

フレームセットを使用して複雑なページレイアウトを実装するためのテクニックの概要

コードをコピーコードは次のとおりです。 <html> <!--混合フレームレイアウ...

Dockerコンテナ間のホスト間通信 - オーバーレイベースの実装方法

オーバーレイネットワーク分析組み込みのホスト間ネットワーク通信は、常に Docker の待望の機能で...

Node.js はクライアントリクエストデータ内の中国語文字化けの問題を解決します

Node.js はクライアントリクエストデータ内の中国語文字化けの問題を解決しますコード例: var...

Vueタイマーの詳細な使い方

この記事では、参考までにタイマーを実装するためのVueの具体的なコードを紹介します。具体的な内容は次...