MySQL レプリケーション問題の 3 つのパラメータの分析

MySQL レプリケーション問題の 3 つのパラメータの分析

今日は火曜日です。朝遅く起きて仕事に遅れました。本当に... 。 。早速ですが、昨日の記事では次の 3 つのパラメータについて説明しました。

  • slave_exec_mode パラメータ;
  • sql_slave_skip_counter=N パラメータ;
  • slave-skip-errors=N パラメータ。

これら 3 つのパラメータは、重複キー 1062 エラーなど、並列レプリケーションで指定されたいくつかのエラーを解決できます。今日は、これら 3 つのパラメータの違いを簡単にテストします。

01 sql_slave_skip_counter パラメータ

このパラメータは、主に特定のエラーのある「イベント」をスキップするために使用されます。ここで使用されている単語はトランザクションではなくイベントであることに注意してください。これは、その本質がイベントを 1 つずつスキップすることであるためです。このパラメータは、オフセット レプリケーション モードで使用する必要があることに注意してください。gtid レプリケーション モードを使用している場合、このパラメータは使用できません。例を見てみましょう。まず、レプリケーション関係を構築します。

マスター 10.30.124.68

スレーブ 10.30.124.128

これら 2 つのインスタンスは、相互にマスターとスレーブです。テスト テーブル test.yeyz を作成し、次のように、id が主キーで一意であるデータを挿入します。

マスター

mysql:(なし) 22:25:56>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
+----+------+
セット内の 4 行 (0.00 秒)

奴隷について

mysql:(なし) 22:25:38>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
セット内の行数は 5 です (0.00 秒)

スレーブ ノードにはマスター ノードよりも 1 つ多くのレコードがあり、id=5 の追加レコードがあることがわかります。次に、マスター ノードにデータを挿入します。

mysql:(なし) 22:26:06>>test.yeyzに値(5,5)、(6,6)を挿入します。
クエリは正常、2 行が影響を受けました (0.00 秒)
記録: 2 重複: 0 警告: 0

この時点でスレーブ ノードを観察します。

mysql:(なし) 22:26:34>>スレーブステータスを表示\G
                  マスターホスト: 10.30.124.68
                  マスターユーザー: dba_repl
                  マスターポート: 4306
                接続再試行: 60
              マスターログファイル:mysqlbin.000002
          読み取りマスターログ位置: 523
               リレーログファイル: スレーブリレーbin.000002
                リレーログ位置: 319
        リレーマスターログファイル: mysqlbin.000002
             スレーブIO実行中: はい
            スレーブSQL実行中: いいえ
                   最終エラー番号: 1062
                   Last_Error: エラーが発生したためコーディネーターが停止しました
 労働者において、最新の失敗は次のとおりです。
 ワーカー0はトランザクション「ANONYMOUS」の実行に失敗しました
 マスターログ mysqlbin.000002、end_log_pos 492。
 エラー ログおよび/または performance_schema.replication_applier_status_by_worker を参照してください。
 この障害または他の障害(ある場合)の詳細については、表を参照してください。
                 スキップカウンタ: 0

スレーブ ノードの SQL スレッドが切断されていることがわかります。この時点で、マスター ノードでこのエラーの位置 492 の binlog をクエリすると、次のようになります。

mysql:(なし) 22:30:28>>194 からの 'my​​sqlbin.000002' の binlog イベントを表示します。
  +-----------------+-----+----------------+-----------+-------------+------------------------------------------+
| ログ名 | 位置 | イベント タイプ | サーバー ID | ログ終了位置 | 情報 |
+-----------------+-----+----------------+-----------+-------------+------------------------------------------+
| mysqlbin.000002 | 194 | Anonymous_Gtid | 192 | 259 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| mysqlbin.000002 | 259 | クエリ | 192 | 327 | 開始 |
| mysqlbin.000002 | 327 | Rows_query | 192 | 391 | # test.yeyz に値 (5,5),(6,6) を挿入 |
| mysqlbin.000002 | 391 | テーブルマップ | 192 | 439 | テーブル ID: 108 (test.yeyz) |
| mysqlbin.000002 | 439 | Write_rows | 192 | 492 | table_id: 108 フラグ: STMT_END_F |
| mysqlbin.000002 | 492 | Xid | 192 | 523 | COMMIT /* xid=38 */ |
+-----------------+-----+----------------+-----------+-------------+------------------------------------------+
セット内の 6 行 (0.00 秒)

