MySQL GTID の総合概要

MySQL GTID の総合概要

01 GTIDの紹介

GTID は、グローバル トランザクション識別子の正式名称であり、グローバル トランザクション ID とも呼ばれます。 MySQL-5.6.2 のサポートが開始され、MySQL-5.6.10 が改良されました。GTID は 2 つの部分に分かれています。1 つの部分はサービスの UUID です。UUID は MySQL データ ディレクトリの auto.cnf ファイルに保存されます。
これは非常に重要なファイルなので削除できません。この部分は変更されません。以下は uuid 値の例です。

[root@dev01 mysql]# cat auto.cnf
 [自動]
サーバーUUID=ac1ebad0-ef76-11e7-872b-080027a03bb6

もう一つの部分はトランザクション ID です。トランザクションの数が増えると、値も増加します。つまり、GTID は実際には UUID + TID で構成されています。 UUID は MySQL インスタンスの一意の識別子です。 TID は、インスタンスでコミットされたトランザクションの数を表します。以下は GTID の例です。

3db33b36-0e51-409f-a61d-c99756e90155:1-14

02 GTIDの仕組み

1. マスターがデータを更新すると、トランザクションの前に GTID を生成し、それを binlog ログに記録します。
2. スレーブの I/O スレッドは、変更されたバイナリログをローカルリレーログに書き込みます。
3. SQL スレッドはリレー ログから GTID を取得し、スレーブ側の binlog にレコードがあるかどうかを比較します。
4. レコードが存在する場合、GTID のトランザクションが実行されたことを意味し、スレーブはそれを無視します。
5. レコードがない場合、スレーブはリレーログから GTID のトランザクションを実行し、バイナリログに記録します。
6. 解析プロセス中に、主キーがあるかどうかが判断されます。主キーがない場合は、セカンダリ インデックスが使用されます。主キーがない場合は、フル スキャンが実行されます。

03 GTIDの利点と欠点

アドバンテージ:

1. トランザクションは一意のGTIDに対応し、GTIDはサーバー上で1回だけ実行されます。
2.GTIDは従来のレプリケーション方法に代わるものです。GTIDレプリケーションと通常のレプリケーションモードの最大の違いは、バイナリファイル名と場所の指定を必要としないことです。
3. 手動介入とサービスのダウンタイムを削減します。メイン マシンに障害が発生した場合、ソフトウェアは多数のバックアップ マシンから 1 つのバックアップ マシンをメイン マシンに昇格させることができます。

欠点:

