DM问题处理总结

案例一

问题描述

通过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实例配置前检查

处理过程

  1. 在asktug上有个帖子,和我的报错一样,我按他这个配置问题依然没有解决,帖子链接详情
  2. 手动执行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
  1. 通过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" 

问题分析

  1. DM task文件添加–no-locks参数不生效的原因:
    mydumper 两种写法,一种是写在最外面,需要在 source-id 下面引用一下,就是我上面的那种写法;另外一种就是直接在 source-id 下面直接写规则。两种写法如下图:
  2. 给用户授权了reload权限,mydumper不成功的原因:
    阿里云rds我们在给用户授权reload权限是可以授权成功,实际没有起作用,只是授权命令执行成功了,该用户还是没有reload权限,

案例二

问题描述

线上有个需求,需要把生产环境Mysql的一个库同步到Tidb集群,我开始按下面操作步骤进行,这个操作步骤只是执行过十几次以上没有任何问题。

  1. 编辑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 
  1. 部署
ansible-playbook deploy.yml --tags=dm-worker -l dm_worker2_20
  1. 启动服务
ansible-playbook start.yml --tags=dm-worker -l dm_worker2_20   
  1. 更新dm-master
ansible-playbook rolling_update.yml --tags=dm-master
  1. 更新监控
ansible-playbook rolling_update_monitor.yml --tags=prometheus
  1. 编写同步任务的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 版本引入

  1. 检查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"
}

处理排查过程

  1. 根据报错提示, "coa-prod"这个数据源不存在,涉及到数据源配置的地方有4个地方,分别是:
  • DM ansible的inventory.ini文件
  • master节点上的配置文件
  • worker节点上的配置文件
  • task的配置文件
  1. 一一排查上面文件里面是否有这个数据源,排查了一遍发都有,说明没问题
  • 查看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"
  1. 排查dm-master、dm-woker的日志也没有发现任务异常或者报错
  2. 问题排查陷入僵局的时候,微信群里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节点目录的相关文件覆盖了

如何解决

  1. 线上已经被覆盖的woker节点恢复
  • 因为只是把配置覆盖了,但是worker没有重启,所以线上之前跑的woker节点没有影响,只需要我们编辑这个节点配置文件把source_id、mysql_host更新回去就行;
  • 把dm-ansible-prod目录inventory.ini文件这个worker节点信息copy到dm-ansible-v1.0.5-prod的inventory.ini添加重新部署即可
  1. 这次新增的worker节点在最新的dm-ansible-v1.0.5-prod的inventory.ini添加重新部署即可
  2. 升级产生的新旧目录共存的这个情况要避免,可以把旧目录备份到一个其他目录,不要放在中控机的工作目录下
3赞

这里的图好像没有显示

1赞

我更新下图片