上記のバイナリログから、挿入操作の 1 つによって実際に 5 つのエントリが生成され、対応する位置が 259 から 492 であることがわかります。イベントについては後で説明します。

id=5 のレコードがマスター ノードに挿入されたため、スレーブ ノードのレコードと競合しています。エラー ログを確認すると、次のことがわかります。

キー「PRIMARY」の重複エントリ「5」
 Error_code: 1062; ハンドラー エラー HA_ERR_FOUND_DUPP_KEY;
 まずイベントのマスターログ、
 終了ログ 492 | 2019-07-16 22:26:25

この問題は、sql_slave_skip_counter パラメータを設定することで解決します。手順は次のとおりです。

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

mysql:(なし) 22:32:45>>グローバルsql_slave_skip_counterを1に設定します;
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql:(なし) 22:33:06>>スレーブを起動します。

昨日の記事で、sql_slave_skip_counter に続く値はイベント数であると言いましたので、ここではイベントをスキップするのと同じです。MySQL では、イベントをスキップしてもトランザクションが継続している場合は、トランザクションはスキップされ続けると規定されています。

このパラメータを使用してイベントをスキップした後、データベース テーブルのデータとレプリケーション ステータスを確認し、次のことを確認します。

スレーブテーブル:

mysql:(なし) 22:33:10>>スレーブステータスを表示\G
************************** 1. 行 ****************************
               Slave_IO_State: マスターがイベントを送信するのを待機中
                  マスターホスト: 10.30.124.68
                  マスターユーザー: dba_repl
                  マスターポート: 4306
                接続再試行: 60
              マスターログファイル:mysqlbin.000002
          読み取りマスターログ位置: 523
               リレーログファイル: スレーブリレーbin.000003
                リレーログ位置: 319
        リレーマスターログファイル: mysqlbin.000002
             スレーブIO実行中: はい
            スレーブSQL実行中: はい


mysql:(なし) 22:33:16>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
セット内の行数は 5 です (0.00 秒)

マスターテーブルを見てみましょう:

mysql:(なし) 22:33:36>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
+----+------+
セット内の 6 行 (0.00 秒)

マスターへのデータ挿入は成功しているが、スレーブへのデータ挿入は失敗していることがわかります。つまり、

このパラメータが誤ってスキップされると、マスターとスレーブのデータが不整合になります。

02 スレーブスキップエラーパラメータ

このパラメータは指定されたエラーをスキップするためのもので、対応するerror_codeを設定する必要があります。以下のログの内容から、error_codeの値が1062であることがわかります。

キー「PRIMARY」の重複エントリ「5」
 Error_code: 1062; ハンドラー エラー HA_ERR_FOUND_DUPP_KEY;
 まずイベントのマスターログ、
 終了ログ 492 | 2019-07-16 22:26:25

このパラメータの値を手動で 1062 に変更する必要があります。このパラメータは読み取り専用パラメータであるため、このパラメータを変更するには MySQL サービスを再起動する必要があることに注意してください。

変更後の状況は以下のとおりです。

[email protected]:(なし) 22:38:55>>'%errors%' のような変数を表示します。
+--------------------+---------+
| 変数名 | 値 |
+--------------------+---------+
| 最大接続エラー数 | 1000000 |
| スレーブスキップエラー | 1062 |
+--------------------+---------+
セットに2行(0.01秒)

この時点でマスター テーブルとスレーブ テーブルのデータが更新され、更新された状況は次のようになります。

マスター:

mysql:(なし) 22:39:15>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 || 2 | 2 |
| 3 | 3 || 4 | 4 |
| 5 | 5 || 6 | 6 |
+----+------+
セット内の 6 行 (0.00 秒)

スレーブについて:

mysql:(なし) 22:40:15>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
+----+------+
セット内の行数は 7 です (0.00 秒)

スレーブ テーブルにはマスター テーブルよりも 1 つ多くのデータ (id=7 のレコード) があることがわかりました。この時点で、マスターで実行します。

