MySQL 非同期レプリケーションを構築してみた

本記事は 新人ブログマラソン2024 の記事です

こんにちは。2024年度入社の野上です。

以前、MySQLの初心者ながらレプリケーション方式をまとめた記事を投稿させていただきました。

今回は、以前まとめた方式の中で一般的とされている「非同期レプリケーション」を構築してみました。

これは実際に私が携わった案件で経験した内容になります。

非同期レプリケーションの概要をわかっていても、実際に構築するとなると考慮しなければいけない事が多々ありました。

ブログや公式ドキュメントで書かれていない内容もありましたので、自分の知識のアウトプットもかねて皆さんにご紹介いたします。

非同期レプリケーションとは

まず非同期レプリケーションとはどういう方式なのかという詳細に関しては、前回私が書いた記事を見ていただきたいです。

MySQL レプリケーションの方式をまとめてみた – TechHarmony

ここで簡単に説明しますと、ソースサーバ(メインで使用するDBサーバ)でデータを更新する処理と、レプリカサーバ(複製されたDBサーバ)にデータの更新を反映させる処理が、非同期で行われます。

データベースのデータを更新するときには、トランザクション(データベースの操作を行う1つの処理単位)のコミットを実行し、コミットが完了することで、更新を確定させます。
非同期レプリケーションではレプリカサーバでの処理❶~❷の完了を待たずにコミットを完了します。

 

実際に構築してみた

非同期レプリケーションを構築する順序は以下の通りになります。

  1. サーバの準備
  2. データベースのコピー
  3. パラメータ設定
  4. レプリケーション用ユーザーの作成
  5. レプリケーション設定

各順序を説明しながら、レプリケーションを構築していきます。

サーバの準備

レプリケーションを構築するにあたり、レプリケーションを張る2つのサーバが必要となります。

Amazon EC2を用いて検証用のサーバを構築しました。

今回はMySQLのバージョンは8.0.36を使用しています。MySQLはバージョンの違いによりコマンドが異なりますのでご注意ください

用途 ホストIPアドレス MySQLバージョン
ソースサーバ 10.10.23.187 MySQL8.0.36
レプリカサーバ 10.10.23.19 MySQL8.0.36

 

データベースのコピー

対象のサーバを準備したら、ソースのデータベースをレプリカにコピーする必要があります。

ただレプリケーションを張るだけでは、レプリカのデータベースはソースと同じにはなりません。
レプリケーションは、ソースのバイナリログの内容をレプリカに転送するため、バイナリログが残っている部分しかレプリケーションされません。バイナリログの保持期間は、「binlog_expire_logs_seconds」というパラメータで設定されているため、my.cnfというパラメータの設定ファイルの内容を確認することをお勧めします。

データをコピーする方法は2通りあり、どちらかの方法でコピーを行います。

  • dmpファイルを用いてコピーする(MySQLの公式ドキュメントに記載されている)
  • MySQLのデータディレクトリをコピーする

dmpファイルを用いた方法が一般的ですが、今回は案件の中で私が勉強したことを共有したいこともあり、MySQLのデータディレクトリをコピーする方法で行います。

①ソースでMySQLのデータディレクトリのパスを確認する

データディレクトリのパスは、my.cnfに記述されているため以下のコマンドを実行します。

 

 

②データディレクトリを圧縮する

以下のコマンドを実行することで、「datacopy.tar.gz」という圧縮ファイルが生成されます。

 

 

③生成した圧縮ファイルをレプリカに送信する

ファイルの送信方法もいくつかありますが、今回は2つのサーバで直接通信が可能なので、scpコマンドを利用してファイルの送信を行いました。

 

 

④レプリカ側で圧縮したファイルを解凍してデータディレクトリを上書きする

以下のコマンドを実行することでデータディレクトリのコピーが完了します。
※ここではmvコマンドにより元のデータディレクトリを退避させることで、安全にコマンドを実行しています。

 

 

⑤auto.cnf の削除

以下のデータディレクトリ内に含まれる「auto.cnf」という名前のファイルの削除を行い、MySQLを再起動します。(※)

 

 

 

(※)auto.cnf とは、MySQL server のUUIDを格納したファイルです。UUIDとは一意の識別子であり、UUIDが重複した状態ではレプリケーションを張ることができません。そのため、ソースとレプリカで異なるUUIDを使用する必要があります。auto.cnf は自動で生成されるファイルであり、手動で削除してMySQLを再起動を実行することで自動作成されます。⑤の手順を行うことで、ソースとレプリカで異なるUUIDとなるため、レプリケーションを張ることが可能になります

以上の手順により、データディレクトリのコピーが完了しました。

 

パラメータ設定

