MySQL Binlog 增量实时同步工具

License

简介

go-mysql-transfer是一款MySQL数据库实时增量同步工具。

能够监听MySQL二进制日志(Binlog)的变动,将变更内容形成指定格式的消息,实时发送到接收端。从而在数据库和接收端之间形成一个高性能、低延迟的增量数据同步更新管道。

特性

1、简单,不依赖其它组件,一键部署

2、集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ、HTTP API等,无需编写客户端,开箱即用

3、内置丰富的数据解析、消息生成规则、模板语法

4、支持Lua脚本扩展,可处理复杂逻辑

5、集成Prometheus客户端,支持监控告警

6、集成Web Admin监控页面

7、支持高可用集群部署

8、数据同步失败重试

9、支持全量数据初始化

原理

1、将自己伪装为MySQL的Slave监听binlog,获取binlog的变更数据

2、根据规则或者lua脚本解析数据,生成指定格式的消息

3、将生成的消息批量发送给接收端

与同类工具比较

特色 Canal mysql_stream go-mysql-transfer
开发语言 Java Python Golang
高可用 支持 支持 支持
接收端 编码定制 Kafka等(MQ) Redis、MongoDB、Elasticsearch、RabbitMQ、Kafka、RocketMQ、HTTP API
后续支持更多
全量数据初始化 不支持 支持 支持
数据格式 编码定制 Json(固定格式) Json(规则配置)
模板语法
Lua脚本

安装包

二进制安装包

直接下载安装包: 点击下载

源码编译

1、依赖Golang 1.14 及以上版本

2、设置' GO111MODULE=on '

3、拉取源码 ' git clone https://github.com/wj596/go-mysql-transfer.git '

4、进入目录,执行 ' go build '编译

全量数据初始化

go-mysql-transfer -stock

运行

开启MySQL的binlog

#Linux在my.cnf文件
#Windows在my.ini文件
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 go-mysql-transfer 的 slave_id 重复

命令行运行

1、修改app.yml

2、Windows直接运行 go-mysql-transfer.exe

3、Linux执行 nohup go-mysql-transfer &

gitee

如果您的github访问不稳定,可以在码云(gitee)上star项目:go-mysql-transfer 码云(gitee)

使用说明

感谢

更新日志

v1.0.0 bate

  • 9.17 初始化提交bate版本

v1.0.1 release

  • 9.22 release

v1.0.2 release

  • 添加dbOps(数据库操作)、httpOps(http操作)两个Lua模块
  • 修复enum类型字段出现的乱码问题
  • redis接收端增加Sorted Set数据类型支持
  • 修复了近来反馈的bug

v1.0.3 release

  • 添加了Web Admin监控界面
  • 改进了全量数据同步的速度
  • 重构了失败重试机制
  • 功能优化,如:针对MongoDB添加UPSERT操作、针对消息队列添加了update原始数据保留,等等

v1.0.4 release

  • 修复了 -position 命令,binlog 名称验证问题
