介绍

ghostferry是一款开源的以go为开发语言的数据库拆分工具,支持MySQL,MariaDB。对于开发人员友好,不需要十分了解数据库,即可进行数据库拆分。类比MySQL原生的数据库复制filter进行的数据拆分优势在于,不需要数据备份和数据恢复的成本,操作简单,配置指定完成之后,只需要执行一个命令,就可以使用web界面进行数据迁移。

工作原理

类似ghost工具,它在其中部分也是模拟了一个slave接收主库传来的binlog。

  1. gf模拟一个slave线程在source库上接收binlog
  2. gf select源数据库的数据并插入到目标数据库
  3. 完成所有的数据复制,target上应用1中接收的binlog
  4. 等到二进制日志应用到最接近源数据库上的位置停止

限制条件

  • binlog_row_image 必须是full

如果是mariadb 10.0版本的数据库,默认是full,但是没有这个参数,就会导致报错,可以在conf文件中写SkipBinlogRowImageCheck=true 跳过检查。

  • 复制的表有整数的自增的主键

可以在转换阶段用mysqldump先迁移这些表

  • 不能有外键约束
  • ghostferry-copy每次只能拷贝一张表

如果有需要可以将gf作为一个库来构建自己的程序

  • 如果是多节点复制的情况,gf只能用在发生写操作的节点上运行,否则可能导致某些二进制条目丢失

安装

  1. git clone https://github.com/Shopify/ghostferry.git
  2. make copydb
    这步可能会遇到的报错
  • 报错:cannot find package

配置go相关变量
GO111MODULE=on
GOPROXY=?
GOPRIVATE=?

  • 报错:get tcp xxxx io timeout

配置http代理
export http_proxy=?
export https_proxy=?
export no_proxy=?

使用

1、source和target授权后,编辑配置文件
source:

mysql> CREATE USER 'gf'@'%' IDENTIFIED BY '123123';
mysql> GRANT SELECT ON `gf`.* TO 'gf'@'%';
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'gf'@'%';

target:

mysql> CREATE USER 'gf'@'%' IDENTIFIED BY '123123';
mysql> GRANT INSERT, UPDATE, DELETE, CREATE, SELECT ON *.* TO 'gf'@'%';

配置说明:https://godoc.org/github.com/Shopify/ghostferry/copydb#Config

chenlei@dbb1 ~ $ cat conf.json
{
  "Source": {
    "Host": "x.x.x.x",
    "Port": 3601,
    "User": "gf",
    "Pass": "123123",
    "Collation": "utf8mb4_general_ci",
    "Params": {
      "charset": "utf8mb4"
    }
  },

  "Target": {
    "Host": "x.x.x.x",
    "Port": 3506,
    "User": "gf",
    "Pass": "123123",
    "Collation": "utf8mb4_general_ci",
    "Params": {
      "charset": "utf8mb4"
    }
  },

  "Databases": {
    "Whitelist": ["gf"]
  },

  "Tables": {
    "Blacklist": ["schema_migrations"]
  },

  "DumpStateOnSignal": true,
  "VerifierType": "ChecksumTable",

  "SkipBinlogRowImageCheck": true

}

2、ghostferry-copydb -verbose examples/copydb/conf.json 2&>examplerun.log

INFO[0000] table schemas cached tables="[gf.t2 gf.t1]" tag=table_schema_cach
这里就说明了,计划要迁移的表,t1和t2

浏览器打开web界面 host:8000
3、通知业务开始做切换,设置source

mysql> FLUSH TABLES WITH READ LOCK; -- Ensure all writes are done
mysql> SET GLOBAL read_only = ON; -- Sets the database to read only
mysql> FLUSH BINARY LOGS -- Ensure all writes are record in binlog

4、web上 cutover,完成后点击checksum
5、业务切换到新集群
6、查看链接,恢复source

show full processlist;
mysql> UNLOCK TABLES; 
mysql> SET GLOBAL read_only = OFF;

其他功能

  1. 如果觉得在source上消耗太大,可以放在source的从上面做
    参数文件指定这俩
    RunFerryFromReplica
    SourceReplicationMaster
  2. 希望同时进行多个库的拆分的话,可以在参数文件里面指定 “ServerBindAddr”: “0.0.0.0:8003”