gcrcman进行备份恢复时报 backup type or content is different from node ... 问题处理方法
1.场景描述
某项目客户准备进行集群数据迁移,迁移方案为源端集群做全备,在目标端搭建集群并把源端集群的备份数据传输的目标集群上,在目标集群执行全量恢复操作进行集群全量数据的迁移。上述过程的迁移验证环境具体如下:
源端集群环境:
- CPU平台:X86
- 操作系统:CentOS Linux release 7.5
- GBase8a集群版本:GBase8a_MPP_Cluster-License-9.5.2.42-129983-redhat7.3-x86_64.tar.bz2
- 集群拓扑:2台服务器,coordinator和data节点混合部署,兼容模式安装
- 服务器IP地址:10.2.6.129,10.2.6.130
目标端集群环境:
- CPU平台:X86
- 操作系统:Kylin Linux Advanced Server release V10 (Tercel) SP1
- GBase8a集群版本:GBase8a_MPP_Cluster-License-9.5.2.42-129983-redhat8-x86_64.tar.bz2
- 集群拓扑:2台服务器,coordinator和data节点混合部署,兼容模式安装
- 服务器IP地址:27.192.143.95,27.192.143.96
2.问题现象
在源端集群进行全量备份后,在目标端进行全量恢复操作时报错: backup type or content is different from node

3.报错排查和处理
检查了目标端集群的gcrcman.log日志,发现日志中有如下信息

对照gcrcman_br_node.py 254行附近代码

传入的指令部分对应代码中的para_cmd,再继续找调用run_cmd函数代码,发现日志中对应的 -s后的一个长串字符,对应了代码中的self.m_node.get_suffix()

进一步查找get_suffix函数定义:

继续查找suffixdump函数定义,在gcrcman_common.py文件中

此处调用了python的pickle模块的dump函数对输入的suffix进行了序列化,并写入dumpBuffer中,并在返回时对序列化的dumpBuffer中的内容进行了base64的加密
在gcrcman_br_node.py中找到初始化suffix结构的部分代码:

可见suffix的内容为根据服务器ip地址对应的node角色进行suffix结构体的初始化,包括节点对应的coordinator节点名称、node节点名称、vcname、distribution信息
具体可以参考集群执行gcadmin时显示的信息,比如如下的一个单节点集群,192.168.56.161这个节点的suffix信息应当包括:
- 此节点的coordinator角色的节点名称:coordinator1
- 此节点的data角色节点名称:node1
- 兼容模式安装时对应的vcname:vcname00001
- 以及此节点对应的distributionID:1

我们对测试环境中目标集群做恢复(recover)操作时gcrcman.log日志中打印出的信息进行base64解码并查看:

打印出 -s参数后用base64编码后的suffix序列化信息如下:
27.192.143.95节点对应如下信息:
echo "KGRwMApTJ25vZGUnCnAxClMnbm9kZTEnCnAyCnNTJ2Nvb3JkaW5hdG9yJwpwMwpTJ2Nvb3JkaW5hdG9yMScKcDQKc1MnZGlzdHJpYnV0aW9uaWRzJwpwNQoobHA2CkkxCmFzUydvd25lcl92Y25hbWUnCnA3ClMndmNuYW1lMDAwMDAxJwpwOApzLg=="|base64 -d

27.192.143.96节点对应如下信息:
echo "KGRwMApTJ25vZGUnCnAxClMnbm9kZTInCnAyCnNTJ2Rpc3RyaWJ1dGlvbmlkcycKcDMKKGxwNApJMQphclMnb3duZXJfdmNuYW1lJwpwNQpTJ3ZjbmFtZTAwMDAwMScKcDYKcy4="|base64 -d

对比27.192.143.95和27.192.143.96两个节点打印出的suffix信息发现,95和96两个节点的集群拓扑并不相同,95对应coordinator1和node1,96对应node2,所以目标集群的集群拓扑是2台服务器1c+2d混合部署架构,而检查源端集群的架构是2台服务器2c+2d混合部署架构,因此从源端集群的备份因集群拓扑结构不同无法在目标集群上进行恢复。
对目标集群进行了unInstall删除操作,并重新安装与源端相同拓扑的集群(2c+2d混合部署)后,再次进行恢复操作,则不再报错。
4.其他注意事项
集群的备份和恢复操作必要条件(前提是在一套集群上进行备份、在另一套集群下进行恢复的操作)如下:
- 目标集群的拓扑架构和源端集群的完全相同:包括相同数量的coordinator节点、相同数量的data节点、相同数量的主分片数和副本分片数;
- 目标集群和源集群的安装路径installPrefix需要完全相同;
- 从源端集群各节点的本地备份目录拷贝到目标集群的本地备份目录时,需要确认节点间的对应关系,对应关系可以从本地备份目录的名称以及目标集群的拓扑中进行对应,比如源端本地备份目录名称为Gcluster_coordinator1_node1对应了备份集群中管理节点coordinator1和计算节点node1所在的节点;
- 目标集群和源集群原则上必须为相同版本,即CPU平台、操作系统版本、数据库版本完全相同,如果需要在不完全相同的情况下进行上述源端备份,目标端恢复的操作需要与gbase技术支持人员进行确认后方可操作;
PS:
本次验证过程中,由于源端集群的操作系统是centos7.5而目标端集群的操作系统版本为kylinv10,如果采用源端集群实例级全备,并在目标端集群进行实例级恢复,会出现目标端集群gclusterd无法启动的问题、
问题原因为,采用实例级备份时,源端集群会备份$GCLUSTER_BASE/server/lib/gbase/plugin 目录下的UDF函数,因C语言编写的UDF函数采用动态链接编译的方式,其生成的.so文件与编译环境的操作系统相关,因此centos7.x操作系统上编译的.so无法在kylinv10上使用,即使用户没有使用UDF API接口编写C语言的UDF函数,plugin目录下还保存了如kerbros认证、全文索引等已经预制的一些plugin函数动态链接库,因此这种情况下不能直接进行实例级的恢复;
可以考虑两种方案:
1)采用库级备份,按库备份源端集群数据库对象,对于用户自己编写的C API的UDF函数,将源码在目标集群上重新编译并注册方式恢复;
2)先将目标集群上的$GCLUSTER_BASE/server/lib/ 目录下的数据备份一份,然后进行目标集群上的实例级恢复,恢复后用备份的数据二次覆盖$GCLUSTER_BASE/server/lib/目录下的内容,然后将用户的UDF函数进行删除,重新编译并注册用户UDF函数。
评论
热门帖子
- 12025-12-01浏览数:182763
- 22023-05-09浏览数:25057
- 42023-09-25浏览数:18525
- 52020-05-11浏览数:17528