Comments
  • 同步数据量比较大时报,大概不到100万条记录

    同步数据量比较大时报,大概不到100万条记录

    fatal error: runtime: out of memory

    runtime stack: runtime.throw(0x1a59567, 0x16) D:/dev/golang/root/src/runtime/panic.go:1112 +0x72 runtime.sysMap(0xc070000000, 0x4000000, 0x3022678) D:/dev/golang/root/src/runtime/mem_linux.go:169 +0xc5 runtime.(*mheap).sysAlloc(0x300cf00, 0x400000, 0x2ba00c0, 0x0) D:/dev/golang/root/src/runtime/malloc.go:715 +0x1cd runtime.(*mheap).grow(0x300cf00, 0x1, 0x0) D:/dev/golang/root/src/runtime/mheap.go:1286 +0x11c runtime.(*mheap).allocSpan(0x300cf00, 0x1, 0x7f1943b10e00, 0x3022688, 0x7f1943332a48) D:/dev/golang/root/src/runtime/mheap.go:1124 +0x6a0 runtime.(*mheap).alloc.func1() D:/dev/golang/root/src/runtime/mheap.go:871 +0x64 runtime.systemstack(0x0) D:/dev/golang/root/src/runtime/asm_amd64.s:370 +0x66 runtime.mstart() D:/dev/golang/root/src/runtime/proc.go:1041

    goroutine 64 [running]: runtime.systemstack_switch() D:/dev/golang/root/src/runtime/asm_amd64.s:330 fp=0xc0004f9880 sp=0xc0004f9878 pc=0x462a30 runtime.(*mheap).alloc(0x300cf00, 0x1, 0x10e, 0x0) D:/dev/golang/root/src/runtime/mheap.go:865 +0x81 fp=0xc0004f98d0 sp=0xc0004f9880 pc=0x425651 runtime.(*mcentral).grow(0x301d6d8, 0x0)

  • 通读完源码后有几个疑问希望得到解答

    通读完源码后有几个疑问希望得到解答

    1. 目前多节点部署只是起到了主备的作用?因为备节点是不打开canal的所以可以理解为不工作吗?
    2. 目前对于每一个onRow过来的数据处理都是串行处理,在mysql并发增删改查数量特别大时处理速度是否会存在瓶颈?
    3. 能否提供一个改动方案在同步mysql数据时添加一定量的业务逻辑处理。比如同步某个表数据时需要做一些逻辑运算。

    Thank!

  • docker下无法启动容器

    docker下无法启动容器

    centos7 docker logs go-mysql-transfer 2021-07-08 08:50:23.611934 I | process id: 1 2021-07-08 08:50:23.611969 I | GOMAXPROCS :16 2021-07-08 08:50:23.611973 I | source mysql(localhost:3306) 2021-07-08 08:50:23.611977 I | destination redis(127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002#redis地址,多个用逗号分隔) dial tcp 127.0.0.1:3306: connect: connection refused

    测试了mysql 使用localhost 和127.0.0.1多能进入

  • redis多纬度需求以及过期时间设置需求~

    redis多纬度需求以及过期时间设置需求~

    需求背景

    这样同步redis想必大家都是为了做cache层使用的吧

    过期时间设置

    当前关于同步到redis 在代码中是写死的过期时间为0 实际需求中可能需要按需写入 例如10秒 1天等情况 也需要更新时自动进行续期

    多纬度

    举例: 用户表中有 手机号 微信号 ID 一般业务中 是会把ID全量写入cache 其他纬度 例如手机号 作为一个key 映射到id的key 在redis下就为 user:1 value:一串json字符串 user:telephone:13888888888 value: user:1 user:weid:1234 value:user:1

    当然了这只是redis作为cache同步的需求 其实使用lua脚本也能实现 但是性能掉落一半 属实有点难以接受~

  • 解析后的消息格式再丰富的建议

    解析后的消息格式再丰富的建议

    很不错的工具,有个建议 json格式可以再丰富一下 类似国外的一个工具 maxwell,http://maxwells-daemon.io/ 加上时间戳字段(毫秒级别) 很多时候 一条数据多次update 需要取到最新的一条

    insert

    {
        "database": "test",
        "table": "maxwell",
        "type": "insert",
        "ts": 1449786310,
        "xid": 940752,
        "commit": true,
        "data": { "id":1, "daemon": "Stanislaw Lem" }
      }
    

    update 新增oldkey 这样可以知道变化内容是什么,下游可以做数据的监控过滤等

    {
        "database": "test",
        "table": "maxwell",
        "type": "update",
        "ts": 1449786341,
        "xid": 940786,
        "commit": true,
        "data": {"id":1, "daemon": "Firebus!  Firebus!"},
        "old":  {"daemon": "Stanislaw Lem"}
      }
    
  • 全量同步怎么只同步部分,并且报错这个,是什么原因

    全量同步怎么只同步部分,并且报错这个,是什么原因

    2020-09-21 11:43:11 info source mysql(rm-######.mysql.cn-chengdu.rds.aliyuncs.com:3306) 2020-09-21 11:43:11 info destination redis(192.168.2.240:6379) [2020/09/21 11:43:11] [info] binlogsyncer.go:144 create BinlogSyncer with config {1001 mysql rm-#####.mysql.cn-chengdu.rds.aliyuncs.com 3306 xinhu utf8 false false false UTC false 0 0s 0s 0 false false 0} 2020-09-21 11:43:11 info GOMAXPROCS :16 2020-09-21 11:43:16 error write tcp 192.168.9.27:33456->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:17 error write tcp 192.168.9.27:33458->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:17 error write tcp 192.168.9.27:33460->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:17 error write tcp 192.168.9.27:33462->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:17 error write tcp 192.168.9.27:33464->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:18 error write tcp 192.168.9.27:33466->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:18 error write tcp 192.168.9.27:33472->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:19 error write tcp 192.168.9.27:33474->192.168.2.240:6379: i/o timeout 2020-09-21 11:43:20 info closing transfer [2020/09/21 11:43:20] [info] canal.go:242 closing canal [2020/09/21 11:43:20] [info] binlogsyncer.go:176 syncer is closing... [2020/09/21 11:43:20] [info] binlogsyncer.go:203 syncer is closed

  • ./go-mysql-transfer -stock 运行时报错elastic: Error 503 (Service Unavailable)

    ./go-mysql-transfer -stock 运行时报错elastic: Error 503 (Service Unavailable)

    [19 14:29:59 root@iZbp1i72h4fylprepdgn5nZ /data/go-mysql-transfer]# ./go-mysql-transfer -stock 2021-03-23 14:30:08.290079 I | process id: 7676 2021-03-23 14:30:08.290096 I | GOMAXPROCS :8 2021-03-23 14:30:08.290101 I | source mysql(47.99.188.92:3306) 2021-03-23 14:30:08.290105 I | destination elasticsearch(http://127.0.0.1:9200) 2021-03-23 14:30:38.313107 I | elastic: Error 503 (Service Unavailable) elastic: Error 503 (Service Unavailable) /data/go-mysql-transfer/service/stock_service.go:85:

    大佬:我按照安装说明最后执行全量同步时 提示 elastic: Error 503 (Service Unavailable),请问是什么原因?求指教

  • 请问下这个错误,是什么啊?

    请问下这个错误,是什么啊?

    service/luaengine/actuator.go:24:2: code in directory /root/go/src/github.com/layeh/gopher-json expects import "layeh.com/gopher-json" package go-mysql-transfer imports go-mysql-transfer/metrics imports github.com/prometheus/client_golang/prometheus imports github.com/golang/protobuf/proto imports google.golang.org/protobuf/encoding/prototext imports google.golang.org/protobuf/proto imports google.golang.org/protobuf/encoding/prototext: import cycle not allowed package go-mysql-transfer imports go-mysql-transfer/metrics imports github.com/prometheus/client_golang/prometheus imports github.com/golang/protobuf/proto imports google.golang.org/protobuf/encoding/prototext imports google.golang.org/protobuf/proto imports google.golang.org/protobuf/proto: import cycle not allowed

  • 使用go-mysql-transfer无法将数据发送至rocketmq,另外是否有调试模式可以看到rocketmq发送的消息吗?

    使用go-mysql-transfer无法将数据发送至rocketmq,另外是否有调试模式可以看到rocketmq发送的消息吗?

    采用本地方式运行的rocketmq。 发现go-mysql-transfer的system.log有输出发送rocketmq,但是不清楚是否正确匹配了rocketmqserver,rocketmqserver么有收到消息。 如果采用附件中工程的相同topic等配置,rocketmqserver可以收到数据。 附件是相关配置和源码: image system.log

    image

    image

    image

    image

    image image

    Work.zip

  • 全量同步数据改成协程池 切分主键进行同步

    全量同步数据改成协程池 切分主键进行同步

    首先获取表的最小最大id,根据配置文件的bulk Size参数切分区间,创建$Maxprocs个worker 比如 mysql表最小id为1,最大为100万,bulk Size=5000,Maxprocs=20 会先创建20个worker等待执行任务,根据最小最大id生成下面的子任务 where id>0 and id<=5000 where id>5000 and id<=10000 where id>10000 and id<=15000

    每个worker从taskChan取任务,执行完将任务结果写入resultChan通道 最后主进程汇总任务的结果

    ➜ go-mysql-transfer git:(master) ✗ go run main.go -stock true 2022-12-24 19:24:20.868626 I | process id: 32925 2022-12-24 19:24:20.868650 I | GOMAXPROCS :24 2022-12-24 19:24:20.868653 I | source mysql(127.0.0.1:3306) 2022-12-24 19:24:20.868657 I | destination rabbitmq(amqp://guest@guest@*****:5672/) 2022-12-24 19:24:20.918500 I | bulk size: 10 2022-12-24 19:24:20.918725 I | 开始导出 blog.blog 2022-12-24 19:24:20.918744 I | minSql select min(id) as min_id from blog.blog 2022-12-24 19:24:20.918754 I | maxSql select max(id) as max_id from blog.blog 2022-12-24 19:24:20.919563 I | minId:1,maxId:67 2022-12-24 19:24:20.923962 I | blog.blog 导入数据 10 条 2022-12-24 19:24:20.949198 I | blog.blog 导入数据 9 条 2022-12-24 19:24:20.955680 I | blog.blog 导入数据 9 条 2022-12-24 19:24:20.958201 I | blog.blog 导入数据 8 条 2022-12-24 19:24:20.958359 I | blog.blog 导入数据 7 条 2022-12-24 19:24:20.959305 I | blog.blog 导入数据 7 条 2022-12-24 19:24:20.959734 I | blog.blog 导入数据 10 条 2022-12-24 19:24:20.959745 I | 共耗时 :41(毫秒) 2022-12-24 19:24:20.959749 I | 表:blog.blog 共导入 60条

  • 建议

    建议

    1.程序运行支持命令行参数 --env app.yml支持读取环境变量 一般密码明文不会存储在配置文件,配环境变量较多 实际开发中需要开发/测试和生产环境 dev_app.yml/prod_app.yml env参数可以更灵活 一台机器可以运行不同环境的监听程序 2.新增一个config/examples目录 里面是转换器写入目的地的redis/kafka/mq配置 目前在一个app.yml里面混合在一起,注释和参考值放一起容易出错 放这个目录别人使用的时候可以按需找到自己的配置文件 3.日志输出 涉及带密码的脱敏改为*****

  • 同步到ES时打开web监控,程序启动会报错,关掉就正常。同步到多个不同target时能否在同一app.yml中配置还是要分多个程序运行?

    同步到ES时打开web监控,程序启动会报错,关掉就正常。同步到多个不同target时能否在同一app.yml中配置还是要分多个程序运行?

    将数据同步到ES时,同步全量数据时是正常的,后台启动程序会报错: [bba@MySQL transfer2]# tail -fn 30 nohup.out 2022-08-18 17:14:38.008047 I | process id: 10254 2022-08-18 17:14:38.008113 I | GOMAXPROCS :16 2022-08-18 17:14:38.008121 I | source mysql(127.0.0.1:3306) 2022-08-18 17:14:38.008129 I | destination elasticsearch(http://192.168.4.3:9200) panic: open statics/index.html: no such file or directory

    goroutine 1 [running]: html/template.Must(...) D:/dev/golang/root/src/html/template/template.go:372 github.com/gin-gonic/gin.(*Engine).LoadHTMLFiles(0xc00001b180, 0xc00075e0c0, 0x1, 0x1) D:/dev/golang/workspace/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:204 +0x36e go-mysql-transfer/web.Start(0x0, 0x0) D:/dev/golang/projects/go-mysql-transfer/web/router.go:36 +0x1d6 main.main() D:/dev/golang/projects/go-mysql-transfer/main.go:132 +0x11e 后面把web监控设为false后就能正常运行。 另外,如果想同时把mysql的数据同步部分同步到redis,部分同步到es,能在一个app.yml中配置多个target吗?还是需要运行两个transfer,每个transfer只能同步一个类型的target?

a powerful mysql toolset with Go
a powerful mysql toolset with Go

go-mysql A pure go library to handle MySQL network protocol and replication. Call for Committer/Maintainer Sorry that I have no enough time to maintai

Dec 28, 2022
Sync MySQL data into elasticsearch
Sync MySQL data into elasticsearch

go-mysql-elasticsearch is a service syncing your MySQL data into Elasticsearch automatically. It uses mysqldump to fetch the origin data at first, the

Dec 30, 2022
A high-performance MySQL proxy

kingshard 中文主页 Overview kingshard is a high-performance proxy for MySQL powered by Go. Just like other mysql proxies, you can use it to split the read

Dec 30, 2022
Golang MySql binary log replication listener

Go MySql binary log replication listener Pure Go Implementation of MySQL replication protocol. This allow you to receive event like insert, update, de

Oct 25, 2022
MySQL replication topology management and HA
MySQL replication topology management and HA

orchestrator [Documentation] orchestrator is a MySQL high availability and replication management tool, runs as a service and provides command line ac

Jan 4, 2023
Vitess is a database clustering system for horizontal scaling of MySQL.

Vitess Vitess is a database clustering system for horizontal scaling of MySQL through generalized sharding. By encapsulating shard-routing logic, Vite

Jan 3, 2023
db-recovery is a tool for recovering MySQL data.

db-recovery is a tool for recovering MySQL data. It is used in scenarios where the database has no backup or binlog. It can parse data files and redo/undo logs to recover data.

Nov 17, 2022
一个使 mysql,pgsql 数据库表自动生成 go struct 的工具

db2go 一个使 mysql、pgsql 数据库表自动生成 go struct 的工具 快速使用 将项目放入到GOPATH/src目录下

Nov 25, 2022
🐳 A most popular sql audit platform for mysql
🐳 A most popular sql audit platform for mysql

?? A most popular sql audit platform for mysql

Jan 6, 2023
Dumpling is a fast, easy-to-use tool written by Go for dumping data from the database(MySQL, TiDB...) to local/cloud(S3, GCP...) in multifarious formats(SQL, CSV...).

?? Dumpling Dumpling is a tool and a Go library for creating SQL dump from a MySQL-compatible database. It is intended to replace mysqldump and mydump

Nov 9, 2022
Vitess is a database clustering system for horizontal scaling of MySQL.

Vitess Vitess is a database clustering system for horizontal scaling of MySQL through generalized sharding. By encapsulating shard-routing logic, Vite

Jan 4, 2023
GitHub's Online Schema Migrations for MySQL
GitHub's Online Schema Migrations for MySQL

gh-ost GitHub's online schema migration for MySQL gh-ost is a triggerless online schema migration solution for MySQL. It is testable and provides paus

Jan 4, 2023
Gaea is a mysql proxy, it's developed by xiaomi b2c-dev team.
Gaea is a mysql proxy, it's developed by xiaomi b2c-dev team.

简介 Gaea是小米中国区电商研发部研发的基于mysql协议的数据库中间件,目前在小米商城大陆和海外得到广泛使用,包括订单、社区、活动等多个业务。Gaea支持分库分表、sql路由、读写分离等基本特性,更多详细功能可以参照下面的功能列表。其中分库分表方案兼容了mycat和kingshard两个项目的路

Dec 30, 2022
Bifrost ---- 面向生产环境的 MySQL 同步到Redis,MongoDB,ClickHouse,MySQL等服务的异构中间件
Bifrost ---- 面向生产环境的 MySQL 同步到Redis,MongoDB,ClickHouse,MySQL等服务的异构中间件

Bifrost ---- 面向生产环境的 MySQL 同步到Redis,ClickHouse等服务的异构中间件 English 漫威里的彩虹桥可以将 雷神 送到 阿斯加德 和 地球 而这个 Bifrost 可以将 你 MySQL 里的数据 全量 , 实时的同步到 : Redis MongoDB Cl

Dec 30, 2022
go mysql driver, support distributed transaction

Go-MySQL-Driver A MySQL-Driver for Go's database/sql package Features Requirements Installation Usage DSN (Data Source Name) Password Protocol Address

Jul 23, 2022
A MySQL-compatible relational database with a storage agnostic query engine. Implemented in pure Go.

go-mysql-server go-mysql-server is a SQL engine which parses standard SQL (based on MySQL syntax) and executes queries on data sources of your choice.

Jan 2, 2023
Innotop for MySQL 8 written in Go
Innotop for MySQL 8 written in Go

Innotop Go Innotop for MySQL 8 written in Go Project started to learn Go and doing something useful (I hope). Additionaly the official Innotop written

Dec 27, 2022
Interactive client for PostgreSQL and MySQL
Interactive client for PostgreSQL and MySQL

dblab Interactive client for PostgreSQL and MySQL. Overview dblab is a fast and lightweight interactive terminal based UI application for PostgreSQL a

Jan 8, 2023