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 マルチテーブル結合入門チュートリアル

接続は、実際の外部キー(人工的に作成された 2 つのテーブル間の対応関係を指します。対照的に、FOR...

Docker ベースの Etcd 分散デプロイメントの方法と手順

1. 環境整備1.1 基本環境NTP設定: 省略 #時間の一貫性を確保するためにNTPサービスを設定...

シンプルなショッピングカートの最も完全なコード分析を実装する JavaScript (ES6 オブジェクト指向)

この記事では、シンプルなショッピングカートを実装するためのJavaScriptの具体的なコードを参考...

VMware12.0 インストール Ubuntu14.04 LTS チュートリアル

私は、デスクトップ バージョンとサーバー バージョンの両方で、仮想マシンにさまざまなイメージを何度も...

Vue のスロットとフィルターの詳細な説明

目次スロットスロットとは何ですか?スロットの内容コンパイルスコープフォールバックコンテンツ名前付きス...

LinuxカーネルマクロContainer_Ofの詳細な説明

目次1. 構造体はメモリにどのように保存されますか? 2. container_ofマクロ3. 型4...

Dockerでホストファイルをカスタマイズする方法について簡単に説明します

目次1. コマンド2. docker-compose.yml 3. Dockerファイル4. 直接変...

Linux ディスク管理 LVM の使用

1. LVM の概要Linux ディスクを管理するときに、このような状況に遭遇することがよくあります...

初心者向けWebサイト構築ガイド⑥:FlashFXPの詳しい使い方

今日は、サイトの設定やウェブサイトのアップロードなど、FlashFXP の最も基本的な機能を紹介しま...

mysql IS NULL インデックスケースの説明を使用する

導入MySQL の SQL クエリ ステートメントで is null、is not null、!= ...

Linux の一般的なハードディスク管理コマンドの紹介

目次1. dfコマンド2. duコマンド3. fsckファイルシステム修復コマンド4. ディスクステ...

知っておくべき JS 配列削減の高度な使い方 25 選

序文Reduce は ES5 で追加された新しい従来の配列メソッドの 1 つです。forEach、f...

MySQLトランザクションの特徴と分離レベルについてお話ししましょう

インターネットにはすでにこの種の記事が溢れていますが、私がこれをまだ書いている理由は単純です。それは...

大量のデータをMySQLにインポートする際に発生する問題と解決策の分析

プロジェクトでは、SQL を使用してデータ分析を実行するために、大量のデータをデータベースにインポー...

MySQL 5.x 以降を使用している場合のエラー #1929 列 ''createtime'' の日付時刻値が正しくありません: '''' の簡単な解決方法

MySQL をインストールした後、テーブル データを保存および削除しようとすると、常にエラー メッセ...