使用 repl_mysql 监控表数据变更
介绍
repl_mysql 在 replication 的基础上增加了更多的功能选项, 基于此可以仅关注指定选项的表的更新. 由于原理同 MySQL 的主从复制, replication 即通过伪造 slave 的方式接收 MySQL master 端的所有更新操作, 不同于真实的 slave, repl_mysql 不需要重新组织接收到的数据到 relay log
日志, 也不用重放 relay log
中的 sql.
注意事项
从上述的实现方式来看, 使用 repl_mysql 的时候需要注意以下几点:
1. 可以在一台主机中使用 repl_mysql 接收多个 MySQL master 的数据, 每个 master 对应一个独立的 repl_mysql 进程.
不过需要注意连接的数量, 避免流量过大引起网络相关的问题;
2. MySQL binlog 为 ROW 格式的情况下会记录所有字段的变更, 单个请求的数据复制会较大, 在更新较多的场景中,
repl_mysql 接收到的流量会较大, 使用 -rowevent 选项时输出的日志也会较多;
3. 过滤选项是在收到 master 所有数据之后建立的规则, 而不是指定哪个表就复制哪个表的数据. 这点同官方的 --replication-do-xx
功能一致, 因为复制协议的局限性, slave 只能全部接收数据, 再在本地按照对应的规则更新数据;
4. 使用 repl_mysql 的过程中不影响 MySQL master 的数据, 仅增加网络传输 binlog 的开销;
5. 目前仅在 MySQL 5.5,5.6, 5.7 环境进行了测试, 未在 gtid 环境下测试. 如果程序运行过程中有异常或者崩溃,
重启进程即可;
repl_mysql 支持的事件类型
repl_mysql 目前支持以下列表中的事件类型:
QUERY_EVENT
TABLE_MAP_EVENT
WRITE_ROWS_EVENTv0
UPDATE_ROWS_EVENTv0
DELETE_ROWS_EVENTv0
WRITE_ROWS_EVENTv1
UPDATE_ROWS_EVENTv1
DELETE_ROWS_EVENTv1
WRITE_ROWS_EVENTv2
UPDATE_ROWS_EVENTv2
DELETE_ROWS_EVENTv2
QUERY_TYPE
为 binlog_format
为 statement
格式的时候所产生的数据更新语句, 其余为 binlog_format
为 row
格式产生的数据类型. 如果需要增加更多类型, 可通过向源文件 repl_mysql.go 中的 map 变量 TypeCheck
增加更多的事件类型, 更多类型见: binlog-event
使用示例:
选项说明
repl_mysql 包含以下选项:
./repl_mysql -h
Usage of ./repl_mysql:
-conf string # 配置文件名, 所有选项参数都可以写到配置文件中;
configure file.
-section string # 配置文件中的 section 信息, 默认为 replication
configure section. (default "replication")
-database string # 如果指定数据库名, 则仅打印该数据库下表的更新信息;
only replicate the database.
-table string # 如果指定表名, 则仅打印该表的更新信息, 和 database 配合使用则表示仅打印指定数据库的指定表的更新信息
only replicate the table, multiple tables are separated by commas.
-host string # master 的主机名;
the mysql master server address. (default "localhost")
-port int # master 的端口;
the mysql master server port. (default 3306)
-user string # 复制用户名
replicate user (default "user_repl")
-pass string # 复制用户的密码;
replicate user password
-binlog string # 需要复制的 master 的 binlog 文件名;
replicate from this binlog file
-pos int # 需要复制的 master 的 binlog 文件的位置;
replicate from this position which in the binlog file
-rowevent # 如果为 row 格式, 是否打印详细的更新信息;
whether print row event change
-serverid int # 唯一的 server id 信息, 默认为 99999.
unique server id in the replication (default 99999)
使用 repl_mysql 的时候, 必须使用 -user
和 -pass
选项, 用户的权限同复制用户的权限, 仅需要 replication slave
即可. 如果使用的时候没有指定 -binlog
和 -pos
选项, 则使用当前 master 最新的 binlog 位置进行主从复制. serverid
默认为 99999, 其值和 master 的 server_id 不同即可.
配置文件示例
下述配置指定 repl_mysql 从 10.0.21.5:3306
实例中的最新的位置开始复制, 仅输出 percona 数据库中的 tttt 表的更新信息:
[replication]
user = user_repl
pass = xxxxxxxx
host = 10.0.21.5
port = 3301
database = percona
table = tri1
使用示例:
./repl_mysql -conf conn.conf -rowevent
......
Time: 2018-10-07T17:02:15
Type: TableMapEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Table: tri1
Binlog: mysql-bin.000035, Logpos: 3177, Eventsize: 53
== UpdateRowsEventV2 ==
TableID: 143
Flags: 1
Column count: 2
Values:
+--
0:10
1:"arsterczxx"
+--
0:10
1:"arsterczxxxxx"
仅输出指定数据库的更新信息
# ./repl_mysql -host 10.0.21.5 -user user_repl -pass xxxxxx -port 3301 -database percona -rowevent -binlog mysql-bin.000035 -pos 3687
......
......
Time: 2018-10-08T10:22:53
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Binlog: mysql-bin.000035, Logpos: 3687, Eventsize: 75
Query: BEGIN
Time: 2018-10-08T10:22:53
Type: TableMapEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Table: test1
Binlog: mysql-bin.000035, Logpos: 3744, Eventsize: 57
== UpdateRowsEventV2 ==
TableID: 197
Flags: 1
Column count: 4
Values:
+--
0:5
1:"flz1"
2:201
3:"2018-09-29 18:16:27"
+--
0:5
1:"flz1"
2:10301
3:"2018-09-29 18:16:27"
Time: 2018-10-08T10:23:22
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Binlog: mysql-bin.000035, Logpos: 3982, Eventsize: 85
Query: BEGIN
Time: 2018-10-08T10:23:22
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Binlog: mysql-bin.000035, Logpos: 4109, Eventsize: 127
Query: update tri1 set name = "arstercz" where id = 10
仅输出指定数据库的指定表的更新信息
输出 percona 库中的 tri1 或 tri2 表的更新信息:
./repl_mysql -host 10.0.21.5 -user user_repl -pass xxxxxx -port 3301 -database percona -table tri1,tri2 -rowevent -binlog mysql-bin.000035 -pos 3687
......
......
Time: 2018-10-08T10:23:22
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Table: tri1
Binlog: mysql-bin.000035, Logpos: 4109, Eventsize: 127
Query: update tri1 set name = "arstercz" where id = 10
仅输出指定表的更新信息
只要表名相同即可, 不限数据库名:
./repl_mysql -host 10.0.21.5 -user user_repl -pass xxxxxx -port 3301 -table tri1 -rowevent -binlog mysql-bin.000035 -pos 3687
......
......
Time: 2018-10-08T10:23:22
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona
Table: tri1
Binlog: mysql-bin.000035, Logpos: 4109, Eventsize: 127
Query: update tri1 set name = "arstercz" where id = 10
Time: 2018-10-08T10:35:43
Type: QueryEvent
Host: 10.0.21.5, Port: 3301
Schema: percona2
Table: tri1
Binlog: mysql-bin.000035, Logpos: 4865, Eventsize: 129
Query: update tri1 set name = "arstercz" where id = 10