オープンソースこねこね

Webプログラミングなどについてあれこれ。

MySQLのレプリケーション構築手順

久しぶりにそういうことをやったので、備忘録です。

前提と方針

  • マスター、スレーブ構成のレプリケーションを設定するための手順です。MySQLのバージョンは5.7を対象とします。
  • OSはCentOS7です。
  • レプリケーションに関わる基本的な概念(バイナリログ、サーバーID)は既知のものとして解説はしません。
  • レプリケーション設定以前のスタンドアロン環境での運用における設定は済んでいるものとします。
  • MySQL5.7では従来の方式に加えて、GTIDベースによるレプリケーションが利用可能になっています。マスター接続時にバイナリログのポジションを指定する必要がないなど、運用上のメリットが多いと判断したので、この方式で構築します。
  • レプリケーションの整合性、安全性を重要視するので行ベースのレプリケーションで設定します。

公式ドキュメントはここ

MySQL :: MySQL 5.7 Reference Manual :: 16 Replication

手順

マスターの設定

my.cnfを設定する。いろいろ他の設定も含めてありますが、以下のreplication (master)部分がレプリケーション関係の主な設定です。server-idをユニークにすることを忘れずに。個々の設定項目の詳細は公式ドキュメントを参照すること。

[mysqld]
server-id             = 1
datadir               = /var/lib/mysql
socket                = /var/lib/mysql/mysql.sock
symbolic-links        = 0
max_allowed_packet    = 100MB
transaction-isolation = READ-COMMITTED
slow_query_log        = 1
slow_query_log_file   = 'mysqld-slow.log'
long_query_time       = 1
max_connections       = 1500
max_connect_errors    = 1000000
log-error             = /var/log/mysqld.log
pid-file              = /var/run/mysqld/mysqld.pid
sql_mode              = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

# replication (master)
log-bin                  = mysql-bin
log-bin-index            = mysql-bin
binlog-format            = 'ROW'
expire_logs_days         = 30
enforce_gtid_consistency = 1
gtid_mode                = ON

# innodb
innodb_file_per_table
innodb_buffer_pool_size = 128MB
innodb_log_file_size    = 48MB

# fulltext search
innodb_ft_min_token_size = 1
ngram_token_size = 1
innodb_ft_enable_stopword = OFF

# character set
character-set-server = utf8mb4
collation-server = utf8mb4_bin
skip-character-set-client-handshake

[mysql]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4

レプリケーション用ユーザの設定を行います。接続元IPの指定やパスワードの設定を適宜、読み替えることを忘れずに。

$ mysql -uroot -p
> GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.0.11/255.255.255.0' IDENTIFIED BY 'yourpassword';
> SELECT Host, User FROM mysql.user;

mysqldを再起動する。

# systemctl restart mysqld

スレーブの設定

my.cnfを設定する。レプリケーションの関連の部分のみ抜粋。他はマスターの設定と同様に。server-idをユニークにすることを忘れずに。

[mysqld]
# ...

# replication (slave)
log-bin                   = mysql-bin
log-bin-index             = mysql-bin
binlog-format             = 'ROW'
expire_logs_days          = 30
enforce_gtid_consistency  = 1
gtid_mode                 = ON
relay-log                 = relay-bin
relay-log-index           = relay-bin
relay_log_info_repository = TABLE
relay_log_recovery        = ON
read_only                 = 1
log_slave_updates         = 1

mysqldを再起動する。

# systemctl restart mysqld

マスターサーバのデータをスレーブにコピーする

ここではコールドバックアップによるマスターのスナップショット(データディレクトリを丸ごとtarで固めたもの)を使っておこないます。 まずマスターのmysqldを停止する。

# systemctl stop mysqld

データディレクトリをコピーしてtarに固める。

# cd /var/lib/mysql
# tar cpf /var/tmp/mysql-snapshot.tar .

スナップショットをスレーブにコピーする。スレーブのIPやSSHユーザー名は適宜読み替えること。

$ scp /var/tmp/mysql-snapshot.tar kohkimakimoto@192.168.0.11:/var/tmp/

スレーブサーバーにログインして、スレーブのmysqldを停止する。

# systemctl stop mysqld

スレーブのmysqlデータディレクトリにスナップショットを展開する。

# cd /var/lib/mysql/
# rm -rf ./*
# tar xpf /var/tmp/mysql-snapshot.tar
# ls -la

バイナリログを削除する。

# rm /var/lib/mysql/mysql-bin.*
# rm /var/lib/mysql/ib_logfile0
# rm /var/lib/mysql/ib_logfile1

サーバーごとのUUIDが設定されているauto.cnfを削除する。(次回起動時に再生成されます)

# rm /var/lib/mysql/auto.cnf

マスターを起動する

# systemctl start mysqld

スレーブを起動する

# systemctl start mysqld

スレーブのレプリケーションを開始する

準備が整いました。スレーブのmysqldに接続して、以下のコマンドを実行して、レプリケーションを開始します。

$ mysql -u root -p
> RESET MASTER;
> CHANGE MASTER TO MASTER_HOST='192.168.0.10', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='yourpassword', MASTER_AUTO_POSITION=1;
> START SLAVE;

スレーブの状態を確認します。

> SHOW SLAVE STATUS\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

となっていることを確認できれば完了です。お疲れさまでした。