まえがき
mariadb10.1より、Running Triggers on the Slave for Row-based Eventsという機能が実装されました。
これを個人的(&社内的)には、
スレーブトリガー
or
レプリケーショントリガー
などと呼称しています。
大まかにいうと、
Aテーブルがレプリケーションで更新される→AテーブルにしかけておいたトリガーでBテーブルを更新
といった機能です。
この機能をうまく使えば、例えば以下のような事が可能になるかなと思っています。
できそうなこと。
- BI用のスレーブサーバがある。
- 以下の様なログイン日時の入っているテーブルをマスタ機からレプリケーションしているとする。
MariaDB [test]> SELECT * FROM login_log ;
+--------+--------+--------------+---------------------+
| SEQ_ID | LOGID | UID | LOGIN_DATE |
+--------+--------+--------------+---------------------+
| 000001 | 111110 | K.HANAZAWA | 2016-04-12 18:49:10 |
| 000002 | 111111 | T.AYANA | 2016-04-12 19:00:39 |
| 000003 | 111112 | Y.OGURA | 2016-04-12 19:02:30 |
| 000004 | 111113 | K.ISHIHARA | 2016-04-12 19:34:21 |
| 000005 | 111114 | Y.HORIE | 2016-04-12 21:11:48 |
| 000006 | 111115 | Y.TAMURA | 2016-04-12 21:39:53 |
| 000007 | 111116 | T.AMAMIYA | 2016-04-13 08:59:04 |
| 000008 | 111117 | Y.NAKAMURA | 2016-04-13 08:59:46 |
| 000009 | 111118 | A.SAKURA | 2016-04-13 09:00:26 |
| 000010 | 111119 | R.HIDAKA | 2016-04-13 09:00:58 |
+--------+--------+--------------+---------------------+
10 rows in set (0.02 sec)
MariaDB [test]>
- ログインする度にLOGIN_DATEが更新される。
- スレーブトリガーを利用して、LOGIN_DATEが更新される度に別テーブルに日次の累計ログイン回数を記録。
こんなイメージです。
MariaDB [test]> SELECT * FROM daily_login_count ;
+--------+--------+--------------+---------------------+---------------------+
| SEQ_ID | LOGID | UID | COUNT_DATE | COUNT |
+--------+--------+--------------+---------------------+---------------------+
| 000001 | 111110 | K.HANAZAWA | 2016-04-12 | 27 |
| 000002 | 111111 | T.AYANA | 2016-04-12 | 26 |
| 000003 | 111112 | Y.OGURA | 2016-04-12 | 20 |
| 000004 | 111113 | K.ISHIHARA | 2016-04-12 | 22 |
| 000005 | 111114 | Y.HORIE | 2016-04-12 | 318 |
| 000006 | 111115 | Y.TAMURA | 2016-04-12 | 318 |
| 000007 | 111116 | T.AMAMIYA | 2016-04-13 | 22 |
| 000008 | 111117 | Y.NAKAMURA | 2016-04-13 | 36 |
| 000009 | 111118 | A.SAKURA | 2016-04-13 | 22 |
| 000010 | 111119 | R.HIDAKA | 2016-04-13 | 21 |
+--------+--------+--------------+---------------------+---------------------+
10 rows in set (0.02 sec)
MariaDB [test]>
- BI用のスレーブ機のみにトリガーをしかけるだけで済む。(少しでもマスターDBの負荷低減ができる。)
- DBだけで完結できる。(DBでやるかは賛否両論あると思いますが。)
早速この機能を試してみました。
動作イメージ図
設定
パラメータについて
公式ドキュメントには以下の通り書いてあります。
Value | Meaning |
---|---|
NO (Default) | Don't invoke triggers for Row-based events |
YES | Invoke triggers for Row-based events, don't log their effect into the binary log |
LOGGING | Invoke triggers for Row-based events, and log their effect into the binary log |
- YESはレプリケーションでもトリガー発動するけど、binlogには書かない。
- LOGGINGならトリガー発動しつつ、binlogにも書き込む(トリガーのかかったテーブルを更にレプリケーションするならこっち?)
パラメータ設定(非永続的)
SET GLOBAL slave_run_triggers_for_rbr = 0/1/2;
- 0=NO(デフォルト)、1=YES、2=LOGGING
パラメータ設定(永続的)
/etc/my.cnf.d/server.cnfに以下を追記して、mysqldを再起動。
slave_run_triggers_for_rbr=1
パラメータ確認。
MariaDB [(none)]> SET GLOBAL slave_run_triggers_for_rbr = 1;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%rbr%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| slave_run_triggers_for_rbr | YES |
+----------------------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]> SET GLOBAL slave_run_triggers_for_rbr = 2;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%rbr%';
+----------------------------+---------+
| Variable_name | Value |
+----------------------------+---------+
| slave_run_triggers_for_rbr | LOGGING |
+----------------------------+---------+
1 row in set (0.00 sec)
MariaDB [(none)]> SET GLOBAL slave_run_triggers_for_rbr = 0;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%rbr%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| slave_run_triggers_for_rbr | NO |
+----------------------------+-------+
1 row in set (0.00 sec)
MariaDB [(none)]>
後は実際にテーブル用意して、TRIGGERを実装すれば、対象テーブルにスレーブトリガーが実行されるようになります。
おまけ
スレーブトリガーの挙動
マスタ側にトリガーあり | マスタ側にトリガーなし | |
---|---|---|
スレーブ側にトリガーあり(マスタと同名同じ内容) | マスタ側内容優先 | スレーブトリガー発動 |
スレーブ側にトリガーあり(マスタと同名別内容) | マスタ側内容優先 | スレーブトリガー発動 |
スレーブトリガーなし | マスタ側の内容が反映 | - |
具体的な使い方の考案については、また後日。