2019年6月3日月曜日

第一印象 of MySQL Ripple

TL;DR

  • MySQL Ripple を試してそっと閉じたメモ。
  • 多分 こういう状態で使うんだと思う
    • マスターの部分はよしなに冗長化されていると思いねえ
    • (おそらく準同期レプリケーションで)マスターに直接スレーブをぶら下げると死んじゃうようなケース
    • あと、このMySQL Ripple自体もたぶん多段構成するんだろうな、とデフォルトのパラメーター(主に -ripple-master-port )を見て思う

ビルド

Dockerイメージで起動

$ docker run -v $PWD:/root/binlog mysql-ripple \
  --ripple-server-address=0.0.0.0 \
  --ripple-master-address=172.17.0.3 \
  --ripple-master-port=3306 \
  --ripple-datadir=/root/binlog
ホスト側にbinlogの保管ディレクトリーをマウントしてるのは深い意味はない。
-ripple-server-address は外側のIPアドレスなり0.0.0.0なりにしておかないと他所のホストからつつけない(デフォルトがlocalhostなので)
-ripple-master-port のデフォルトが3306 ではなく MySQL Rippleが使う51005なので、MySQL Ripple同士で多段構成するのが前提なのかも知れない。

コマンドラインクライアントで接続してみる

  • デフォルトのポートは51005
  • 接続すること自体はできるが、クエリーのパースはできないので、何かコマンドやSQLを叩いても大抵エラーになる
$ mysql -h172.17.0.4 -P51005
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 28
Server version: 5.6.0-ripple ripple version comment

mysql> status
ERROR 2013 (HY000): Lost connection to MySQL server during query

mysql> SHOW MASTER LOGS;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    28
Current database: *** NONE ***

ERROR 2013 (HY000): Lost connection to MySQL server during query

マスターにぶら下げてみる

  • gtid_mode= ON のみのサポート
  • master_log_file とか設定するオプションはないし、 gtid_mode != ON なところにぶら下げようとすると怒られる
I0603 09:05:54.490025     7 mysql_client_connection.cc:148] connected to host: 172.17.0.5, port: 3306
I0603 09:05:54.493810     7 mysql_master_session.cc:137] Connected to host: 172.17.0.5, port: 3306, server_id: 102, server_name:
W0603 09:05:54.495193     7 mysql_master_session.cc:197] master does not support semi sync
I0603 09:05:54.495231     7 mysql_master_session.cc:206] start replicating from 'f9874359-85da-11e9-a9fb-0242ac110003:0-0-4'
I0603 09:05:54.495659     7 mysql_master_session.cc:229] Master session entering main loop
E0603 09:05:54.495913     7 mysql_master_session.cc:296] Failed to read packet: Got error reading packet from server: The replication sender thread cannot start in AUTO_POSITION mode: this server has GTID_MODE = OFF instead of ON.
I0603 09:05:54.495939     7 binlog.cc:675] Connection closed last position binlog file: binlog.000000:1608, gtid: 0-0-4

スレーブをぶら下げてみる

  • こっちももちろん gtid_mode= ON のみのサポート
mysql> CHANGE MASTER TO master_host= '172.17.0.4', master_port= 51005, master_user= 'root' /* Non-GTID */;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 172.17.0.4
                  Master_User: root
                  Master_Port: 51005
..
                Last_IO_Errno: 1593
                Last_IO_Error: The replication receiver thread cannot start because the master has GTID_MODE = ON and this server has GTID_MODE = OFF.
               Last_SQL_Errno: 0
               Last_SQL_Error:
..
  • gtid_mode >= ON_PERMISSIVE にして master_auto_position= 1 で設定すると動く
    • ちゃんとデータも転送されてきた。
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> CHANGE MASTER TO master_auto_position = 1;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.4
                  Master_User: root
                  Master_Port: 51005
..
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
..

MySQL Rippleの吐いたバイナリログファイル

  • よく訓練されたMySQLerにはわかると思うんだけど、フツーのバイナリログとちょっと違う。
    • ちなみにマスターはMySQL 5.7.26でbinlog_format= ROW
