MySQL GTID マスターとスレーブの不一致を修復するソリューション

MySQL GTID マスターとスレーブの不一致を修復するソリューション

解決策1: レプリカを再構築する

MySQL 5.6 以降では、レプリケーションで新しいグローバル トランザクション ID (GTID) のサポートが導入されています。 GTID モードを有効にして MySQL および MySQL 5.7 のバックアップを実行すると、Percona XtraBackup は GTID 値を xtrabackup_binlog_info に自動的に保存します。 この情報を使用して、新しい GTID ベースのレプリカを作成 (または破損したレプリカを修復) できます。

前提条件

Percona xtrabackupをMySQLマシンにインストールする必要があります

アドバンテージ

比較的安全で操作が簡単

欠点

  • データ量が多い場合、バックアップ時間は長くなります。
  • データベースが読み取りと書き込みを分離している場合、スレーブによって行われた読み取り要求はマスターに転送される必要がある。

手順

マスター

現在のデータベースをバックアップするには、マスター上の xtrabackup ツールを使用してください。このコマンドを実行するユーザーには、MySQL データ ディレクトリを読み取る権限が必要です。

innobackupex --default-file=/etc/my.cnf --user=root -H 127.0.0.1 --password=[パスワード] /tmp

バックアップファイルをスレーブマシンにコピーする

奴隷

スレーブマシンでこのコマンドを実行してバックアップファイルを準備します

innobackupex --default-file=/etc/my.cnf --user=root -H 127.0.0.1 --password=[パスワード] --apply-log /tmp/[タイムスタンプ]

スレーブデータディレクトリをバックアップして削除する

systemctl を停止します。
mv /data/mysql{,.bak}

バックアップをターゲットディレクトリにコピーし、対応する権限を付与してからスレーブを再起動します。

innobackupex --default-file=/etc/my.cnf --user=root -H 127.0.0.1 --password=[パスワード] --copy-back /tmp/[タイムスタンプ]
chmod 750 /データ/mysql
chown mysql.mysql -R /data/mysql
systemctl で mysqld を起動します。

次の例に示すように、実行された現在のバックアップの最後のGTIDを表示します。

$ cat /tmp/[タイムスタンプ]/xtrabackup_binlog_info
mysql-bin.000002 1232 c777888a-b6df-11e2-a604-080027635ef5:1-4

この GTID は、innobackupex バックアップが完了した後にも印刷されます。

innobackupex: MySQL バイナリログの位置: ファイル名 'mysql-bin.000002'、位置 1232、最終変更の GTID 'c777888a-b6df-11e2-a604-080027635ef5:1-4'

MySQLにrootとしてログインし、次のように設定します。

NewSlave > マスターをリセットします。
NewSlave > グローバル gtid_purged='c777888a-b6df-11e2-a604-080027635ef5:1-4' を設定します。
NewSlave > マスターを変更
       MASTER_HOST="$masterip",
       MASTER_USER="repl",
       MASTER_PASSWORD="$slavepass",
       マスター自動位置 = 1;
NewSlave > スレーブを開始;

スレーブのレプリケーションステータスが正常かどうかを確認します

NewSlave > スレーブステータスを表示\G
     [..]
     スレーブIO実行中: はい
     スレーブSQL実行中: はい
     [...]
     取得済み_Gtid_Set: c777888a-b6df-11e2-a604-080027635ef5:5
     実行されたGtidセット: c777888a-b6df-11e2-a604-080027635ef5:1-5

レプリカが 5 番の新しいトランザクションを取得したことがわかります。つまり、1 から 5 までのトランザクションはすでにこのレプリカ上に存在します。こうして、新たなレプリカの構築が完了しました。

解決策2: データ修復にpercona-toolkitを使用する

PT ツールキットには、pt-table-checksum と pt-table-sync という 2 つのツールが含まれており、主にマスターとスレーブの整合性を検出し、データの不整合を修復するために使用されます。

前提条件

percona-toolkitツールをMySQLマシンにインストールする必要があります

アドバンテージ

修復速度が速く、スレーブライブラリを停止する必要がない

欠点

操作は複雑です。操作の前にデータベースをバックアップしてください。修復するテーブルには一意制約が必要です。

手順

背景例

IP関係マッピング

| IP | 役割 |
| ---- | ---- |
| 192.168.100.132 | マスター |
| 192.168.100.131 | スレーブ |

復元するテーブル構造が次の通りであると仮定します。

mysql> show テーブル test.t を作成します。
+-------+-------------------------------------
| テーブル | テーブルの作成 |
+-------+-------------------------------------
| t | テーブル `t` を作成する (
 `id` int(11) NULLではない、
 `content` varchar(20) デフォルト NULL,
 主キー (`id`)
) エンジン=InnoDB デフォルト文字セット=latin1 |
+-------+-------------------------------------

