先日MariaDB ColumnStore 1.2.4のリリースノートにInnoDB EngineテーブルからMariaDB ColumnStoreへのレプリケーション実装を確認しました。
今回は、同機能についての機能検証を行いたいと思います。
MariaDB ColumnStore 1.2.4 Release note
Add hidden switch for MariaDB async replication
Allow simple replication to ColumnStore
DWHへのレプリケーションが業務データベースより簡単に行えるようになると、様々な可能性が広がるかと思います。
これも、ColumnStoreがMariaDB Serverのストレージエンジンであるからこそ為せる技かと思います。
なお、この機能はInnoDBストレージエンジンのテーブルをマスタ、ColumnStoreストレージエンジンのテーブルをスレーブとした構成を意味します。
環境
今回は以下の環境を使用しました。
Hostname | Software | OS | Desc |
---|---|---|---|
mariadb1 | MariaDB Server 10.3.16 | CentOS 7.5 | Master server |
um1 | MariaDB ColumnStore 1.2.5 | CentOS 7.5 | User module(Slave) |
pm1 | MariaDB ColumnStore 1.2.5 | CentOS 7.5 | Performance Module |
MariaDB ColumnStore 1.2.4は一部の機能に問題があったため現在ではRelease Removedのステータスとなっています。
検証の際にはMariaDB ColumnStore 1.2.5をご利用ください。
SystemConfig.ReplicationEnabled
MariaDB Serverからのレプリケーションを許可するためにReplicationEnabledオプションを有効化する必要があります。
Active Parent OAM(通常PM1) で以下のように設定を行い、再起動します。
1 2 |
[root@pm1 ~]# configxml.sh setconfig SystemConfig ReplicationEnabled Y [root@pm1 ~]# mcsadmin restartSystem y |
設定が行われていることを確認します
1 2 |
[root@pm1 ~]# configxml.sh getconfig SystemConfig ReplicationEnabled Current value of SystemConfig / ReplicationEnabled is Y |
テストテーブルの作成
InnoDB とColumnStoreにおけるテーブル定義に幾つかの差異があります
- ColumnStoreにはインデックスが無い
- ColumnStoreにはnvarcharが無い
- auto_incrementの構文の違い
- その他
そのためレプリケートするテーブル定義は事前に類似のものとして作成しておきます。
もし運用中にテーブルを追加する場合は
- MariaDB Server側でバイナリログを出さない(set sql_log_bin=0)
- ColumnStore側でレプリケーションエラーをスキップする(set global sql_slave_skip_counter=1)
等の工夫が必要になりそうです。
mariadb1
1 2 3 4 5 6 7 |
MariaDB> create database replication_test; MariaDB> show databases like 'rep%'; +------------------+ | Database (rep%) | +------------------+ | replication_test | +------------------+ |
um1
1 2 3 4 5 6 7 |
MariaDB> create database replication_test; MariaDB> show databases like 'rep%'; +------------------+ | Database (rep%) | +------------------+ | replication_test | +------------------+ |
mariadb1
1 2 3 4 5 6 7 8 9 10 |
MariaDB> use replication_test MariaDB> create table t1 (i int primary key auto_increment, v varchar(7)); MariaDB> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `i` int(11) NOT NULL AUTO_INCREMENT, `v` varchar(7) DEFAULT NULL PRIMARY KEY (`i`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
um1
1 2 3 4 5 6 7 8 |
MariaDB> create table t1 (i int , v varchar(7)) engine columnstore; MariaDB> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL, `v` varchar(7) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
レプリケーション設定
MariaDB ColumnStoreのUM1のserver-idが1となっているため、MariaDB Server側のserver-idを10としました。
またこの機能は現在のところSTATEMENT Based Replicationでのみ動作しますので、binlog_formatを変更します。
ROW Based Replicationを行った場合、UM側のmysqldがSignal 6を受けてクラッシュし続ける状態となりましたのでご注意ください。
mariadb1
1 2 3 4 5 6 7 8 |
[root@mariadb1 ~]# echo -e "[mysqld]\nserver-id=10\nbinlog_format=STATEMENT" > /etc/my.cnf.d/replication.cnf [root@mariadb1 ~]# systemctl restart mariadb [root@mariadb1 ~]# mysql -e "select @@server_id, @@binlog_format;" +-------------+-----------------+ | @@server_id | @@binlog_format | +-------------+-----------------+ | 10 | STATEMENT | +-------------+-----------------+ |
レプリケーション用ユーザを作成します。
mariadb1
1 |
MariaDB> GRANT REPLICATION SLAVE ON *.* TO rep@`um1` IDENTIFIED BY 'password'; |
現在のポジションを確認しておきます
mariadb1
1 2 3 4 5 6 |
MariaDB> show master status; +---------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +---------------------+----------+--------------+------------------+ | mariadb1-bin.000002 | 534 | | | +---------------------+----------+--------------+------------------+ |
レプリケーションの開始
ColumnStoreでレプリケーションを設定します。
um1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
MariaDB> CHANGE MASTER TO MASTER_USER="rep", MASTER_HOST="mariadb1", MASTER_PASSWORD="password", MASTER_LOG_FILE="mariadb1-bin.000002", MASTER_LOG_POS=534; MariaDB> show slave status\G *************************** 1. row *************************** Slave_IO_State: Master_Host: mariadb1 Master_User: rep Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mariadb1-bin.000002 Read_Master_Log_Pos: 534 Relay_Log_File: relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: mariadb1-bin.000002 Slave_IO_Running: No Slave_SQL_Running: No : (略) : Slave_Transactional_Groups: 0 |
レプリケーションテスト
まずはInnoDB側でinsertを実行します
mariadb1
1 2 3 4 5 6 7 8 9 |
MariaDB> insert into replication_test.t1 values (1, 'test'); Query OK, 1 row affected (0.004 sec) MariaDB> select * from t1; +---+------+ | i | v | +---+------+ | 1 | test | +---+------+ |
ColumnStore側でも反映されたことが確認できました
um1
1 2 3 4 5 6 |
MariaDB> select * from t1; +------+------+ | i | v | +------+------+ | 1 | test | +------+------+ |
マルチソースレプリケーションのテスト
DWHはデータを蓄積するためのデータベースですので、複数データソースがあることが一般的です。
通常のMariaDBではマルチソースレプリケーションが使用可能ですので、ColumnStoreでも可能かテストしてみました。
2台目のマスタとしてmariadb2を構築、起動しています。
um1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
MariaDB> SET @@default_master_connection='mariadb1'; MariaDB> CHANGE MASTER 'mariadb1' TO MASTER_HOST = 'mariadb1', MASTER_USER = 'rep', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mariadb1-bin.000003', MASTER_LOG_POS = 586097370; MariaDB> SET @@default_master_connection='mariadb2'; MariaDB> CHANGE MASTER 'mariadb2' TO MASTER_HOST = 'mariadb2', MASTER_USER = 'rep', MASTER_PASSWORD = 'password', MASTER_LOG_FILE = 'mariadb2-bin.000001', MASTER_LOG_POS = 379651942; |
各サーバにテーブルを作成します。
CREATE TABLE時には set sql_log_bin = 0
を実行するのを忘れないようにしてください。
mariadb1
1 2 3 4 5 |
MariaDB> create database multisource_test; MariaDB> use multisource_test; MariaDB> set sql_log_bin=0; MariaDB> create table t(i int primary key auto_increment, host varchar(10)); MariaDB> set sql_log_bin=1; |
mariadb2
1 2 3 4 5 |
MariaDB> set sql_log_bin=0; MariaDB> create database multisource_test; MariaDB> use multisource_test; MariaDB> create table t(i int primary key auto_increment, host varchar(10)); MariaDB> set sql_log_bin=1; |
um1
1 2 |
MariaDB> use multisource_test; MariaDB> create table t(i int comment 'autoincrement=1', host varchar(10)) engine columnstore; |
um1
1 2 3 4 5 6 7 8 |
MariaDB> pager grep -i -e running: -e connection_name MariaDB> show all slaves status\G Connection_name: mariadb1 Slave_IO_Running: Yes Slave_SQL_Running: Yes Connection_name: mariadb2 Slave_IO_Running: Yes Slave_SQL_Running: Yes |
mariadb1, mariadb2
1 |
seq 100| while read no; do mysql multisource_test -e "insert into t values(null, \"$(uname -n)\")";done |
※ @@hostnameを使用していない理由としてはSTATEMENTベースの場合、スレーブのhostnameとなるためです。
um1
1 2 3 4 5 6 7 |
MariaDB> select host, count(i) from t group by host; +----------+----------+ | host | count(i) | +----------+----------+ | mariadb1 | 100 | | mariadb2 | 100 | +----------+----------+ |
マルチソースレプリケーションについては同機能のチケットで触れられておりませんでしたが概ね正常に動作したようです。
しかしながら、MariaDB ColumnStoreはInnoDBと比較して1行ごとの更新は非常に遅いため、想定通り顕著にレプリケーション遅延が発生しました。
スレーブサーバ | Second_behind_masterの最大値 |
---|---|
MariaDB Server | 20 |
MariaDB ColumnStore | 139 |
replicate_do_db等のレプリケーションフィルタで更新するテーブルを絞る、更新はLOAD DATA INFILEで一度に行う等の工夫が必要そうです。
その他の注意点
- 現在本機能はMulti-UM環境で正常に動作しないようです
- 本来業務データベースとDWH、行指向データベースと列指向データベースでは最適なスキーマ構造が異なります。VIEWをColumnStore側に作成する等の工夫が必要です。
- ColumnStoreは少量のデータであっても比較的大きなデータファイルを初期作成しますのでレプリケーションによって細かいテーブルが増えると不要にストレージが消費されます。
- replicate-do-db/replicate-do-table等レプリケーションフィルタを設定する事が必要になるかもしれません。
- INSERTに限らずUPDATEやDELETE等の処理もレプリケートされ、これらを除外するフィルタは基本機能ではありません。
まとめ
通常のレプリケーションがMariaDB ColumnStoreで可能となったのは大きな進歩です。
しかしながら、データベース特性の違いによる問題や、ROW Based Replicationができない等、課題はまだまだあるようです。
次期リリースであるMariaDB Columstore 1.4では様々な課題が解決されることを期待しつつ、まずは限定的に試すのがよいでしょう。