1. 非トランザクションエンジンはサポートされていません
2. create table ... select ステートメントのレプリケーションはサポートされていません (マスター データベースは直接エラーを報告します)
原則: (2 つの SQL が生成されます。1 つはテーブルを作成するための DDL SQL で、もう 1 つはデータを挿入するための挿入 SQL です。
DDL は自動送信を引き起こすため、この SQL には少なくとも 2 つの GTID が必要ですが、GTID モードでは、この SQL に対して生成できる GTID は 1 つだけです。
3. 1つのSQL文でトランザクションエンジンテーブルと非トランザクションエンジンテーブルを同時に更新することはできません。
4. GTIDを有効にするには再起動が必要です(5.7を除く)
5. 一時テーブルの作成および一時テーブルの削除ステートメントはサポートされていません。
6. sql_slave_skip_counterはサポートされていません

04 テスト環境構築

ノード:
サーバー1 192.168.197.128 3306 マスター
server2 192.168.197.137 3306 スレーブ
server3 192.168.197.136 3306 スレーブ

GTID を有効にするには、次の 3 つのパラメータを有効にする必要があります。

gtid_mode = オン

強制GTID一貫性 = 1

ログスレーブ更新 = 1

テスト環境を構築する手順は次のとおりです。

1. マスターノードにレプリケーションユーザーを作成し、マスターノードの GTID オプションを有効にします。

mysql> '123456' で識別される 'repluser'@'%' に *.* 上のレプリケーション スレーブを許可します。
クエリは正常、影響を受けた行は 0 行、警告は 1 件 (0.00 秒)

2. スレーブ ノードでマスターの変更操作を実行し、次のようにマスターとスレーブの関係を構築します。

mysql>マスターを次のように変更します
     -> マスターホスト='192.168.197.128',
    -> マスターユーザー='repluser',
    -> マスターパスワード='123456',
    -> マスターポート=3306、
    -> マスター自動位置 = 1;
クエリは正常、影響を受けた行は 0 行、警告は 2 件 (0.01 秒)

3. インストールが成功したら、スレーブ ノードがマスター ノード 197.128 に参加しているかどうかを確認します。

mysql> スレーブホストを表示します。
+-----------+------+-------+---------+--------------------------------------+
| Server_id | ホスト | ポート | Master_id | Slave_UUID |
+-----------+------+-------+---------+--------------------------------------+
| 3 | | 3306 | | 969488f5-c486-11e8-adb7-000c29bf2c97 |
| 2 | | 3306 | | bb874065-c485-11e8-8b52-000c2934472e |
+-----------+------+-------+---------+--------------------------------------+
 セット内の行数 (.sec)

接続を表示します:

mysql> プロセスリストを表示します。
+----+----------+------------------+------+------------------+------+--------------------------------------------------------------+--+
| ID | ユーザー | ホスト | db | コマンド | 時間 | 状態 | 情報 |
+----+----------+------------------+------+------------------+------+--------------------------------------------------------------+--+
| | root | localhost | NULL | クエリ | 0 | 開始 | プロセスリストを表示 |
| 3 | repluser | work_NAT_4:60051 | NULL | バイナリログ ダンプ GTID | | マスターはすべてのバイナリログをスレーブに送信しました。さらに更新を待機しています | NULL |
| | repluser | work_NAT_5: | NULL | バイナリログ ダンプ GTID | 5970 | マスターはすべてのバイナリログをスレーブに送信しました。さらに更新を待機しています | NULL |
+----+----------+------------------+------+------------------+------+--------------------------------------------------------------+--+
 セット内の行数 (.sec)

4. 3 つのテスト環境の UUID は次のとおりです。

197.128
mysql> @@server_uuid を選択します。
+--------------------------------------+
| @@サーバーのUUID |
+--------------------------------------+
| bd0d-8691-11e8-afd6-4c3e51db5828 |
+--------------------------------------+
 セット内の行数 (0.00 秒)

197.137
mysql> @@server_uuid を選択します。
+--------------------------------------+
| @@サーバーのUUID |
+--------------------------------------+
|bb874065-c485-11e8-8b52-000c2934472e |
+--------------------------------------+
 セット内の行数 (0.00 秒)

197.136
mysql> @@server_uuid を選択します。
+--------------------------------------+
| @@サーバーのUUID |
+--------------------------------------+
|f5-c486-11e8-adb7-000c29bf2c97 |
+--------------------------------------+
 セット内の行数 (0.00 秒)

05 テストを開始する

テスト環境は主に以下の側面に分かれています。

a. レプリケーションフェイルオーバーをテストする

b. コピーエラースキップ

1 レプリ​​ケーションフェイルオーバーをテストする

まず、テスト レプリケーションのフェイルオーバーを見てみましょう。

(1)まず、サーバ3のレプリケーションプロセスを停止する

mysql> スレーブを停止します。
クエリは正常、影響を受けた行は 0 行 (0.01 秒)

(2)サーバー1にデータを作成する

mysql> テーブル yyy.a(id int); を作成します。
クエリは正常、影響を受けた行は 0 行 (0.03 秒)

mysql> テーブル yyy.b(id int); を作成します。
クエリは正常、影響を受けた行は 0 行 (0.02 秒)

mysql> テーブル yyy.c(id int); を作成します。
クエリは正常、影響を受けた行は 0 行 (0.02 秒)

(3)他の2台のマシンでデータ結果を確認します。

サーバ 
mysql> yyy からテーブルを表示します。
+---------------+
| テーブル_in_yyy |
+---------------+
| ア |
| バ |
| は |
+---------------+
 セット内の行数 (0.00 秒)

サーバ 
mysql> yyy からテーブルを表示します。
空のセット (0.00 秒)

(4) この時点で、サーバー2のデータがサーバー3のデータよりも新しいことがわかります。次に、サーバー1を停止して、プライマリサーバーのクラッシュをシミュレートします。

[root@work_NAT_1 init.d]# サービスmysqldを停止します
MySQL をシャットダウンしています............ [ OK ]

(5)この時点で、他の2つのノードはサーバ1にアクセスできなくなっていることがわかる。

mysql>スレーブステータスを表示\G
************************** 1. 行 ****************************
        Slave_IO_State: マスターイベントの読み取りに失敗した後に再接続中
         マスターホスト: 192.168.197.128
         マスターユーザー: repluser
         マスターポート: 3306
        接続再試行: 60
       マスターログファイル: mysql-bin.000006
     読み取りマスターログ位置: 1364
        リレーログファイル:mysql-relay-bin.000004
        リレーログ位置: 1569
    リレーマスターログファイル: mysql-bin.000006
       Slave_IO_Running: 接続中
      スレーブSQL実行中: はい
     実行マスターログ位置: 1364
       リレーログスペース: 2337 
        マスターSSLキー: 
    マスターより遅れている秒数: NULL
Master_SSL_Verify_Server_Cert: いいえ
        最終IOエラー番号: 2003
        Last_IO_Error: マスター '[email protected]:3306' への再接続エラー - 再試行時間: 60 再試行回数: 1
        最終SQLエラー番号: 0

(6)サーバー2のデータが新しいため、サーバー2をサーバー3のプライマリデータベースとして設定する必要があります。このとき、従来の方法を使用すると、以前のメインデータベースの log_pos と現在のメインデータベースとして設定する log_pos を計算する必要があり、失敗する可能性が高くなります。そのため、この問題を解決するために、MHA や MMM などの高可用性ツールが登場しました。

MySQL 5.6 以降では、この問題は簡単に解決されました。同じトランザクションの GTID はすべてのノードで同じ値を持つため、server3 の現在の停止ポイントの GTID に基づいて server2 の GTID を見つけることができ、server3 で直接変更を実行できます。

mysql>マスターを次のように変更します 
  -> マスターホスト='192.168.197.137',
  -> マスターユーザー='repluser',
  -> マスターパスワード='123456',
  -> マスターポート=,
  -> マスター自動位置 =;
クエリは正常、行は影響を受け、警告あり (0.01 秒)

(7)サーバー3のデータを確認すると、データが同期されていることがわかります。

2 コピーエラースキップ

上記のテストでは、最終結果はサーバー 2 がプライマリ ノード、サーバー 3 がセカンダリ ノードです。次に、レプリケーション エラーをスキップする方法を検証します。

(1)まず、スレーブノード上でdrop文を実行して、両側のデータの不整合を次のようにします。

mysql> データベースを表示します。
+--------------------+
| データベース |
+--------------------+
| 情報スキーマ |
| DBA |
| 顧客 |
| インク_db |
|mysql |
| パフォーマンススキーマ |
|システム|
|テストデータベース|
|はいはい|
|あ|
+--------------------+
 セット内の行数 (.sec)

mysql> データベース yyy を削除します。
クエリは正常、行は影響を受けました (. 秒)

mysql> データベースを表示します。
+--------------------+
| データベース |
+--------------------+
| 情報スキーマ |
| DBA |
| 顧客 |
| インク_db |
|mysql |
| パフォーマンススキーマ |
|システム|
|テストデータベース|
|はいはい|
+--------------------+
 セット内の行数 (.sec)

(2)次に、サーバー2でdrop database yyy操作を次のように実行します。

mysql> データベース yyy を削除します。
クエリは正常、3 行が影響を受けました (0.02 秒)

(3)この時点で、サーバ3にyyyデータベースがないため(前の手順で削除されているため)、マスタースレーブ同期外れエラーの警告が表示されていることがわかります。エラーは次のとおりです。

mysql>スレーブステータスを表示\G
*************************** 。 行 ***************************
        Slave_IO_State: マスターがイベントを送信するのを待機中
         マスターホスト: 192.168.197.137
         マスターユーザー: repluser
         マスターポート: 
        接続再試行: 
       マスターログファイル: mysql-bin。
     マスターログ位置を読み取り: 
        リレー ログ ファイル: mysql-relay-bin。
        リレーログ位置: 
    リレーマスターログファイル: mysql-bin。
       スレーブIO実行中: はい
      スレーブSQL実行中: いいえ
          最終エラー番号: 
          Last_Error: クエリでエラー「データベース 'yyy' を削除できません。データベースが存在しません」が発生しました。デフォルトのデータベース: 'yyy'。クエリ: 'drop database yyy'
         スキップカウンター: 
     実行マスターログ位置: 
       リレーログスペース: 
        Last_SQL_Error: クエリでエラー「データベース 'yyy' を削除できません。データベースが存在しません」が発生しました。既定のデータベース: 'yyy'。クエリ: 'drop database yyy'
 Replicate_Ignore_Server_Ids: 
       マスターサーバーID: 
         マスター_UUID: bb874065-c485-e8-b52-c2934472e
       マスター情報ファイル: mysql.slave_master_info
      取得済みGtidセット: bd0d--e8-afd6-c3e51db5828:-,
bb874065-c485-e8-b52-c2934472e:
      実行されたGtidセット: db33b36-e51-f-a61d-c99756e90155:-,
bd0d--e8-afd6-c3e51db5828:-,
f5-c486-e8-adb7-c29bf2c97:
        自動位置: 
     Replicate_Rewrite_DB: 
         チャンネル名: 
      マスター TLS バージョン: 
 セット内の行数 (0.00 秒)

(4)このエラーをスキップするために従来の方法を使用すると、次のようにGTIDモードでは許可されていないというメッセージが表示されます。

mysql> グローバル sql_slave_skip_counter= を設定します。
エラー (HY000): サーバーが @@GLOBAL.GTID_MODE = ON で実行されている場合、sql_slave_skip_counter を設定することはできません。代わりに、スキップするトランザクションごとに、トランザクションと同じ GTID を持つ空のトランザクションを生成します。

では、この方法でこのエラーをスキップするにはどうすればよいでしょうか?

(5) GTID 経由でレプリケーションを行っているため、このトランザクションもスキップしてレプリケーションを続行する必要があります。このトランザクションは、マスターの binlog で確認できます。どの GTID がエラーの原因となったかわからないため、どの GTID をスキップすればよいかわかりません。ただし、上記手順 (3) の 18 行目のコードである show slave status の情報から、実行中のマスターの POS:2012 を見つけることができます。ここで、pos:2012 を使用してサーバー 2 のログを検索し、次の情報を見つけます。

# 2012年
#190305 20:59:07 サーバー ID 2 end_log_pos 2073 GTID last_committed=9 シーケンス番号=10 rbr_only=no
@@SESSION.GTID_NEXT= 'bb874065-c485-11e8-8b52-000c2934472e:1' を設定します。
# 2073 で
#190305 20:59:07 サーバー ID 2 end_log_pos 2158 クエリ thread_id=3 exec_time=0 error_code=0
タイムスタンプを /*!*/ に設定します。
データベースyyyを削除
//*!*/;

(6)GTID_NEXTの値は

次に、次の方法でマスター スレーブ レプリケーションを復元します。

mysql> スレーブを停止します。
クエリは正常、行は影響を受けました (0.00 秒)

mysql> セッション gtid_next='bb874065-c485-11e8-8b52-000c2934472e:1' を設定します。
クエリは正常、行は影響を受けました (0.00 秒)

mysql> 開始します。
クエリは正常、行は影響を受けました (0.00 秒)

mysql> コミット;
クエリは正常、行は影響を受けました (0.01 秒)

mysql> セッション gtid_next=automatic を設定します。
クエリは正常、行は影響を受けました (0.00 秒)

mysql> スレーブを起動します。
クエリは正常、行は影響を受けました (0.00 秒)

mysql>スレーブステータスを表示\G
************************** 1. 行 ****************************
        Slave_IO_State: マスターがイベントを送信するのを待機中
         マスターホスト: 192.168.197.137
         マスターユーザー: repluser
         マスターポート: 3306
        接続再試行: 60
       マスターログファイル:mysql-bin.000002
     読み取りマスターログ位置: 2158
        リレーログファイル:mysql-relay-bin.000003
        リレーログ位置: 478
    リレーマスターログファイル: mysql-bin.000002
       スレーブIO実行中: はい
      スレーブSQL実行中: はい
     実行マスターログ位置: 2158
       リレーログスペース: 1527
       Until_Condition: なし
       マスターサーバー ID: 2
         マスター_UUID: bb874065-c485-11e8-8b52-000c2934472e
       マスター情報ファイル: mysql.slave_master_info
          SQL_遅延: 0
     SQL_残り遅延: NULL
   Slave_SQL_Running_State: スレーブはすべてのリレーログを読み取りました。さらに更新を待機しています。
      マスター再試行回数: 
      取得済み_Gtid_Set: bd0d-8691-11e8-afd6-4c3e51db5828:-7、
bb874065-c485-11e8-8b52-000c2934472e:
      実行されたGtidセット: db33b36-0e51-409f-a61d-c99756e90155:-14、
bd0d-8691-11e8-afd6-4c3e51db5828:-7、
f5-c486-11e8-adb7-000c29bf2c97:,
bb874065-c485-11e8-8b52-000c2934472e:
        自動位置: 
     Replicate_Rewrite_DB: 
         チャンネル名: 
      マスター TLS バージョン: 
 セット内の行数 (0.00 秒)

上記はMySQL GTIDの包括的な概要の詳細な内容です。MySQL GTIDの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MYSQL データベース GTID はマスタースレーブレプリケーションを実現します (超便利)
  • MySQL 5.7 で業務を停止せずに従来のレプリケーションを GTID レプリケーションに変更する例
  • MySQL で GTID モードをオンラインで有効または無効にする

<<:  CSS スティッキーフッターのいくつかの実装

>>:  Yahooが開発したウェブページスコアリングプラグインYSlowのスコアリングルール

推薦する

Vue3+Element+Tsは、フォームの基本的な検索リセットやその他の機能を実装します

Vue2 の記述スタイルから Vue3 の形式に切り替えると、記述スタイルとコード構造にいくつかの変...

ネイティブ js はカスタム スクロール バー コンポーネントを実装します

この記事の例では、カスタムスクロールバーコンポーネントを実装するためのjsの具体的なコードを参考まで...

Vueコンポーネントの基本のまとめ

コンポーネントの基本1 コンポーネントの再利用コンポーネントは再利用可能な Vue インスタンスです...

HTML テーブル マークアップ チュートリアル (29): セルのライト境界線の色属性 BORDERCOLORLIGHT

セルでは、明るい境界線の色を個別に定義できます。 > 基本構文<TD ボーダーカラーライ...

MySQL スケジュールバックアップタスクの簡単な分析

導入実稼働環境では、データの損失を回避するために、通常、データベースは定期的にバックアップされます。...

【Webデザイン】E-WebTemplates の美しい海外の Web ページ テンプレート (FLASH+PSD ソース ファイル+HTML) を共有します

これらはすべて海外のE-WebTemplates WebサイトからのWebページテンプレートであり、...

MySQLのインストールと設定方法のグラフィックチュートリアル(CentOS7)

1. システム環境[root@localhost ホーム]# cat /etc/redhat-re...

MySQLの行数カウントに関する簡単な説明

各テーブルの行数をカウントするために使用される MySQL count() 関数は、誰もがよく知って...

Linux のタイムドログ削除を実装する簡単な方法

導入Linux は、ファイル、ログ、電子メール、バックアップなどを自動的に生成できるシステムです。ハ...

Docker+gitlab+jenkins は、ゼロから自動デプロイメントを構築します

目次序文: 1. Dockerをインストールする2. DockerでJenkinsをインストールする...

デザイン参考 WordPressウェブサイト構築成功事例

これら 16 のサイトはそれぞれ注意深く読む価値があり、どのサイトでも推奨されている Web サイト...

HTML テキストエスケープのヒント

今日、CSDN で HTML テキスト エスケープのちょっとしたトリックを見ましたが、とても簡単です...

Mysql データベースの日付と日時型でデフォルト値 0000-00-00 を設定するときに発生するエラー問題の詳細な説明

現象: MySQL バージョン 5.7 以降では、日付型と日付時刻型のデフォルト値が「0000-00...

Vue3 はメッセージコンポーネントの例を実装します

目次コンポーネント設計最終的なコンポーネントAPIの定義コンポーネント構造の定義テンプレートとスタイ...

Docker swarm の簡単なチュートリアル

3つの仮想マシン132、133、134を群がらせる1. クラスターを初期化し、自分自身をクラスターに...