LoginSignup
3
2

More than 5 years have passed since last update.

mariadbのスレーブトリガーを試してみる。(slave_run_triggers)

Last updated at Posted at 2016-04-13

まえがき

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でやるかは賛否両論あると思いますが。)

早速この機能を試してみました。

動作イメージ図

レプリケーショントリガーイメージ.gif

設定

パラメータについて

公式ドキュメントには以下の通り書いてあります。

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を実装すれば、対象テーブルにスレーブトリガーが実行されるようになります。

おまけ

スレーブトリガーの挙動

マスタ側にトリガーあり マスタ側にトリガーなし
スレーブ側にトリガーあり(マスタと同名同じ内容) マスタ側内容優先 スレーブトリガー発動
スレーブ側にトリガーあり(マスタと同名別内容) マスタ側内容優先 スレーブトリガー発動
スレーブトリガーなし マスタ側の内容が反映 -

具体的な使い方の考案については、また後日。

3
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2