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 の構成と継承の説明

推薦する

Excel エクスポートは docker 環境では常に失敗する

Excel のエクスポートは、docker 環境では常に失敗します。最も直接的な原因は、中国語フォン...

Vue で pdfjs を使用して PDF ファイルをプレビューする方法

目次序文考えるライブラリディレクトリの解析とダウンロード使い方ファイルの場所実際の通話質問要約する序...

抽選効果を実現するJavaScript

この記事では、宝くじマシンの効果を実現するためのJavaScriptの具体的なコードを参考までに共有...

Ubuntu 18.04 に VMware Tools をインストールする際のエラーを解決する

1. オンライン チュートリアルによると、Ubuntu 18.04 のインストールはまだ失敗します。...

CSSに基づいてマウス入力の方向を決定する

以前、フロントエンド技術グループに所属していたとき、グループのメンバーが面接中に問題に遭遇したと言っ...

動的な色切り替えの実装コードをサポートするために、CSS で SVG 画像を参照します。

表示する svg 画像を追加すると、React はファイルが見つからないというメッセージを表示します...

JavaScript における一般的な配列操作

目次1. 連結() 2. 結合() 3. プッシュ() 5. シフト() 6. シフト解除() 7....

HTML の入力の readonly 属性と disabled 属性の違いについて簡単に説明します。

「読み取り専用」と「無効」はどちらも、ユーザーがフォーム フィールドの内容を変更できないようにしま...

システム CD をマウントして yum ウェアハウスを構築する VMware 15.5 バージョンのグラフィック チュートリアル

1. CentOS 7 仮想マシンを開きます。 2. 仮想マシンにログインし、リストにないユーザー名...

Navicat 接続 MySQL エラーの説明分析

目次環境仮想マシンバージョンMySQL バージョン事前準備MySQLの実行ステータスを確認するルート...

Reactのヒントはフックの依存関係の問題を解消する方法を教えます

reactプロジェクトで非常に一般的なシナリオ: const [watchValue、setWatc...

Linux で PHP curl 拡張機能をインストールする方法の詳細な説明

この記事では、Linux で PHP curl 拡張機能をインストールする方法について説明します。ご...

MySQL のメモリ使用量と CPU 使用率が高い場合のテストと解決策

変更後: innodb_buffer_pool_size=576M ->256M InnoDB...

1時間で学ぶMySQLの基礎

目次MySQL を使い始めるMySQL 管理6. MySQL サーバーを起動および停止します。 7....

CentOS6.9+Mysql5.7.18 ソースコードのインストール詳細チュートリアル

CentOS6.9+Mysql5.7.18 ソースコードのインストールでは、以下の操作を root ...