目录
引入Maxwell
在数据驱动的业务场景中,经常需要实时捕获MySQL数据库的变更数据(如插入、更新、删除操作),并将这些数据同步到数据仓库、缓存系统、消息队列等下游组件,以支撑数据同步、实时分析、业务监控等需求。
Maxwell是一款开源的MySQL数据变更捕获工具,它能够轻量级地抓取MySQL的binlog日志,解析出数据变更详情,并以结构化的格式输出。
相关概念
Maxwell概念
Maxwell是一个基于MySQL binlog的实时数据同步工具,其功能是解析MySQL的binlog日志,提取其中的数据变更记录(包括INSERT、UPDATE、DELETE操作),并将这些记录以指定的格式(JSON)输出到下游目标(如Kafka、文件等)。
特点:轻量级(无复杂依赖)、低侵入(不影响MySQL主库性能)、支持全量同步与增量同步、输出格式灵活、易于集成。
MySQL主从复制

MySQL主从复制是MySQL提供的一种数据备份与负载均衡方案,原理是:主库(Master)将数据变更记录写入binlog日志,从库(Slave)通过IO线程读取主库的binlog日志并写入本地的relay log(中继日志),再通过SQL线程解析relay log中的日志,将数据变更同步到从库,从而实现主从库数据一致。
组件:
-
binlog日志:主库产生的记录数据变更的日志;
-
IO线程(从库):负责连接主库,读取主库的binlog日志并写入本地relay log;
-
SQL线程(从库):负责解析relay log,执行日志中的SQL语句,同步数据变更;
-
relay log:从库本地存储主库binlog日志的中继文件,避免直接依赖主库binlog。
binlog模式
MySQL的binlog日志有三种记录模式,不同模式的日志内容、用途及性能存在差异:
-
Statement-based(SBR,基于语句模式):记录触发数据变更的SQL语句(如INSERT INTO ...、UPDATE ...)。优点是日志体积小、性能损耗低;缺点是部分SQL语句(如使用NOW()、RAND()等函数的语句)无法保证主从复制一致性,且Maxwell无法精准解析出变更前后的数据。
-
Row-based(RBR,基于行模式):记录每一行数据变更的具体内容(如某行数据更新前的值、更新后的值)。优点是能精准记录数据变更细节,保证主从复制一致性;缺点是日志体积较大,性能损耗相对较高。
-
Mixed(混合模式):默认使用Statement模式,当检测到可能导致主从不一致的SQL语句时,自动切换到Row模式。虽然兼顾了性能和一致性,但对于Maxwell而言,无法保证解析的稳定性,因此不推荐使用。
Tip:Maxwell要求MySQL的binlog必须采用Row-based模式,否则无法正常抓取并解析数据变更详情。
Maxwell工作原理
"模拟MySQL从库",完全遵循MySQL主从复制协议与主库进行交互,从而抓取binlog日志并解析数据变更,具体流程如下:
-
Maxwell启动后,向MySQL主库发送"从库注册"请求,将自己伪装成一个MySQL从库;
-
主库接受注册后,会给Maxwell分配一个唯一的server-id(从库标识,需确保与主库及其他从库不重复);
-
Maxwell通过主从复制协议,向主库请求binlog日志(可指定起始日志文件和起始位置,支持增量同步;也可请求全量日志,支持全量同步);
-
主库将binlog日志通过网络发送给Maxwell;
-
Maxwell解析接收到的binlog日志(由于binlog是二进制格式,需通过解析转换为可读的结构化数据);
-
Maxwell将解析后的结构化数据变更记录,按照配置的格式输出到下游目标。
Tip:由于Maxwell完全遵循主从复制协议,无需在MySQL主库中创建触发器、存储过程等,对主库性能几乎无侵入,且能精准捕获所有数据变更。
Maxwell操作
Maxwell的操作分为两类:增量数据同步(实时抓取新增变更数据)和历史数据全量同步(抓取已有历史数据),两类操作的适用场景、操作方式及数据格式存在差异,具体如下:
增量数据同步
①适用场景
适用于实时抓取MySQL的新增数据变更,如生产环境中实时同步数据到下游系统(如实时数据仓库、缓存更新)。
②操作方式
-
确保MySQL已开启binlog且为Row模式(配置方法见"Maxwell安装配置");
-
配置Maxwell连接MySQL主库的信息(如主库地址、端口、用户名、密码);
-
配置Maxwell的输出目标(如Kafka地址、文件路径等);
-
启动Maxwell,指定起始binlog位置(若不指定,默认从最新的binlog位置开始抓取;也可指定历史binlog文件和位置,从指定点开始增量抓取)。
示例启动命令(输出到控制台):
maxwell --user=mysql用户名 --password=mysql密码 --host=mysql主库地址 --port=mysql端口 --producer=stdout
③数据格式
增量数据同步的输出格式默认为JSON,包含字段如下(不同操作类型的字段略有差异):
-
database:数据变更所属的数据库名;
-
table:数据变更所属的表名;
-
type:操作类型(INSERT/UPDATE/DELETE);
-
ts:数据变更的时间戳(毫秒级);
-
data:变更后的数据(INSERT/UPDATE操作时存在,JSON对象);
-
old:变更前的数据(UPDATE/DELETE操作时存在,JSON对象);
-
server_id:MySQL主库的server-id;
-
binlog_file:对应的binlog日志文件名;
-
binlog_pos:对应的binlog日志位置。
示例(INSERT操作):
{
"database": "test_db",
"table": "user",
"type": "INSERT",
"ts": 1735689600000,
"data": {
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com"
},
"server_id": 1,
"binlog_file": "mysql-bin.000001",
"binlog_pos": 156
}
示例(UPDATE操作):
{
"database": "test_db",
"table": "user",
"type": "UPDATE",
"ts": 1735689720000,
"data": {
"id": 1,
"name": "张三",
"age": 26,
"email": "zhangsan_new@example.com"
},
"old": {
"age": 25,
"email": "zhangsan@example.com"
},
"server_id": 1,
"binlog_file": "mysql-bin.000001",
"binlog_pos": 320
}
历史数据同步
①适用场景
适用于首次部署Maxwell时,同步MySQL中已存在的历史数据(如初始化数据仓库、补全历史数据),全量同步完成后,可自动切换到增量同步模式。
②操作方式
Maxwell通过bootstrap命令实现全量同步,执行SELECT语句全量读取目标表的数据,再封装为结构化格式输出,具体操作:
-
确保Maxwell已配置好MySQL连接信息;
-
执行bootstrap命令,指定需要全量同步的数据库和表;
-
全量同步完成后,Maxwell会记录当前的binlog位置,后续自动从该位置开始增量同步。
示例启动命令(全量同步test_db库的user表,输出到控制台):
maxwell --user=mysql用户名 --password=mysql密码 --host=mysql主库地址 --port=mysql端口 --producer=stdout --bootstrap --database=test_db --table=user
Tip:bootstrap全量同步本质是执行SELECT * FROM 表名,若表数据量较大,可能会对MySQL主库造成一定压力,建议在业务低峰期执行。
③数据格式
全量同步的输出格式与增量同步类似,差异是type字段为"BOOTSTRAP",且无old字段(全量同步是读取当前数据,无变更前状态),具体字段:
-
database:所属数据库名;
-
table:所属表名;
-
type:固定为"BOOTSTRAP";
-
ts:同步时间戳(毫秒级);
-
data:表中的一行数据(JSON对象);
-
bootstrap_server_id:Maxwell的bootstrap标识(默认与Maxwell进程ID相关);
-
binlog_file/binlog_pos:全量同步完成时对应的binlog日志文件和位置(用于后续增量同步)。
示例(全量同步user表数据):
{
"database": "test_db",
"table": "user",
"type": "BOOTSTRAP",
"ts": 1735690000000,
"data": {
"id": 1,
"name": "张三",
"age": 25,
"email": "zhangsan@example.com"
},
"bootstrap_server_id": 1001,
"binlog_file": "mysql-bin.000001",
"binlog_pos": 500
}
Maxwell安装配置
Maxwell的安装配置分为两部分:MySQL环境配置和Maxwell自身配置,具体步骤如下:
MySQL环境配置
Maxwell依赖MySQL的binlog日志,因此必须先配置MySQL开启binlog并设置为Row模式,步骤如下:
①编辑MySQL配置文件
MySQL的配置文件路径:
-
Linux:/etc/my.cnf 或 /etc/mysql/my.cnf;
-
Windows:MySQL安装目录下的 my.ini。
在配置文件的[mysqld]节点下添加以下配置:
# 开启binlog日志
log_bin = mysql-bin
# 指定binlog日志存储路径(可选,默认在MySQL数据目录下)
# log_bin_index = /var/lib/mysql/mysql-bin.index
# 主库的server-id(必须唯一,取值范围:1-2^32-1)
server-id = 1
# 设置binlog模式为Row-based(Maxwell必须要求)
binlog_format = ROW
# 可选:仅记录指定数据库的binlog(减少日志体积,若不指定则记录所有数据库)
# binlog_do_db = test_db
# 可选:忽略指定数据库的binlog
# binlog_ignore_db = mysql
# 可选:binlog日志过期时间(单位:天),避免日志文件过大
expire_logs_days = 7
②重启MySQL服务
配置修改后需重启MySQL服务使配置生效:
Linux重启命令:
# CentOS/RHEL
systemctl restart mysqld
# Ubuntu/Debian
systemctl restart mysql
Windows重启命令:在服务面板中找到"MySQL"服务,右键选择"重启"。
③验证配置是否生效
登录MySQL客户端,执行以下命令验证binlog是否开启及模式是否正确:
-- 查看binlog相关配置
show variables like '%binlog%';
-- 查看server-id配置
show variables like 'server_id';
验证结果:
-
log_bin的值为"ON",表示binlog已开启;
-
binlog_format的值为"ROW",表示模式正确;
-
server_id的值为配置的1(或其他自定义值),表示主库标识已设置。
④创建Maxwell专用MySQL用户并授权
为了安全,建议创建专门的MySQL用户供Maxwell使用,并授予必要的权限(复制权限、查询权限等):
-- 创建用户(用户名:maxwell,密码:maxwell123,可自定义)
CREATE USER 'maxwell'@'%' IDENTIFIED BY 'maxwell123';
-- 授予复制权限(读取binlog日志所需)
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'maxwell'@'%';
-- 授予查询权限(全量同步bootstrap所需)
GRANT SELECT ON *.* TO 'maxwell'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
Tip:若仅需同步指定数据库,可将"*.*"改为"test_db.*"(test_db为目标数据库名),遵循最小权限原则。
Maxwell安装与配置
①下载Maxwell
下载后解压到指定目录(如/usr/local/maxwell):
tar -zxvf maxwell-1.39.0.tar.gz -C /usr/local/ cd /usr/local/ mv maxwell-1.39.0 maxwell
②配置Maxwell
Maxwell支持通过命令行参数配置,也可通过配置文件配置(更方便管理)。在Maxwell安装目录下创建config.properties配置文件:
# MySQL连接配置
maxwell.user=maxwell
maxwell.password=maxwell123
maxwell.host=192.168.1.100(MySQL主库地址)
maxwell.port=3306
# 输出目标配置(以输出到Kafka为例,若输出到控制台可注释)
maxwell.producer=kafka
kafka.bootstrap.servers=192.168.1.101:9092,192.168.1.102:9092(Kafka集群地址)
kafka.topic=maxwell-data(输出到Kafka的主题)
# 其他可选配置
maxwell.server_id=100(Maxwell的标识,需与MySQL主从的server-id不重复)
maxwell.log_level=INFO(日志级别:DEBUG/INFO/WARN/ERROR)
maxwell.output.format=json(输出格式,默认JSON)
常见输出目标配置:
-
输出到控制台:maxwell.producer=stdout;
-
输出到文件:maxwell.producer=file,file.output.path=/data/maxwell/output.log;
-
输出到RabbitMQ:maxwell.producer=rabbitmq,rabbitmq.host=xxx,rabbitmq.port=5672等。
③启动Maxwell
-
通过配置文件启动(推荐)
cd /usr/local/maxwell
nohup bin/maxwell --config config.properties
说明:使用nohup命令可让Maxwell在后台运行,日志默认输出到nohup.out文件。
-
通过命令行参数启动(适合快速测试):
nohup bin/maxwell --user=maxwell --password=maxwell123 --host=192.168.1.100 --producer=stdout
④验证Maxwell是否启动成功
-
查看日志:tail -f nohup.out,若出现"Maxwell started."则表示启动成功;
-
测试数据变更:在MySQL中对目标表执行INSERT/UPDATE/DELETE操作,查看Maxwell的输出目标(控制台/Kafka/文件等)是否有对应的变更数据。
Maxwell流程示例
本示例以"Maxwell抓取MySQL数据变更并输出到Kafka"为例,完整演示从环境准备到数据同步的全流程:
①环境准备
-
MySQL主库:192.168.1.100:3306,已开启binlog(Row模式),创建maxwell用户并授权;
-
Kafka集群:192.168.1.101:9092、192.168.1.102:9092,已创建主题maxwell-data;
-
Maxwell服务器:192.168.1.103,已安装JDK 1.8+,下载并解压Maxwell。
②配置步骤
-
配置MySQL binlog;
-
在Maxwell服务器创建config.properties配置文件:
maxwell.user=maxwell
maxwell.password=maxwell123
maxwell.host=192.168.1.100
maxwell.port=3306
maxwell.producer=kafka
kafka.bootstrap.servers=192.168.1.101:9092,192.168.1.102:9092
kafka.topic=maxwell-data
maxwell.server_id=100
maxwell.log_level=INFO
③启动与测试
-
启动Maxwell:
cd /usr/local/maxwell
nohup bin/maxwell --config config.properties -
查看Maxwell日志,确认启动成功:tail -f nohup.out,出现"Maxwell started."即可;
-
在MySQL中创建测试数据库和表,并插入数据:
CREATE DATABASE test_db;
USE test_db;
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
email VARCHAR(100)
);
-- 插入数据
INSERT INTO user (name, age, email) VALUES ('张三', 25, 'zhangsan@example.com');
-- 更新数据
UPDATE user SET age=26 WHERE id=1;
-- 删除数据
DELETE FROM user WHERE id=1; -
查看Kafka主题中的数据(验证同步结果):
kafka-console-consumer.sh --bootstrap-server 192.168.1.101:9092 --topic maxwell-data --from-beginning
预期结果:Kafka消费者能接收到3条数据,分别对应INSERT、UPDATE、DELETE操作,格式为JSON,包含数据库名、表名、操作类型、变更数据等信息。
④全量同步测试
若需要同步test_db.user表的历史数据,执行以下命令:
nohup bin/maxwell --config config.properties --bootstrap --database=test_db --table=user
查看Kafka主题,会接收到type为"BOOTSTRAP"的全量数据,全量同步完成后,Maxwell自动切换到增量同步模式,后续新增的变更数据会实时同步到Kafka。