【MariaDB】レプリケーションとは
MariaDBのレプリケーションはデータのバックアップや負荷分散に役立つ重要な技術です。
本ブログでは、Windows環境でMariaDBの非同期レプリケーションを設定する方法を初心者~中級者向けに紹介します。
【MariaDB】レプリケーションの目的
データの冗長化とバックアップ
Masterサーバーが障害を起こした場合でもSlaveサーバーにデータが複製されているため、システムの可用性を向上させることができます。
負荷分散
読み取り専用のクエリをSlaveサーバーに振り分けることで、Masterサーバーの負荷を軽減しシステム全体のパフォーマンスを向上させる事ができます。
災害復旧
データセンターやサーバーの障害が発生した際、別の場所にあるSlaveサーバーからデータを復旧することが可能になります。
テスト環境の構築
本番環境のデータを複製しテスト用の環境を作成することで、リスクを抑えた検証作業が可能になります。

【MariaDB】レプリケーションの種類
MariaDBのレプリケーションには以下の種類があります。
非同期レプリケーション
- 最も一般的なレプリケーション方式であり、Masterサーバーがトランザクションをコミットした後、即座に処理を完了とみなします。
- SlaveサーバーはMasterのバイナリログを非同期で取得して適用します。
- MasterとSlaveの間でデータのズレが生じる可能性があるため、障害発生時にデータの不整合が発生することがあります。
セミ同期レプリケーション
- Masterサーバーはトランザクションをコミットした後、少なくとも1つのSlaveサーバーがデータを受信したことを確認するまで次の処理を実行しません。
- 非同期レプリケーションよりもデータ整合性が向上し、Masterの障害発生時にデータの欠落を最小限に抑えることができます。
ただし、Masterの処理速度が遅くなる可能性があるため、パフォーマンスへの影響を考慮する必要があります。
マルチソースレプリケーション
- 1つのSlaveサーバーが複数のMasterサーバーからデータを取得し、統合する方式です。
- 複数のデータソースを集約したい場合や、分散データベースを統合する際に役立ちます。
- 複雑な設定が必要であり、データの競合を適切に管理する必要があります。

本ブログのでのシステム環境
- Masterサーバー
- OS:Windows 10 Pro 22H2
- MariaDB:Community版 11.4.4
- Slaveサーバー
- OS:Windows 10 Home 22H2
- MariaDB:Community版 11.4.4
【MariaDB】Masterサーバーの設定
設定ファイルの編集
設定ファイル my.ini をMasterサーバー用に変更します。
[mysqld]
datadir=C:/Program Files/MariaDB 11.4/data
port=3306
innodb_buffer_pool_size=1527M
character-set-server=utf8mb4
# ------- 追加パラメータ ----------------------------------------------------
server-id=1 # サーバーごとに一意のIDを設定(Masterは1)
log-bin=mysql-bin # バイナリログを有効化
bind-address = 0.0.0.0 # 外部からの接続を許可
binlog-format=row # 行ベースのバイナリログフォーマットを使用(推奨)
expire_logs_days=7 # バイナリログの保存期間(7日間)
max_binlog_size=500M # バイナリログの最大サイズ(500MB)
gtid_strict_mode=1 # GTID整合性に関するチェックを有効化
#----------------------------------------------------------------------------
[client]
port=3306
plugin-dir=C:\Program Files\MariaDB 11.4/lib/plugin
- log-bin=mysql-bin
バイナリログを有効化します。
バイナリログ(Binary Log)は、MariaDBの変更履歴を記録するログであり、データベースの更新(INSERT、UPDATE、DELETEなど)の情報が保存されます。レプリケーションでは、Masterサーバーがこのバイナリログを記録し、Slaveサーバーがそれを取得してデータを同期します。 - binlog-format=row
バイナリログの記録形式を行ベースに設定します。(推奨)
行形式は各行のデータの変更内容を直接記録する為、再実行時にデータの不整合が発生し難くなるますが、ログのサイズが大きくなりがちです。- その他の形式
- STATEMENT(ステートメントベース)
SQLクエリ(INSERT, UPDATE, DELETEなど)をそのままログに記録する方法ですが、NOW()
やRAND()
を含むクエリ等、再実行時に異なる結果になる可能性があります。 - MIXED(ミックス)
STATEMENTとROWのハイブリッドで、MariaDBがクエリの内容に応じて適切なフォーマットを自動で選択します。
- STATEMENT(ステートメントベース)
- その他の形式
- expire_logs_days=7
バイナリログの保存期間(7日間)に設定しています。 - max_binlog_size=500M
バイナリログ(binlog)の最大サイズを指定します。このサイズに達すると新しいバイナリログファイルが自動的に作成されます。- 推奨サイズ
- デフォルト値:
1G
(1GB) - 小規模環境(低トラフィック):
100M
~500M
- 中規模環境(中程度のトラフィック):
500M
~1G
- 大規模環境(高トラフィック):
1G
以上(適宜調整)
- デフォルト値:
- 推奨サイズ
- gtid_strict_mode=1
GTIDモードを有効にします。すべてのトランザクションにGTIDが割り当てられデータの不整合を防ぐことができます。
- binlog-do-db=replication_db
特定のデータベースのみをレプリケーションしたい場合に指定します。指定しない場合は全ての変更がバイナリログに記録されます。
設定を変更したらMariaDBを再起動します。

【MariaDB】レプリケーションユーザーの作成
レプリケーション専用のユーザーを作成し、Slaveサーバーからの接続を許可します。
MariaDB [(none)]> CREATE USER 'repl_user'@'%' IDENTIFIED BY '********';
Query OK, 0 rows affected (0.012 sec)
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
Query OK, 0 rows affected (0.007 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]>
【MariaDB】Slaveサーバーの設定
設定ファイルの編集
設定ファイル my.ini をSlaveサーバー用に変更します。
[mysqld]
datadir=C:/Program Files/MariaDB 11.4/data
port=3306
innodb_buffer_pool_size=1018M
character-set-server=utf8mb4
# ------- 追加パラメータ ----------------------------------------------------
server-id=2 # スレーブサーバーの一意なID
log-bin=mysql-bin # バイナリログを有効化
bind-address = 0.0.0.0 # 外部からの接続を許可
relay-log=relay-bin # リレーログを設定
relay-log-index=relay-bin.index # リレーログインデックスファイル名
read-only=1 # スレーブサーバーを読み取り専用に設定
skip-slave-start=1 # スレーブの自動開始を無効化
relay-log-recovery=1 # 破損したリレーログを自動的に修復します。
# ---------------------------------------------------------------------------
[client]
port=3306
plugin-dir=C:\Program Files\MariaDB 11.4/lib/plugin
- server-id=2
スレーブサーバーの一意なIDを指定します。Masterサーバーは1です。 - relay-log=relay-bin
リレーログのファイル名がrelay-bin.000001
,relay-bin.000002
… のように作成されます。リレーログファイルはrelay-log-index によって管理され、どのリレーログが現在適用されているかを管理します。 - relay-log-index=relay-bin.index
リレーログのインデックスファイルを指定します。