$ xxd binlog.000000
0000000: fe62 696e 0000 0000 0f53 b601 00f0 0000  .bin.....S......
0000010: 00f4 0000 0000 0004 0035 2e36 2e30 2d72  .........5.6.0-r
0000020: 6970 706c 6500 0000 0000 0000 0000 0000  ipple...........
..
00000f0: 0413 0400 0000 0000 0fea 0300 0073 0000  .............s..
0000100: 0067 0100 0000 0004 0035 2e37 2e32 362d  .g.......5.7.26-
0000110: 6c6f 6700 0000 0000 0000 0000 0000 0000  log.............
0000120: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000130: 0000 0000 0000 0000 0000 008a dcf4 5c13  ..............\.
0000140: 380d 0008 0012 0004 0404 0412 0000 5f00  8............._.
0000150: 041a 0800 0000 0808 0802 0000 000a 0a0a  ................
0000160: 2a2a 0012 3400 0000 0000 0096 53b6 0100  **..4.......S...
0000170: 2b00 0000 9201 0000 0000 ff00 0000 81dd  +...............
0000180: f45c 78c0 0e77 0815 e466 fa6c bd26 d9f5  .\x..w...f.l.&..
0000190: b607 3200 0000 b929 f7d4 aa18 4bdf 954e  ..2....)....K..N
  • マスターから取り出した生のバイナリログはこちら
$ xxd 935510b1506e-bin.000001
0000000: fe62 696e 8adc f45c 0fea 0300 0077 0000  .bin...\.....w..
0000010: 007b 0000 0001 0004 0035 2e37 2e32 362d  .{.......5.7.26-
0000020: 6c6f 6700 0000 0000 0000 0000 0000 0000  log.............
..
00000f0: 0000 0000 0000 0200 001f 0000 0000 0000  ................
0000100: 0120 00a0 5500 0000 0006 0373 7464 042d  . ..U......std.-
0000110: 002d 002d 000c 0164 3100 6431 0043 5245  .-.-...d1.d1.CRE
0000120: 4154 4520 4441 5441 4241 5345 2064 31e9  ATE DATABASE d1.
0000130: 5801 e9d4 dcf4 5c21 ea03 0000 4100 0000  X.....\!....A...
0000140: 7401 0000 0000 01f9 8743 5985 da11 e9a9  t........CY.....
0000150: fb02 42ac 1100 0302 0000 0000 0000 0002  ..B.............
0000160: 0100 0000 0000 0000 0200 0000 0000 0000  ................
0000170: 69f5 fb70 d4dc f45c 02ea 0300 0070 0000  i..p...\.....p..
0000180: 00e4 0100 0000 0004 0000 0000 0000 0002  ................
0000190: 0000 1f00 0000 0000 0001 2000 a055 0000  .......... ..U..
00001a0: 0000 0603 7374 6404 2d00 2d00 2d00 0c01  ....std.-.-.-...
00001b0: 6431 0064 3100 6372 6561 7465 2074 6162  d1.d1.create tab
00001c0: 6c65 2074 3120 286e 756d 2069 6e74 2c20  le t1 (num int,
00001d0: 7661 6c20 7661 7263 6861 7228 3332 2929  val varchar(32))
..
binlog_format= ROWでもフツーに記録されるはずのDDLが目視できない。 mysqlbinlog で食わせようとしても食えない。
どうやら暗号化されているっぽい。
$ docker run mysql-ripple --help | less
..
    -ripple_encryption_scheme (Encryption scheme used by ripple for local
      binlogs) type: int32 default: 255
..
-ripple-encryption-scheme=0 にすると暗号化されなくなって読めるようになる。
ただし rippled さん、結構バイナリログをバッファリングする(メモリー上にため込んで、 bin.000000 になかなか吐かない)ので、このあたりの動作を試して変だなと思ったらコンテナを止めてみるとフラッシュされたりする。
あと、 -ripple-encryption-scheme=255 で吐かせたバイナリログが残っているとそれに合わせて(?)同じ方式で暗号化し続けるっぽいので、 bin.000000 とかも削除して吸わせなおした方がいいと思われる。試すなら。
バイナリログを暗号化しておけるのは良いとして “MySQL Rippleからなら特に気にせず吸い上げられちゃう” ような気がするので、今のところあんまり期待してはいけないのかも知れない。難読化、くらいのつもりで。