レプリケーションを張るためには、レプリケーションに必要なパラメータ設定をする必要があります。

MySQLのパラメータは「my.cnf」という設定ファイルに記述してあり、そのファイル内のパラメータ値を変更します。

 

① 設定が必要なパラメータを以下の通りに設定する

<ソースとレプリカ両方に設定>

  • gtid_mode = ON
    • GTID(グローバルトランザクションID)を有効化するパラメータです。
    • GTIDを有効化することによりソースとレプリカの一貫性の判断を容易にします。
  • enforce_gtid_consistency = ON
    • GTIDを使用する際に、整合性に違反するトランザクションを禁止する設定です。
  • server_id = 1(ソース), 2(レプリカ)
    • レプリケーションの構成内でソースとレプリカを一意に識別するために用います。

<レプリカのみに設定>

  • read_only = ON
    • レプリカ側でデータの更新を拒否します。
    • SUPER権限を持つアカウントは拒否しません。
  • super_read_only = ON
    • レプリカ側でSUPER権限を持つアカウントからの更新を拒否します。

 

② MySQLを再起動する

my.cnf の内容を変更したときには、MySQLを再起動することで設定を反映することができます。
再起動には以下のコマンドを実行します。

 

以上の手順を実行することでMySQLのパラメータ変更が完了しました。

 

レプリケーション用ユーザーの作成

次に、レプリケーションを行うために必要なMySQLのユーザーを作成します。

レプリケーションを張る際には、レプリカがソースのMySQLユーザーとしてデータにアクセスします。そのため、ソース側にレプリケーションのユーザー権限を持ち、レプリカのIPアドレスからのログインを許可するユーザーが必要です。

①ソース側でMySQLにログインし、以下のステートメントを実行してユーザーを作成する

 

 

ここでは、replica@10.10.23.19 というユーザーを作成しています。
MySQLではユーザー名とホスト名の組み合わせによってユーザーを作成します。

 

②作成したユーザーにレプリケーション権限を与える

以下のステートメントを実行します。作成したユーザーがレプリケーション権限を持っていることが確認できます。

 

 

 

 

以上の手順でレプリケーション用のユーザーの作成が完了しました。

 

レプリケーション設定

パラメータの設定が完了したら、いよいよレプリケーションを張ります。

①レプリカ側でMySQLにログインして、レプリケーションの設定を行う

以下のステートメントを実行します。

 

 

 

ここでは、先ほどソースで作成したユーザーのホストアドレス、ユーザー名、パスワードを指定します。

さらに、「source_auto_position」,「source_ssl」という2つのオプションを付けています。
「source_auto_position」はGTIDを使用するために必須のオプションです。
「source_ssl」 はレプリケーションの通信がSSL接続するというオプションです。(※)

(※)MySQLはバージョン5.7以前と8.0以降でユーザー認証の方式が変更されています。5.7以前はデフォルトの認証プラグインが「mysql_native_password」ですが、8.0以降は「caching_sha2_password」となっています。それにより、セキュアな接続が必須となりました。そのため「source_ssl」のオプションを付けない場合にレプリケーション接続が失敗してしまいます
(参考)https://dev.mysql.com/doc/refman/8.0/ja/upgrading-from-previous-series.html#upgrade-caching-sha2-password
 

②レプリケーションの開始

以下のステートメントを実行することでレプリケーション接続を開始します。

 

 

③レプリケーションのステータスの確認

以下のステートメントを実行することでレプリケーションのステータスを表示します。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

実行結果の赤枠で囲んだ項目は以下を意味します。

  • Replica_IO_Running=Yes
    • ソースのバイナリログを読み込み、レプリカにログを転送するスレッドが動いていることを示します。
  • Replica_SQL_Running=Yes
    • レプリカで、ソースから転送されたログからデータの更新を行うスレッドが動いていることを示します。
  • Last_IO_Errno: 0
    Last_IO_Error:
    Last_SQL_Errno: 0
    Last_SQL_Error:       

    • エラーが発生していないことを示します。

上記のことから、実行結果通りであればレプリケーション接続が成功していることになります。

以上の手順を実行しレプリケーションの構築に成功しました。MySQLでは非同期レプリケーションがデフォルトであるため、非同期レプリケーションの構築ができたことになります。

まとめ

本記事では、非同期レプリケーションを実際に構築してみました。

私が案件の中で手を詰まらせた項目は紹介できたと思っています。

しかし、レプリケーションは要件によってパラメータの値などを変化させる必要があります。

そのため今回紹介したのはレプリケーションの構築の1つの例ですが、少しでも読んでくださった方の助けになるポイントがあれば嬉しいです。

タイトルとURLをコピーしました