mysql:(なし) 22:34:15>>test.yeyzに値(7,7)、(8,8)を挿入します。
クエリは正常、2 行が影響を受けました (0.00 秒)
記録: 2 重複: 0 警告: 0

次のようにして、スレーブ上のレプリケーションとデータのステータスを確認します。

mysql:(なし) 22:39:05>>スレーブステータスを表示\G
************************** 1. 行 ****************************
               Slave_IO_State: マスターがイベントを送信するのを待機中
                  マスターホスト: 10.30.124.68
                  マスターユーザー: dba_repl
                  マスターポート: 4306
                接続再試行: 60
              マスターログファイル:mysqlbin.000002
          読み取りマスターログ位置: 852
               リレーログファイル: スレーブリレーbin.000005
                リレーログ位置: 648
        リレーマスターログファイル: mysqlbin.000002
             スレーブIO実行中: はい
            スレーブSQL実行中: はい
              レプリケート_Do_DB:
           レプリケート_無視_DB:
            テーブルの複製:
        無視テーブルを複製:
       Replicate_Wild_Do_Table:


 mysql:(なし) 22:40:15>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
+----+------+
セット内の行数は 7 です (0.00 秒)

ご覧のとおり、スレーブに id=7 のレコードがすでに存在するにもかかわらず、レプリケーションにエラーはありません。また、スレーブ データベースのデータは以前のデータと一致したままであることも判明しました。つまり、マスター データベースに挿入された id=8 のレコードは同期されていませんでした。

要約すると、このパラメータがレプリケーション エラーをスキップすると、MySQL サービスを再起動する必要があり、マスター データとスレーブ データの間に不整合が発生する可能性があります。

03 スレーブスキップエラー=N パラメータ

最後のパラメータを見てみましょう。このパラメータは、並列レプリケーション中のスレーブ レプリケーション モードを示します。デフォルト値は厳密モードです。上記のように、まずマスター ライブラリとスレーブ ライブラリのデータを見てみましょう。

マスターデータ:

mysql:(なし) 22:39:20>>test.yeyzから*を選択します。
                 +----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
+----+------+
セット内の行数は 8 です (0.00 秒)

スレーブデータ:

mysql:(なし) 22:42:46>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
+----+------+
セット内の行数は 9 です (0.00 秒)

この時点で、スレーブ ライブラリのパラメータを次のように変更します。

mysql:(なし) 22:42:59>>'%exec%'のような変数を表示します。
+----------------------------------+--------+
| 変数名 | 値 |
+----------------------------------+--------+
| gtid_executed_compression_period | 1000 |
| 最大実行時間 | 0 |
| rbr_exec_mode | STRICT |
| スレーブ実行モード | 厳密 |
+----------------------------------+--------+
セット内の 4 行 (0.00 秒)

mysql:(なし) 22:44:05>>グローバルslave_exec_modeを'IDEMPOTENT'に設定します。
クエリは正常、影響を受けた行は 0 行 (0.00 秒)

mysql:(なし) 22:44:10>>'%exec%'のような変数を表示します。
           +----------------------------------+-------------+
| 変数名 | 値 |
+----------------------------------+-------------+
| gtid_executed_compression_period | 1000 |
| 最大実行時間 | 0 |
| rbr_exec_mode | STRICT |
| スレーブ実行モード | IDEMPOTENT |
+----------------------------------+-------------+
セット内の 4 行 (0.00 秒)

パラメータを変更した後、メイン データベースに対して挿入操作を実行します。

test.yeyzに値(9,9)、(10,10)を挿入します。

次のようにして、スレーブ ライブラリのレプリケーション ステータスとデータ ステータスを確認します。

mysql:(なし) 22:44:14>>スレーブステータスを表示\G
************************** 1. 行 ****************************
               Slave_IO_State: マスターがイベントを送信するのを待機中
                  マスターホスト: 10.30.124.68
                  マスターユーザー: dba_repl
                  マスターポート: 4306
                接続再試行: 60
              マスターログファイル:mysqlbin.000002
          読み取りマスターログ位置: 1183
               リレーログファイル: スレーブリレーbin.000007
                リレーログ位置: 650
        リレーマスターログファイル: mysqlbin.000002
             スレーブIO実行中: はい
            スレーブSQL実行中: はい

