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) の紹介

推薦する

MySQL テーブルの垂直分割と水平分割

垂直分割垂直分割とは、データテーブルの列を分割すること、つまり、多くの列を持つテーブルを複数のテーブ...

Django が uwsgi+nginx プロキシで静的リソースにアクセスできない問題の解決方法

uwsgi+nginx プロキシ Django をデプロイする場合、uwsgi を使用したアクセスは...

Vue カプセル化 TabBar コンポーネントの完全なステップ記録

目次実装のアイデア:ステップ 1: TabBar と TabBarItem のコンポーネント カプセ...

JavaScriptのスリープ関数の使用

目次1.スリープ機能2.タイムアウトを設定する3. 約束4. 非同期待機5. 1秒後に出力1、2秒後...

vue3.2 で追加された defineCustomElement の基本原理の詳細な説明

目次Webコンポーネントカスタム要素概要HTMLTemplateElement コンテンツ テンプレ...

MYSQL大規模書き込み問題の最適化の詳細な説明

概要: MySQL のパフォーマンス最適化について話すとき、誰もがクエリ パフォーマンスを向上させる...

Dockerコンテナとホスト間のデータ相互作用の概要

序文実稼働環境で Docker を使用する場合、多くの場合、データを複数のコンテナ間で永続化または共...

CSS変数を使用してスタイルを変更する方法の例

質問js を使用して CSS 疑似クラス スタイルを変更するにはどうすればよいでしょうか?しかし、j...

HTMLノードの追加と削除の簡単な例

<br />HTMLノードの追加と削除の簡単な例<input type="...

FileZilla を使用して FTP ファイル サービスを素早く構築する方法

ファイルの保存とアクセスを容易にするために、FTPサービスが特別に構築されています。 FTP サーバ...

Linux システムでデプロイメント プロジェクトを設定する方法

1. ファイアウォールの設定を変更し、対応するポートを開きますLinux システムのファイアウォール...

webpack イメージを base64 に変換する例

url-loader をダウンロード 糸を追加 -D URLローダー モジュール: { ルール: {...

Dockerはプロセス操作を管理するためにSupervisorを使用する

Docker コンテナは、起動時に、たとえば ssh または apache デーモン サービスなどの...

MySQL Shell import_tableデータインポートの実装

目次1. import_tableの紹介2. データのロードとテーブル関数のインポートの例2.1 L...

mysql8.0.23 Linux (centos7) のインストールの完全かつ詳細なチュートリアル

目次リレーショナルデータベースとは何ですか?非リレーショナルデータベースとは何ですか? MySQL ...