【MariaDB】レプリケーションの開始
Masterサーバー バイナリログの確認
Masterサーバーの現在のバイナリログファイルと位置を確認し、その情報をレプリケーション開始時Slave側で設定します。
MariaDB [(none)]> SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 2763 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.000 sec)
Slaveサーバー レプリケーションの開始
レプリケーションを開始するために、SlaveサーバーでCHANGE MASTER TO
コマンドを実行します。Masterサーバーの現在のバイナリログファイルと位置情報は以下の様に設定します。
MariaDB [(none)]> CHANGE MASTER TO
-> MASTER_HOST='192.168.0.80',
-> MASTER_USER='repl_user',
-> MASTER_PASSWORD='********',
-> MASTER_LOG_FILE='mysql-bin.000003', -- Masterから得たファイル名
-> MASTER_LOG_POS=2763; -- Masterから得た位置
Query OK, 0 rows affected, 1 warning (0.029 sec)
MariaDB [(none)]>
Slaveサーバーでレプリケーションを開始します。
MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.007 sec)
レプリケーション動作の確認
正常に動作していれば Slave_IO_Running
と Slave_SQL_Running
が Yes
になります。
■Slaveサーバーで「SHOW SLAVE STATUR\G」コマンドを実行
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.80
Master_User: repl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 2763
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 555
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
・
・
・
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
Slave_Transactional_Groups: 0
Replicate_Rewrite_DB:
1 row in set (0.001 sec)

Masterサーバー側にレコードを追加して確認
Masterサーバー側にレコードを追加してSlaveサーバーに反映されるか確認します。
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| books_db |
| customers_db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.003 sec)
MariaDB [(none)]> use books_db
Database changed
MariaDB [books_db]> show tables;
+--------------------+
| Tables_in_books_db |
+--------------------+
| books |
+--------------------+
1 row in set (0.003 sec)
MariaDB [books_db]> select * from books;
Empty set (0.000 sec)
MariaDB [books_db]> INSERT INTO books (title, author, genre, price, stock_quantity, publication_date)VALUES ('The Great Adventure', 'John Doe', 'Adventure', 1200.00, 10, '2023-05-10');
Query OK, 1 row affected (0.007 sec)
MariaDB [books_db]> select * from books;
+---------+---------------------+----------+-----------+---------+----------------+------------------+
| book_id | title | author | genre | price | stock_quantity | publication_date |
+---------+---------------------+----------+-----------+---------+----------------+------------------+
| 7 | The Great Adventure | John Doe | Adventure | 1200.00 | 10 | 2023-05-10 |
+---------+---------------------+----------+-----------+---------+----------------+------------------+
1 row in set (0.001 sec)
MariaDB [books_db]>
Slaveサーバー側の確認
Slaveサーバー側にも同一内容のレコードが作成されているか確認します。下記のように同一レコードが作成されており非同期レプリケーションの正常動作が確認できました。
MariaDB [books_db]> show databases;
+--------------------+
| Database |
+--------------------+
| books_db |
| customers_db |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.001 sec)
MariaDB [books_db]> use books_db;
Database changed
MariaDB [books_db]> show tables;
+--------------------+
| Tables_in_books_db |
+--------------------+
| books |
+--------------------+
1 row in set (0.001 sec)
MariaDB [books_db]> select * from books;
+---------+---------------------+----------+-----------+---------+----------------+------------------+
| book_id | title | author | genre | price | stock_quantity | publication_date |
+---------+---------------------+----------+-----------+---------+----------------+------------------+
| 7 | The Great Adventure | John Doe | Adventure | 1200.00 | 10 | 2023-05-10 |
+---------+---------------------+----------+-----------+---------+----------------+------------------+
1 row in set (0.000 sec)
MariaDB [books_db]>

まとめ
非同期レプリケーションではMasterデータベースからSlaveデータベースにデータが複製されます。しかし、コミットした時点でSlaveへのデータ転送が即時に実行される訳ではありません。その為、データの整合性がリアルタイムに保たれない場合があります。
非同期レプリケーションの場合は特に以下の点に留意しましょう。
- データ遅延
アプリケーションを開発する場合、遅延を考慮した設計をする - 監視とログ管理
SHOW SLAVE STATUS等のコマンドを実行して、エラーや警告がないか定期的にチェックする - レプリケーションの再同期
同期が取れなくなった場合、STOP SLAVE
とSTART SLAVE
を使って再同期を行うがデータ損失の可能性があるため慎重に行う - バックアップの実施
定期的にバックアップを実施しデータ損失リスクを最小限に抑える