セット内の 1 行 (0.00 秒)

mysql:(なし) 22:44:38>>test.yeyzから*を選択します。
+----+------+
| ID | 年齢 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
+----+------+
セット内の行数は 10 です (0.00 秒)

レプリケーション エラーはなく、プライマリ データベースに挿入されたデータも同期されていることがわかります。

要約すると:

  • slave_exec_mode パラメータ;
  • sql_slave_skip_counter=N パラメータ;
  • slave-skip-errors=N パラメータ。

これら 3 つのパラメータは、レプリケーション プロセス中の不整合を解決できます。違いは次のとおりです。

slave_exec_mode パラメータはマスターとスレーブのデータの一貫性を保証できますが、他の 2 つでは保証できません。

slave-skip-errors パラメータは指定されたエラーをスキップできますが、インスタンスを再起動する必要があり、データの一貫性を保証することはできません。

sql_slave_skip_counter パラメータはオフセット レプリケーション モードで使用する必要があり、データの一貫性を保証することはできません。

上記は、MySQL レプリケーション問題の 3 つのパラメータ分析の詳細な内容です。MySQL レプリケーション問題の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MySQL5.7 並列レプリケーションの原理と実装
  • MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明
  • MySQL マスタースレーブレプリケーション切断の一般的な修復方法
  • MySql マスタースレーブレプリケーションメカニズムの包括的な分析
  • MySQL シリーズ 13 MySQL レプリケーション

<<:  CSSを使用してAndroidシステムの読み込みアニメーションを実装する

>>:  クラウドネイティブテクノロジー Kubernetes (K8S) の紹介

推薦する

Windows 2008 Server サブドメインを親ドメインに追加すると、ドメインが既に存在するというエラー メッセージが表示されます。

Windows 2008 Serverのサブドメインを親ドメインに参加させると、「ドメインは既に存...

ツリー チャートの実装方法に関する Echarts チュートリアル

ツリーマップは主にツリーのようなデータ構造を視覚化するために使用され、特殊なタイプの階層です。これを...

JavaScript を使用したコマンドライン アプリケーションの構築

目次1. ノードをインストールする2. Commander.jsをインストールする3. JavaSc...

Ubuntu環境でのPHP関連のパスと変更方法

Ubuntu環境におけるPHP関連パスPHP パス /usr/bin/php phpize5 /us...

mysqlのデータディレクトリ内のファイルを直接コピーしてデータを復元する実装

mysqlはデータディレクトリ内のファイルをコピーしてデータを復元します背景: MySQL がクラッ...

Tomcat が設定ファイルを外部に配置するためのソリューション

質問通常の開発では、プロジェクトを Tomcat にデプロイする場合、プロジェクトを war パッケ...

CSS トップに戻る コード例

最近のウェブサイトのほとんどはページが長く、4 画面または 5 画面の長さのものもあれば、2 画面ま...

Grafana+Prometheus を使用して MySQL サービスのパフォーマンスを監視する

Prometheus (プロメテウスとも呼ばれる) 公式サイト: https://prometheu...

JQueryはアニメーション効果の非表示と表示を実装します

この記事では、アニメーション効果の非表示と表示を実現するためのJQueryの具体的なコードを参考まで...

CSSは5つの一般的な2D変換を実装します

CSS の 2D 変換を使用すると、移動、回転、拡大縮小、変形などの基本的な変換操作を 2 次元空間...

jsはユーザーのページ操作を記憶するためにクッキーを使用します

序文開発プロセスでは、ブラウザレベルでユーザーが実行した操作を記憶するなど、同様の要件に遭遇すること...

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

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

JavaScript オブジェクト指向クラス継承ケースの説明

1. オブジェクト指向のクラス継承これまでの章では、JavaScript のオブジェクト モデルがプ...

Pure CSS と Flutter はそれぞれブリージング ライト効果を実現します (サンプル コード)

前回、非常に熱心なファンから、月を呼吸する光の効果にできるかどうか尋ねられました。月の大きさの写真が...

Chrome デベロッパー ツールの詳細な紹介 - タイムライン

1. 概要ユーザーは、アクセスする Web アプリケーションがインタラクティブでスムーズに実行される...