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

推薦する

Docker コンテナ データ ボリュームの名前付きマウントと匿名マウントの問題

目次コンテナデータボリュームとはコンテナ データ ボリュームが必要なのはなぜですか?使用データボリュ...

ウィンドウの中央にブロック要素の位置を設定する方法

ウィンドウの中央にブロック要素の位置を設定する方法ブロック要素をウィンドウの中央に配置する上記の方法...

HTML テーブルタグチュートリアル (17): テーブルタイトルの垂直配置属性 VALIGN

表のキャプションは表の上または下に配置でき、プロパティで調整できます。デフォルトのテーブル タイトル...

vue-cli でレスポンシブ レイアウトを実装する方法

フロントエンド開発を行うと、PCとモバイル端末の適応に必然的に直面することになります。このような問題...

Docker ケース分析: MySQL データベース サービスの構築

目次1 設定ディレクトリとデータディレクトリを作成する3 イメージからホストに構成ファイルをコピーす...

MySQLデッドロック問題の詳細な分析

序文私たちのビジネスがまだ初期段階にあり、同時実行の度合いが比較的低い場合、数年間はデッドロックの問...

Linux で複数のファイルの名前を一括で変更する方法

Linux では、通常、ファイルの名前を変更するために mv コマンドを使用します。これは、単一のフ...

JS でオブジェクト プロパティを簡単にトラバースするいくつかの方法

目次1. 自己列挙可能なプロパティ2. Object.values()はプロパティ値を返します3. ...

Linux で nohup ログ出力が大きすぎる問題の解決方法の詳細な説明

最近、hadoop テスト クラスターで spark ストリーミング プログラムを実行し、その後、n...

MySQL の基本: グループ化関数、集計関数、グループ化クエリの詳細な説明

目次1. 使い方が簡単2. DISTINCTを使用して重複を削除する3. COUNT()の詳細な紹介...

WeChat ミニプログラム 宝くじ番号ジェネレーター

この記事では、WeChatアプレットの宝くじ番号ジェネレータの具体的なコードを参考までに紹介します。...

uniappを使用してWeChatミニプログラムでEChartsを使用する方法

今日は、uniapp を使用して Echarts を統合し、マップ チャートを表示します。 mpvu...

mysql5.6.zip形式の圧縮版インストールグラフィックチュートリアル

はじめに: MySQL は、スウェーデンの MySQL AB によって開発されたリレーショナル デー...

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

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

MySQL実践ウィンドウ関数SQL分析クラスの生徒のテストの成績と生活費

目次1. 背景2. テーブル作成ステートメントとデータ挿入テーブルを作成するデータの挿入3. ウィン...