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のスコアリングルール

推薦する

DockerコンテナのIPアドレスを表示する方法

私はずっとDockerにはIPアドレスがないと思っていました。実はDockerのネットワークテンプレ...

mysql ステートメントを使用してユーザー権限を照会するプロセスの詳細な説明

MySQL では、ユーザーに付与された権限をどのように確認しますか? ユーザーに付与される権限は、グ...

シンプルなページング効果を実現するjQuery+Ajax

この記事では、ページング効果を実現するためのjquery+Ajaxの具体的なコードを参考までに紹介し...

携帯電話番号の真ん中の4桁を隠すMySQL SQL文の方法

最初のクエリ テーブル構造 (sys_users): sys_users から * を選択します。最...

MySQLのクラスタモードでのgalera-clusterのデプロイメントの詳細説明

目次1: galera-clusterの紹介2. galera-clusterの仕組み3: Mari...

CSSコンテンツ属性の具体的な使用法

コンテンツ属性は通常、::before および ::after 疑似要素で使用され、疑似要素のコンテ...

HTML 内の CSS および JS リンクのバージョン番号 (キャッシュを更新)

背景検索エンジンで「.htaccess キャッシュ」というキーワードを検索すると、ウェブサイトのファ...

2時間のDocker入門チュートリアル

目次1.0 はじめに2.0 Dockerのインストール3.0基本的なDockerコマンド4.0 Do...

CSSインジェクションの知識の要約

最近のブラウザでは、CSS 内で JavaScript を実行することはできなくなりました。以前は、...

伝説的な VUE 構文シュガーは何をするのでしょうか?

目次1. 糖衣構文とは何ですか? 2. VUE の構文糖とは何ですか? 1. 最も一般的な構文シュガ...

CocosCreatorでJSZip圧縮を使用する方法

CocosCreator バージョン: 2.4.2 jszipの実践的なプロジェクトアプリケーション...

MySQL ストレージエンジンの簡単な紹介

1. MySQL アーキテクチャストレージ エンジンを紹介する前に、まずは MySQL アーキテクチ...

MySQL ベースのシーケンス実装方法

チームは新しいフレームを交換しました。すべての新しいビジネスでは、新しいフレームワークと新しいデータ...

Vueは携帯電話のカメラとアルバムを呼び出す機能を実装します

この記事では、携帯電話のカメラとアルバムにアクセスするためのVueの具体的なコードを参考までに共有し...

Windows サービス 2012 Alibaba Cloud サーバーで MySQL をビルドするときに msvcr100.dll ファイルが見つからないという問題を解決します

解決策1: msvcr100.dll ファイルをダウンロードし (インターネットからソース ファイル...