はじめに
この記事ではMariaDBにおけるレプリケーション環境の構築方法についてまとめる。
レプリケーション自体の説明やどういうことに使うかといったことについては記載しない。
この記事の対象者
- MariaDBにおけるレプリケーションの方法を知りたい方
筆者の環境
MariaDB v11.4.2 のDockerイメージを使って環境構築している。
同一のdocker networkにコンテナを2つ用意し、1つはマスタ、もう一つはレプリカとする。
試した環境は以下のGitHubに上げておく。
環境構築方法
マスタ側の準備
マスタ側(レプリケーションの元となるDB)の準備を行う
MariaDBの設定
MariaDBの設定ファイル(*.cnf
)に下記を設定する。
[mariadb]
log-bin
server_id=10
log-basename=master1
binlog-format=mixed
- log-bin
バイナリログを出力するかどうかを指定する。
レプリケーションにはバイナリログを使用するため、この設定は必須。
log-bin=〇〇
みたいな書き方はせず、log-bin
とだけ書けばOK。
- server_id
MariaDBサーバのIDを整数で指定する。
レプリケーションを構築するすべてのDBサーバ内で一意にする必要がある。
- log-basename
すべてのログ関連ファイルのベースとなる名前を指定する。
これを指定しないとファイル名にホスト名が使われ、ホスト名が変更されたときに影響があるため、設定しておくことを推奨している。
- binlog-format
バイナリログの書き方を指定する。
row
, statement
, mixed
のいずれかを指定可能。
基本的にはmixed
を使えば問題ない。
row
はバイナリログのファイルサイズが大きくなるが、個々の行がどのように変わるのかを記録するため、安全にレプリケーションできる。
statement
はファイルサイズは小さいが、クエリそのものをバイナリログに書き込むため、非決定的なSQL(現在日時を使っているなど)の場合、マスタとレプリカで値が異なってしまう可能性がある。
mixed
はそれらのいいとこどり。
基本的にはstatement
を使い、非決定的なクエリの場合はrow
が使われる。
レプリケーションユーザの作成
レプリカがマスタのバイナリログを読み込めるように、レプリケーション専用のユーザを作成する。
replication slave
の権限が必要になるため、その権限も付与しておく。
-- レプリケーション用のユーザ作成
create user if not exists 'repl'@'%' identified by '12345678';
-- replication slave の権限も付与する
grant replication slave on *.* to 'repl'@'%';
全テーブルのロック
レプリケーション設定中にDBの変更が起きないようにすべてのテーブルをロックしておく。
FLUSH TABLES WITH READ LOCK
FLUSH
ステートメントを入力したセッションを切ってしまうと、テーブルロックが解除されてしまうため、セッションを切らずに置いておくこと。
バイナリログのポジションの確認
show master status
でバイナリログのファイル名(File列)とポジション(Position列)を確認し、メモしておく。
show master status;
+--------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| master1-bin.000002 | 1188 | | |
+--------------------+----------+--------------+------------------+
DBのバックアップ
mariadb-backup
コマンドでフルバックアップを取得する。
target-dir
オプションでバックアップ先を指定可能。
mariadb-backup --backup --target-dir=/var/data/backup -uroot -p12345678
target-dir
で指定したディレクトリごと、レプリカにコピーする。
レプリカの準備
MariaDBの設定
MariaDBの設定ファイル(*.cnf
)に下記を設定する。
レプリカ側はserver_id
のみを設定する。
マスタや他のレプリカと同じserver_id
にならないように注意。
[mariadb]
server_id=20
バックアップのリストア
マスタ側で取得したバックアップをレプリカ側でリストアする。
MariaDBのデータディレクトリが空でないと、mariadb-backup
コマンドの際に失敗してしまうため、データディレクトリの中身をすべて削除した状態にしておく。
# 隠しファイルを含めて、データディレクトリの中身を全部削除
# これをやっておかないとmariadb-backupコマンドの際にエラーになる
rm -rf /var/lib/mysql/* && rm -rf /var/lib/mysql/.*
# copy-backオプションを使うことでリストアできる
# target-dirにバックアップファイルのディレクトリを指定する
mariadb-backup --copy-back --target-dir=/var/data/backup/
データディレクトリの中身の所有者を変更する
mariadb-backup
コマンドでリストアした場合、リストアされたデータディレクトリ内のファイルの所有者およびグループはコマンドを入力したユーザになるため、どちらもmysql
に変更しておく。
chown -R mysql:mysql /var/lib/mysql/
レプリカのMariaDBを再起動する
dockerのMariaDBコンテナであれば、docker restart
でOK
docker restart mariadb_slave
マスタ側のテーブルロックを解除する
ここまで来れば、マスタ側のテーブルロックを解除して問題ない。
テーブルロック (FLUSH TABLES WITH READ LOCK
) していたセッションを切るか、テーブルロックしているセッションで以下を入力すれば解除可能。
UNLOCK TABLES;
どのサーバをマスタにするのか設定する
レプリカ側でCHANGE MASTER TO
を使い、どのサーバをマスタとするか設定する。
CHANGE MASTER TO
MASTER_HOST='mariadb_master',
MASTER_USER='repl',
MASTER_PASSWORD='12345678',
MASTER_PORT=3306,
MASTER_LOG_FILE='master1-bin.000002',
MASTER_LOG_POS=1188,
MASTER_CONNECT_RETRY=10;
- MASTER_HOST
マスタとなるサーバのホスト名を入れる。
- MASTER_USER
マスタ側の設定で作成したレプリケーション用のユーザ
- MASTER_PASSWORD
レプリケーション用のユーザのログインパスワード
- MASTER_PORT
マスタとなるサーバのMariaDBのポート番号
- MASTER_LOG_FILE
マスタ側でバイナリログのポジションの確認(show master status
)した際にメモしておいた、ログファイル名
- MASTER_LOG_POS
マスタ側でバイナリログのポジションの確認(show master status
)した際にメモしておいた、ポジション
- MASTER_CONNECT_RETRY
マスタへの接続が失敗した際に何回リトライするか。
レプリケーションを開始する
レプリカ側にて以下のステートメントを実行し、レプリケーションを開始する。
START SLAVE;
開始したら、SHOW SLAVE STATUS
ステートメントを実行し、Slave_IO_Running
、Slave_SQL_Running
の状態を確認する。
これらがYes
になっていれば問題なし。
SHOW SLAVE STATUS \G
*************************** 1. row ***************************
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
何かしらのエラーが発生した場合は、SHOW SLAVE STATUS
の結果のLast_IO_Error
にエラー内容が設定されるため、ここをみて対処する。
レプリケーションの確認
実際にレプリケーションができているか確認する。
マスタ、レプリカが以下のテーブルを持っている状態とする。
- マスタ
select * from t1;
+----+------+
| id | name |
+----+------+
| 1 | taro |
| 2 | jiro |
+----+------+
- レプリカ
select * from t1;
+----+------+
| id | name |
+----+------+
| 1 | taro |
| 2 | jiro |
+----+------+
この状態でマスタに対してデータを変更してみる。
-- マスタで実行する
update t1 set name = 'taro2' where id = 1;
レプリカ側がマスタ側と同じ状態になっていることを確認する。
select * from t1;
+----+-------+
| id | name |
+----+-------+
| 1 | taro2 |
| 2 | jiro |
+----+-------+
まとめ
今回はMariaDBにおけるレプリケーションの環境構築方法をまとめた。
MariaDBでレプリケーション環境を整えようしている人に参考になれば嬉しく思う。
それではまた。
TomoProg
参考資料