案例一
问题描述
通过DM同步阿里云的RDS到Tidb,woker节点部署好之后,在这个woker节点上新增task,task运行到dump数据这个环节就报错,报错信息如下:
[2020/07/08 13:49:07.626 +08:00] [ERROR] [mydumper.go:164] ["Couldn't acquire LOCK BINLOG FOR BACKUP, snapshots will not be consistent: Access denied; you need (at least one of) the SUPER privilege(s) for this operation"] [task=it_coa_prod] [unit=dump]
但是阿里云的RDS已经授权DM了REPLICATION SLAVE、REPLICATION CLIENT、RELOAD、SELECT权限了,这个是DM需要的权限,可以参考上游Mysql实例配置前检查
处理过程
- 在asktug上有个帖子,和我的报错一样,我按他这个配置问题依然没有解决,帖子链接详情
- 手动执行mydumer命令备份,发现也报错,备份不成功,报错如下:
[root@db-otter-1-vpvx-prod dm_worker2_18]# ./bin/mydumper --host chehejia-coa1.mysql.rds.aliyuncs.com --port 3306 --user tidb_slave --outputdir ./dumped_data.it_coa_prod --logfile /dev/stderr --verbose 3 --threads 8 --chunk-filesize 64 --skip-tz-utc --tables-list coa.fanqier_document_items,coa.fanqier_document_structures,coa.fanqier_documents --password 'EJMxnu7V8v$rQZ1o'
2020-07-23 08:24:50 [INFO] - Server version reported as: 5.6.16-log
2020-07-23 08:24:50 [INFO] - Connected to a MySQL server
2020-07-23 08:24:50 [INFO] - Using Percona Backup Locks
2020-07-23 08:24:50 [ERROR] - Couldn't acquire LOCK TABLES FOR BACKUP, snapshots will not be consistent: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
2020-07-23 08:24:50 [ERROR] - Couldn't acquire LOCK BINLOG FOR BACKUP, snapshots will not be consistent: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
2020-07-23 08:24:50 [INFO] - TokuDB detected, creating dummy table for CS
2020-07-23 08:24:50 [INFO] - Started dump at: 2020-07-23 08:24:50
- 通过pingcap的工程师贤净指导,在上面帖子的基础上需要在mysql-instances区域把mydumpers的配置引用进来,最终的配置如下:
---
# ----------- 全局配置 -----------
## ********* 基本信息配置 *********
name: it_coa_prod # 任务名称,需要全局唯一
task-mode: all # 任务模式,可设为 "full"、"incremental"、"all"
target-database: # 下游数据库实例配置
host: "tidb-prod.xx.cloud"
port: 3306
user: "sync"
password: "xxxx" # 如果不为空则需经过 dmctl 加密
## ******** 功能配置集 **********
black-white-list: # 上游数据库实例匹配的表的 black & white list 过滤规则集
bw-rule-1: # 黑白名单配置的名称
do-dbs: ["coa"] # 同步哪些库
# ----------- 实例配置 -----------
mysql-instances:
- source-id: "it-coa-prod" # 上游实例或者复制组 ID,参考 `dm-master.toml` 的 `source-id` 配置
black-white-list: "bw-rule-1" # 黑白名单配置名称
mydumper-thread: 8 # mydumper 用于导出数据的线程数量,在 v1.0.2 版本引入
loader-thread: 8 # loader 用于导入数据的线程数量,在 v1.0.2 版本引入
syncer-thread: 8 # syncer 用于同步增量数据的线程数量,在 v1.0.2 版本引入
mydumper-config-name: "global"
mydumpers:
global:
extra-args: "--no-locks"
问题分析
-
DM task文件添加–no-locks参数不生效的原因:
mydumper 两种写法,一种是写在最外面,需要在 source-id 下面引用一下,就是我上面的那种写法;另外一种就是直接在 source-id 下面直接写规则。两种写法如下图:
-
给用户授权了reload权限,mydumper不成功的原因:
阿里云rds我们在给用户授权reload权限是可以授权成功,实际没有起作用,只是授权命令执行成功了,该用户还是没有reload权限,
案例二
问题描述
线上有个需求,需要把生产环境Mysql的一个库同步到Tidb集群,我开始按下面操作步骤进行,这个操作步骤只是执行过十几次以上没有任何问题。
- 编辑DM ansible的inventory.ini文件,添加新的worker信息
#下面dm_worker1_19是现在已经存在的woker节点,dm_worker1_20是这次新加的节点
dm_worker1_19 ansible_host=172.1.2.175 server_id=119source_id="bb-prod" deploy_dir=/chj/app/dm_worker2_17 dm_worker_port=8277 mysql_host=bb.rds.rds.bj.yun.com enable_gtid=true mysql_user=dbarepl mysql_password='x3/F11fQ0oeM6iZ92/V2g==' mysql_port=3306
dm_worker1_20 ansible_host=172.1.2.175 server_id=120 source_id="coa-prod" deploy_dir=/chj/app/dm_worker2_18 dm_worker_port=8278 mysql_host=coa.mysql.rds.yuncs.com enable_gtid=true mysql_user=dbarepl mysql_password='vXNxPOkhlmUim9x' mysql_port=3306
- 部署
ansible-playbook deploy.yml --tags=dm-worker -l dm_worker2_20
- 启动服务
ansible-playbook start.yml --tags=dm-worker -l dm_worker2_20
- 更新dm-master
ansible-playbook rolling_update.yml --tags=dm-master
- 更新监控
ansible-playbook rolling_update_monitor.yml --tags=prometheus
- 编写同步任务的task文件,task/coa_prod.yaml,配置文件内容如下:
---
# ----------- 全局配置 -----------
## ********* 基本信息配置 *********
name: coa_prod # 任务名称,需要全局唯一
task-mode: all # 任务模式,可设为 "full"、"incremental"、"all"
target-database: # 下游数据库实例配置
host: "tidb-prod.xxx.com"
port: 3306
user: "sync"
password: "TiTpE5IXAj+ZBoRw==" # 如果不为空则需经过 dmctl 加密
## ******** 功能配置集 **********
black-white-list: # 上游数据库实例匹配的表的 black & white list 过滤规则集
bw-rule-1: # 黑白名单配置的名称
do-dbs: ["coa"] # 同步哪些库
routes:
instance-coa-rule:
schema-pattern: "coa"
target-schema: "coa"
# ----------- 实例配置 -----------
mysql-instances:
- source-id: "coa-prod" # 上游实例或者复制组 ID,参考 `dm-master.toml` 的 `source-id` 配置
black-white-list: "bw-rule-1" # 黑白名单配置名称
mydumper-thread: 8 # mydumper 用于导出数据的线程数量,在 v1.0.2 版本引入
loader-thread: 8 # loader 用于导入数据的线程数量,在 v1.0.2 版本引入
syncer-thread: 8 # syncer 用于同步增量数据的线程数量,在 v1.0.2 版本引入
- 检查task文件的编写是否正确,报错配置文件里面“coa-prod”这个数据源找不到
» check-task task/coa-prod_yaml
{
"result": false,
"msg": "[code=20031:class=dm-master:scope=internal:level=medium] source coa-prod in deployment configuration not found\"ngithub.com/pingcap/dm/pkg/terror.(*Error).Generate\"n\"t/home/jenkins/agent/workspace/build_dm_master/go/src/github.com/pingcap/dm/pkg/terror/terror.go:232\"ngithub.com/pingcap/dm/dm/config.(*TaskConfig).SubTaskConfigs\"n\"t/home/jenkins/agent/workspace/build_dm_master/go/src/github.com/pingcap/dm/dm/config/task.go:485\"ngithub.com/pingcap/dm/dm/master.(*Server).generateSubTask\"n\"t/home/jenkins/agent/workspace/build_dm_master/go/src/github.com/pingcap/dm/dm/master/server.go:1871\"ngithub.com/pingcap/dm/dm/master.(*Server).CheckTask\"n\"t/home/jenkins/agent/workspace/build_dm_master/go/src/github.com/pingcap/dm/dm/master/server.go:1835\"ngithub.com/pingcap/dm/dm/pb._Master_CheckTask_Handler\"n\"t/home/jenkins/agent/workspace/build_dm_master/go/src/github.com/pingcap/dm/dm/pb/dmmaster.pb.go:2643\"ngoogle.golang.org/grpc.(*Server).processUnaryRPC\"n\"t/go/pkg/mod/google.golang.org/grpc@v1.25.1/server.go:1007\"ngoogle.golang.org/grpc.(*Server).handleStream\"n\"t/go/pkg/mod/google.golang.org/grpc@v1.25.1/server.go:1287\"ngoogle.golang.org/grpc.(*Server).serveStreams.func1.1\"n\"t/go/pkg/mod/google.golang.org/grpc@v1.25.1/server.go:722\"nruntime.goexit\"n\"t/usr/local/go/src/runtime/asm_amd64.s:1357"
}
处理排查过程
- 根据报错提示, "coa-prod"这个数据源不存在,涉及到数据源配置的地方有4个地方,分别是:
- DM ansible的inventory.ini文件
- master节点上的配置文件
- worker节点上的配置文件
- task的配置文件
- 一一排查上面文件里面是否有这个数据源,排查了一遍发都有,说明没问题
- 查看inventory.ini文件
cat inventory.ini|grep "coa-prod"
- 查看dm-master的配置文件
cat conf/dm-master.toml |grep "coa-prod"
- 查看woker节点配置
cat conf/dm-worker.toml |grep ‘"coa-prod"
- 查看task配置文件
cat task/coa_prod.yaml |grep ‘"coa-prod"
-
排查dm-master、dm-woker的日志也没有发现任务异常或者报错
-
问题排查陷入僵局的时候,微信群里PingCAP的同学也一直帮忙一起排查,贤净同学提出了一个疑问,为啥我新增的woker节点的目录里面文件的时间都不是最新的,而是很久之前的时间,我仔细一看确实不对,然后通过dumper生成的全量备份目录,我才意思到这个woker是线上另外一个库的同步任务,也就是说我这次新加的woker目录把线上已经存在的woker节点目录覆盖了
问题原因
为啥新增的worker节点会把线上已经运行的worker节点覆盖呢?根本原因是因为DM升级过版本,我把目录搞混了,在中控机上存在两个DM的ansible目录:dm-ansible-prod和dm-ansible-v1.0.5-prod,在没有新增或者改动woker节点之前,这两个目录的inventory.ini 文件除了dm_version 不一样其他都一样,后续对inventory.ini 的操作应该在dm-ansible-v1.0.5-prod这个里面做,但是升级之后我在dm-ansible-prod里面加过一个woker节点,这次操作是错误的,然后这次添加woker节点是在dm-ansible-v1.0.5-prod这个里面操作的,并且这次worker节点的部署参数除了source_id、mysql_host和上次添加的不一样,其他的参数都一样,所以就把上次部署的woker节点目录的相关文件覆盖了
如何解决
- 线上已经被覆盖的woker节点恢复
- 因为只是把配置覆盖了,但是worker没有重启,所以线上之前跑的woker节点没有影响,只需要我们编辑这个节点配置文件把source_id、mysql_host更新回去就行;
- 把dm-ansible-prod目录inventory.ini文件这个worker节点信息copy到dm-ansible-v1.0.5-prod的inventory.ini添加重新部署即可
- 这次新增的worker节点在最新的dm-ansible-v1.0.5-prod的inventory.ini添加重新部署即可
- 升级产生的新旧目录共存的这个情况要避免,可以把旧目录备份到一个其他目录,不要放在中控机的工作目录下