通常のマスタースレーブ整合性の場合、マスターとスレーブのデータは次のようになります。

mysql> test.t から * を選択します。
+----+---------+
| ID | コンテンツ |
+----+---------+
| 1 | へ |
| 2 | バ |
+----+---------+
セット内の 2 行 (0.00 秒)

極端な場合、次のようなマスターとスレーブの不整合が発生すると、状況は次のようになります。

  1. 以下に示すように、マスターは ID 3 のレコードを追加しますが、スレーブに同期されず、自動的にスレーブにフェイルオーバーされます。
  2. 古いスレーブが一定期間新しいマスターとして機能した後、新しいレコードがテーブルに追加されます。

古いマスターを再起動した後、古いマスターのデータは次のようになります。

old_master> test.t から * を選択します。
+----+---------+
| ID | コンテンツ |
+----+---------+
| 1 | へ |
| 2 | バ |
| 3 | く |
+----+---------+
セット内の 3 行 (0.00 秒)

New Masterのデータは以下のとおりです。

new_master> test.t から * を選択します。
+----+---------+
| ID | コンテンツ |
+----+---------+
| 1 | へ |
| 2 | バ |
| 3 | cc |
| 4 | dd |
+----+---------+
セット内の 4 行 (0.00 秒)

このとき、古いマスターが新しいマスターのスレーブとして設定されている場合は、次のようなエラーが報告されます。

...Last_IO_Error: バイナリ ログ: 'マスターの SERVER_UUID を使用すると、スレーブにはマスターよりも多くの GTID があります。

オールドマスターのGTIDが255に達したことがわかります。

実行されたGtidセット: 5b750c75-86c2-11eb-af71-000c2973a2d5:1-10、
60d082ee-86c2-11eb-a9df-000c2988edab:1-255

新マスターのGTIDは254のみ

mysql> マスターステータスを表示\G
************************** 1. 行 ****************************
       ファイル:mysql-bin.000001
     位置: 4062
   バイナリログ_Do_DB:
 バイナリログを無視:
実行されたGtidセット: 5b750c75-86c2-11eb-af71-000c2973a2d5:1-2、
60d082ee-86c2-11eb-a9df-000c2988edab:1-254
セット内の 1 行 (0.00 秒)

この時点で、古いマスターがエラーをスキップし、新しいマスターから正常にレプリケートできる状態に古いマスターを復元するように構成します。

old_master> スレーブを停止します。
クエリは正常、影響を受けた行は 0 行、警告は 1 件 (0.00 秒)

old_master> set gtid_next='60d082ee-86c2-11eb-a9df-000c2988edab:254'; --スキップする次のトランザクションのバージョン、GTIDを指定します
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

old_master> 開始します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

old_master> commit; -- 空のトランザクションを挿入する
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

old_master> set gtid_next='AUTOMATIC'; -- 自動GTIDに復元
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

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

すると、古いマスター上でレプリケーションが正常に進行していることがわかります。

mysql>スレーブステータスを表示\G
      ...
       スレーブIO実行中: はい
      スレーブSQL実行中: はい
      ...
      実行されたGtidセット: 5b750c75-86c2-11eb-af71-000c2973a2d5:1-10、
60d082ee-86c2-11eb-a9df-000c2988edab:1-255
        自動位置: 1
     Replicate_Rewrite_DB:
         チャンネル名:
      マスター TLS バージョン:

最後に、新しいマスターのslave_master_infoをクリアします。

new_master> チャネル '' のすべてのスレーブをリセットします。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

new_master> スレーブステータスを表示します\G;
空セット (0.01 秒)

一貫性を検証する

次に、マスターとスレーブの一貫性を検証する必要があります。新しいマスターでpt-table-checksumを実行します。ROWSは4で、DIFFSがあります。

[root@localhost ~]# pt-table-checksum h='127.0.0.1',u='mha',p='[パスワード]',P=3306 --no-check-binlog-format --databases test
すべてのテーブルをチェックサムできるかどうかを確認しています...
チェックサムを開始しています...
      TS エラー 差分行 DIFF_ROWS チャンク スキップされた時間表
03-29T19:24:18 0 1 4 1 1 0 0.322 テスト.t

双方向同期(同期操作によりデータが変更され、操作前にデータのバックアップが実行されます)

同期プロセス中、pt-table-sync はマスター上のデータを変更します。pt-table-sync のパラメータは次のとおりです。

pt-table-sync --databases テスト --bidirectional --conflict-column='*' --conflict-comparison 'newest' h='192.168.100.132',u='mha',p='[パスワード]',P=3306 h='192.168.100.131' --print
--database は実行するデータベースを指定します --bidirectional は双方向同期です --conflict-column は競合が発生したときに列を比較します --conflict-comparison 競合比較戦略です --print は比較結果を出力します --dry-run テストを実行します --execute テストを実行します # 左側の DSN はスレーブです
# 右側のDSNはマスターです

ここでは、比較列として —conflict-name='content' を指定し、この列としては通常、ビジネス主キーが使用されます。実行される文が印刷されているのがわかります

[root@localhost ~]# pt-table-sync --databases test --bidirectional --conflict-column='content' --conflict-comparison 'newest' h='192.168.100.132',u='mha',p='[パスワード]',P=3306 h='192.168.100.131' --print
/*192.168.100.132:3306*/ `test`.`t` を更新し、`content`='cc' を設定し、`id`='3' を制限 1 に設定します。
/*192.168.100.132:3306*/ `test`.`t`(`id`, `content`) に VALUES ('4', 'dd') を挿入します。

次に、ステートメントを実行します

[root@localhost ~]# pt-table-sync --databases test --bidirectional --conflict-column='content' --conflict-comparison 'newest' h='192.168.100.132',u='mha',p='[パスワード]',P=3306 h='192.168.100.131' --execute

次にマスターで再度データ比較を実行すると、データが正常であることがわかります。

[root@localhost ~]# pt-table-checksum h='127.0.0.1',u='mha',p='[パスワード]',P=3306 --no-check-binlog-format --databases test
すべてのテーブルをチェックサムできるかどうかを確認しています...
チェックサムを開始しています...
      TS エラー 差分行 DIFF_ROWS チャンク スキップされた時間表
03-30T12:09:57 0 0 4 0 1 0 0.330 テスト.t

上記は、MySQL GTID マスタースレーブ不整合の修復ソリューションの詳細な内容です。MySQL GTID マスタースレーブ不整合修復の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL はどのようにしてマスターとスレーブの一貫性を確保するのでしょうか?

<<:  iframe に関するいくつかの発見と考察

>>:  JavaScript の構成と継承の説明

ブログ    

推薦する

HTMLテキスト内のすべてのタグを置き換える方法

(?i) は大文字と小文字を区別しないことを意味します。大文字と小文字をすべて置き換えます。 htm...

DockerコンテナでJupyterノートブックを設定する方法

Jupyter ノートブックは、主に Python コードの記述、より具体的にはディープラーニング開...

MySQL 重複インデックスと冗長インデックスの例の分析

この記事では、例を使用して MySQL の重複インデックスと冗長インデックスについて説明します。ご参...

JQuery データグリッドクエリの詳細な説明

目次ツリー項目にコードを追加します。 1. 右側に関連情報ページを保存します(userManage....

Docker プライベート サーバー イメージを定期的にクリーンアップする方法

CI を利用してリリース用の Docker イメージをビルドすることで、全員のバージョンリリース効率...

Vueは完全な選択機能を実装しています

この記事の例では、完全な選択機能を実装するためのVueの具体的なコードを参考までに共有しています。具...

CentOS での samba フォルダ共有サーバー構成の詳細な説明

1. はじめに最近、CentOS での開発には多くの不便があることがわかりました。Windows/M...

JSON.stringify を使用する際に発生する循環参照の問題を解決する方法の詳細な説明

プログラマーが日常的に TypeScript/JavaScript 開発を行う場合、複雑な Java...

HTMLテーブルレイアウトの実践的な使い方の詳しい説明

テーブルはいつ使用されますか?最近では、Web ページの全体的なレイアウトにテーブルが使用されること...

Linux コマンドで .sql ファイルをエクスポートおよびインポートする方法

この記事では、Linux コマンドを使用して .sql ファイルをエクスポートおよびインポートする方...

Linux 上での MySQL データベースのインストールと Java プロジェクトの構成に関する詳細なグラフィック説明

1. MySQLデータベースをインストールする① ダウンロードして解凍し、/opt/softディレク...

Dockerコンテナを使用してホストネットワークにアクセスする方法

最近、nginx をリバース プロキシとして使用し、docker で nginx を実行するシステム...

MySQL ログイン エラーを解決する: 'ユーザー 'root'@'localhost' へのアクセスが拒否されました

まず、コマンドラインまたはワークベンチを使用して MySQL にログインできず、「ユーザー '...

Vue 実践における実用的な小さな魔法のまとめ

初回の読み込みを高速化できるルートの遅延読み込みをどうして忘れられるでしょうか?ルーティングの遅延読...

MySQL データベースのバックアップ プロセスに関する注意事項

今日は、データ バックアップに関連するいくつかの点について調べ、MySQL データ バックアップに関...