一 实验环境
这里演示只同步源端ccc库下的t1,t2表,ddd库下的所有表到两个目标端。
二 实验步骤
2.1 创建专用账号
2.1.1 在源端创建账号
2.1.1.1 登录其中一个mongos节点创建用户
#这里创建一个mongoshake用户,密码是123456
use admin;
db.createUser({user:"mongoshake",pwd:"123456",roles:[{role:"readWrite",db:"admin"}]});
db.grantRolesToUser("mongoshake",[{role:"read",db:"local"}])
db.grantRolesToUser("mongoshake",[{role:"readWrite",db:"mongoshake"}]);
2.1.1.2 在每个分片主节点上创建用户
use admin;
db.createUser({user:"mongoshake",pwd:"123456",roles:[{role:"readWrite",db:"admin"}]});
db.grantRolesToUser("mongoshake",[{role:"read",db:"local"}])
db.grantRolesToUser("mongoshake",[{role:"clusterMonitor",db:"admin"}])
2.1.2 在目标端创建账号
2.1.2.1 登录其中一个mongos节点创建用户
#登录mongos节点,创建一个对所有库都具有读写权限的账号
use admin;
db.createUser({user:"mongoshake",pwd:"123456",roles:[{role:"readWriteAnyDatabase",db:"admin"}]});
2.2 关闭分片集群的balancer
对于sharding的同步,需要关掉balancer进行同步,否则会有时序不一致的问题。
暂不支持move chunk的同时进行同步。
#登录其中一台mongos服务器执行
mongos> sh.getBalancerState()
true
mongos> sh.stopBalancer()
{
"ok" : 1,
"operationTime" : Timestamp(1640785850, 4),
"$clusterTime" : {
"clusterTime" : Timestamp(1640785850, 4),
"signature" : {
"hash" : BinData(0,"1YhPvOALc/9ggQN+E3+GfTDjcKs="),
"keyId" : NumberLong("7046829662332256286")
}
}
}
mongos> sh.getBalancerState()
false
2.3 安装mongoshake
#在所有目标端都安装下mongoshake(若目标端是mongo分片集群,则只在分片集群其中一台服务器上安装即可)
Mongo shake下载地址:
Releases · alibaba/MongoShake · GitHub
cd /opt
tar -xvf mongo-shake-v2.4.16.tar.gz
mv mongo-shake-v2.4.16 mongoshake
cd mongoshake
2.4 配置mongoshake
2.4.1 目标端为单实例的情形
#这里以往目标端192.168.144.252同步为例
vi collector.conf
# 配置源端MongoDB连接串信息,逗号分隔同一个副本集内的节点,分号分隔分片sharding实例
mongo_urls = mongodb://mongoshake:123456@192.168.144.249:27021,192.168.144.250:27021,192.168.144.251:27021;mongodb://mongoshake:123456@192.168.144.249:27022,192.168.144.250:27022,192.168.144.251:27022;mongodb://mongoshake:123456@192.168.144.249:27023,192.168.144.250:27023,192.168.144.251:27023
# 如果源端是分片集群,mongo_cs_url这里需要指定config服务器的地址
mongo_cs_url = mongodb://mongoshake:123456@192.168.144.249:27020,192.168.144.250:27020,192.168.144.251:27020
# 配置mongos的地址,多个mongos地址以逗号分割
mongo_s_url = mongodb://mongoshake:123456@192.168.144.249:27017,192.168.144.250:27017,192.168.144.251:27017
# 配置同步模式为全量+增量模式
sync_mode = all
# 这里配置只同步ccc.t1,ccc.t2,ddd库下的所有表,请结合自己业务情况进行设置,若想同步所有库的所有表,则不需要设置此选项,按默认即可。
filter.namespace.white = ccc.t1;ccc.t2;ddd
#配置目标端地址
tunnel.address = mongodb://mongoshake:123456@192.168.144.252:27017
#设置只同步某些对象,分号分割不同namespace,每个namespace可以是db,也可以是db.collection。
checkpoint.storage.collection = ckpt_default_1
2.4.2 目标端为分片集群的情形
mongo_urls,mongo_cs_url,mongo_s_url,sync_mode,filter.namespace.white等配置同2.4.1。但是tennel.address及checkpoint.storage.collection配置的时候需要注意:
#tennel.address设置为目标端的mongos地址
tunnel.address = mongodb://mongoshake:123456@192.168.144.231:27017,192.168.144.232:27017,192.168.144.233:27017
/*
注意:这里是用逗号分隔的,不是分号,否则会报错:
[2021/12/30 22:33:10 CST] [CRIT] Replayer-1, executor-1, oplog for namespace[ddd.y3] op[i] failed. error type[*mgo.BulkError] error[index[0], msg[command insert requires authentication], dup[false]], logs number[1], firstLog: {"ts":7047498676503052294,"h":8608176140228710902,"v":2,"op":"i","ns":"ddd.y3","o":[{"Name":"_id","Value":"61cdbeb57912ca48bcaaa346"},{"Name":"name","Value":444}],"o2":null}
*/
#注意:不同mongoshake里的checkpoint.storage.collection值应该是唯一的,不能和其他的重复,示例:
checkpoint.storage.collection = ckpt_default_2
2.5 启动mongoshake
sh start.sh collector.conf
#检查是否能看到collector进程
ps -ef |grep collector | grep -v 'grep'
root 27759 1 0 18:52 ? 00:00:00 ./hypervisor --daemon --exec=./collector.linux -conf=collector.conf 1>> collector.linux.output 2>&1
root 27760 27759 0 18:52 ? 00:00:04 ./collector.linux -conf=collector.conf 1>> collector.linux.output 2>&1
/*
对应的停止命令是sh stop.sh mongoshake.pid。
日志文件路径:mongoshake/logs
有时启动mongoshake没起来,日志里也没报错,可用如下方式启动,能在启动页面就能看到有日志输出:
./collector.linux -conf=collector.conf -verbose
*/
2.6 验证数据同步
登录源端mongos,插入一条测试数据:
mongos> use ddd;
switched to db ddd
mongos> db.t1.insert({"id":1,name:"baidd"})
WriteResult({ "nInserted" : 1 })
#在目标端查看数据是否能收到:
> use ddd;
switched to db ddd
> db.t1.find();
{ "_id" : ObjectId("61cb6590a2d018cc73dee5d3"), "id" : 1, "name" : "baidd" }
发现数据过来了。
注意:
本篇文章没有开启ddl同步,若想开启ddl同步,则需要设置filter.ddl_enable = true。
若要设置该参数,还需要设置incr_sync.mongo_fetch_method = change_stream,否则会报错。但是实验的该mongoshake版本只支持部分ddl(库表的建/删,重命名),由于MongoDB本身的限制,对于建/删索引,convertToCapped,applyOps等都不支持。因此,本篇文章并未开启ddl同步。
本篇文章参考了: