1. 总体详细设计
原始文档
## 1. 需求描述
1、在superinsight上集成DRSP的部署和管理能力
superinsight新增一个DRSP页面,该页面中可以查到各个goldendb集群的标签、租户信息,
(1) 页面上展示goldendb集群的DRSP关系,显示源端和目标端goldendb标签、租户名、复制关系是否正常、复制时延等信息
(2) 点击创建DRSP关系按钮,源端和目标端的goldendb标签、租户可在页面上选择,创建页面有下列主要内容
列表框1:源端goldendb标签、租户
列表框2:目标端goldendb标签、租户
config.ini模板下载和上传
(3) 点击卸载DRSP按钮,将源端和目标端的的DRSP关系断开
(4) 点击修改DRSP按钮,可编辑DRSP的config.ini文件,重新上传并生效
2、superinsight的drsp页面能自动加载RDB中已有的DRSP关系进行展示
3、支持在superinsight上进行DRSP的切换,包括计划切换、演练切换、故障切换
## 2.本需求预期实现功能分析
| 条目 | 说明 | 备注 |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| 需求功能描述 | superinsight 支持对GDB drsp 的安装、扩容,展示drsp关系组的列表,支持切换操作:计划切换、演练切换、故障切换,支持停止同步、恢复同步,支持删除drsp。 superinsight通过GDB提供的rest接口对drsp进行操作。 | 总体描述本需求实现的功能 |
| 新增/修改语法/功能说明 | 功能说明见上。 | 新增修改的语法功能,reset接口,界面功能,dbtool命令等,均需要补充 |
| 新增/修改关键字说明 | 无 | 本需求如需新增配置项或者修改关键字,实现控制逻辑; |
| 新增/修改配置项说明 | 无 | 本需求如需新增配置项或者修改配置项,实现控制逻辑,则需要补充 |
| 新增/修改错误码说明 | 无 | 本需求的异常场景如需新增错误,则需要补充 |
| 新增/修改告警说明 | 无 | 本需求如涉及到导致系统不可用的异常,需要告警,补充告警码和告警说明 |
| 新增/修改后台线程说明 | 无 | 通过后台线程实现的功能,需要补充后台线程的运行机制 |
| 升级兼容 | SI是单体,升级无影响。 | 本需求实现后支持只升级管理节点,不升级租户,不影响升级前的功能正常使用 |
| 新增修改模块间交互接口说明 | GDB提供drsp的rest接口。 | 本需求跨模块的交互接口说明,此处需要明确接口的输入和输出,以及异常表现。详细内容由详设补充。 |
| 其它 | 无 | |
### 1 superinsight新增一个DRSP菜单,该菜单实现DRSP的管理功能。
页面展示drsp的 生产--灾备 组 列表。 支持新增、修改、解除、切换操作。
### 2. 创建DRSP
1. 前提: 源租户、 灾备租户已经提前创建好,灾备租户的数据已经恢复。 这里灾备租户可以是多个。
2. 功能说明:先独立安装好多套租户集群,其中一个作为生产集群,其余做灾备集群,在两者之间建立主从数据复制链路,实现生产集群到灾备集群的实时数据同步。
3. 点击“创建DRSP”按钮,源端和灾备端的goldendb标签、租户可在页面上选择,创建页面有下列主要内容,配置好后调用rest接口创建。
1) 选择 多个租户。 DRSP是支持一次创建多个灾备租户的。 提供GDB名称-租户名称 树,可以选多个租户。 选择框支持输入名称模糊搜索。
2) 预置阶段。 此阶段需要做基础配置。 但还没没设置谁是生产,谁是灾备。
a、为每个GDB设置标签,即goldendb_tag,它要求英文,不能中文,不能重复。
SI管理多个GDB,要求GDB标签全局唯一。 但是SI纳管已创建好的drsp,这条要求可能没法满足。 这里只要求由SI创建的drsp时,里面gdb标签全局唯一。
b、自动从GDB的rdb中获取所有zk的ip和端口。 管理节点模式(单机还是多管理),如果是单管理节点,自动获取mds的ip和端口。 自动获取管理节点IA的协议模式和端口。
根据上面获取的信息,生成每个GDB标签的配置参数。其中非自动获取的参数采用默认值。
如果gdb2的c1和c2 是gdb1的c1的灾备库,gdb2这个标签配置在config中只需要配置一次。
注意 这个config主要是对GDB的参数说明,里面涉及租户,只有一个“"cN_priority": ""” 优先级配置,还默认为空。
c、 根据上面内容,生成一个config.ini的内容,展示在页面上,允许用户修改其他部分的内容。
d、将用户配置好的参数加密, 组装好rest接口参数。 接口会将上面配置自动回写入config.ini中。
3) 配置组网。
即支持级联,也支持1:N, 也支持它们的组合。 但是它不能形成闭环,它是有向图。
用图形进行配置。采用鱼骨图的模型,中间的主轴是级联链条,允许竖向新增节点。

组网在 “只读进同步”阶段设置。 根据上面配置好的图,每2个租户之间设置一下谁是源。
4)上面配置好后,开始安装部署,页面显示进度。 进度就按它的4个阶段进行划分。
5) 创建drsp,其实有严格的要求, 不是随便2个租户就能建立这个关系。做在页面上,不了解的人就容易产生误操作。当前也没有对2个租户的校验接口。在点击创建后,先弹个提醒的窗口,说明 搭建DRSP需要满足的前提条件。用户确认后才进入配置界面。
3, 对 已有的 drsp组 进行 扩容 ,扩容灾备租户。
与上面创建drsp步骤流程是一样的。
1) 点扩容按钮, 选drsp组和新的灾备租户。
2)预置阶段。
拿到drsp组的config,a、如果新灾备租户的GDB已经在config中, 则gdb标签属性复用已有的配置,新增一个“"cN_priority": ""” 优先级配置。
b、如果新灾备租户的GDB不在config中,但它已有GDB标签,那就需要将已有的GDB标签属性拿过来,同时新增租户的优先级配置。
c、如果新灾备租户的GDB不在config中,它也没有GDB标签,那就需要配置标签,及它的属性,并加入config中。
这个过程比较复杂,需要考虑能否程序把这个配置文件自动生成出来。
3) 部署阶段。 此步骤是将所有租户信息写入rdb。
4) 服务进只读。 只对新租户进行操作。
5)只读进同步。 对新租户和它的源端进行操作。
4, 停止同步,即将源端和灾备端的的DRSP同步断开。需要校验SI 用户的密码。需要控制权限。
这个就是执行 “同步进只读”,就断开了数据同步。 灾备集群进入只读状态。 不会去卸载已安装的drsp脚本和配置。
删除DRSP:此操作会将备租户的同步复制关系拆开,然后将备租户切为服务模式。 rdb中,它跟源的drsp关系会被删除。
5,修改DRSP,可编辑DRSP的config.ini文件,重新上传并生效。需要校验SI 用户的密码。需要控制权限。
需要通过IA获取到已有的config文件。在它基础上对配置文件进行修改。 然后执行预置操作,**下发给这个DRSP涉及的所有GDB**。
这个需要对config里的配置项进行分类, 很多切换参数应该是通过切换操作进行修改。 其他参数,可以编辑配置下发。
6, 页面展示DRSP组列表。
(1)DRSP关系支持级联,支持1:N星型连接,这种组网关系比较灵活。 不管哪种方式,都可以看成一主多备的一个复制链。 主集群就是生产集群,其他都是灾备集群。
展示:序号、DRSP组ID,组节点数。
(2)组列表支持展开节点查看页,每个节点信息如下。
新列表:
角色,GDB名称,GDB标签,租户ID,租户名称,工作模式、源端标识、 同步状态,同步时延,回放时延 |操作
说明:
序号:查询出来按某种排序规则的顺序编号。
DRSP组ID: drsp自身没有这个ID,SI纳管后,自动给每个drsp组分配一个组ID。 同组的多个复制关系的组ID是相同的。
DRSP链节点数 : 组中DRSP的节点总数。
角色: 主、备、 级联。 生产是整个链条的起始节点,是生产集群。 备是指没有集群指向它的末端节点。 级联是链条中间节点,它是前一段关系的备,是后一段关系的主。
角色加个帮助,说明主、备、级联的含义。
GDB名称:GDB被SI纳管,为区分多套GDB,SI上需要给GDB一个名称。 上面标签的设置,是为了兼容已部署的DRSP环境,部署时没有SI,标签是自己定义。
GDB标签:对应MDS表中goldendb_tag,即一套GDB的名称。
租户ID:就是租户的clusterid。 这里不用集群,是因为集群含义比较广。
租户名称:就是租户的clustername。
工作模式:服务,只读、同步。
源端标识: 如果是灾备节点 ,显示它的源端标识。 标识形式: GDB标签.租户ID (用点号连接)。
同步状态:如果是灾备节点 ,显示同步状态和时延。通过下面命令,获取同步状态。 返回0就是状态正常, 非0就是状态异常。 状态提供下钻,可以弹窗展示命令的详细输出。
7, 切换操作, 提供三种切换操作。
(1) 计划切换
功能说明: 生产集群与灾备集群同步状态正常,将生产与灾备角色进行对调, 生产变灾备,灾备变生产提供服务。
场景说明:
切换前:gdb1.c1处于服务模式,对外提供服务;gdb2.c1处于同步模式,从gdb1.c1同步数据;
切换后:gdb2.c1处于服务模式,对外提供服务;gdb1.c1处于同步模式,从gdb2.c1同步数据。
操作说明:切换操作设置在drsp组的非主节点上。点击切换,选择计划切换,弹出确认窗口,用户确认则执行切换,用户取消则不做操作。
实现说明:如果是2个节点的drsp组,有rest接口,调用rest接口执行操作。
如果是3个以上节点的drsp组,有脚本,没有rest接口,需要开发rest接口。 它会将选中的灾备升为生产,同时自动将余下的节点指向新生产。
操作分多个阶段,展示进度页,每个阶段展示执行结果。
(2)演练切换
功能说明:生产集群与灾备集群同步状态正常,用灾备集群进行业务演练。先将灾备集群的同步断开,然后对业务提供服务。演练结束,对灾备集群数据进行回滚,恢复到演练前状态,再接入源端集群,恢复数据同步。灾备集群对外提供服务期间,请禁止DDL业务,若执行DDL,DDL语句无法回滚。
场景说明:
场景说明
切换前:gdb1.c1处于服务模式,对外提供服务;gdb2.c1处于同步模式,从gdb1.c1同步数据;
切换后:gdb1.c1处于服务模式,对外提供服务;gdb2.c1处于服务模式,供演练使用。
限制:选演练集群只能选末端的灾备集群,不能选级联集群。(防止演练数据顺着同步路径扩散到下级集群)。
操作说明:演练切换包含 演练前切换和演练后切换 2个独立的操作,中间还夹杂着一个演练过程,它们不是一个切换按钮能顺序执行的内容,需要拆分为2个独立的按钮。
按钮1:演练迁出。 在drsp组的备租户(即末端节点)的操作栏,提供“演练迁出”按钮。点击,弹出确认窗口。按用户选择进行操作。
按钮2:演练回迁。正在演练结束后,人工在drsp列表中,找到迁出的租户,它的操作栏提供“演练回迁”按钮。点击,弹出确认窗口。按用户选择进行操作。
实现说明: 执行切换,调用演练切换的rest接口。
执行回切,调用数据回退、重新接入的rest接口。
(3)故障切换
功能说明:当为业务提供服务的生产集群发生故障,可以先将灾备集群转为服务模式,对业务提供服务。然后修复原生产集群,接入新生成集群进行数据同步。
提供选项: 执行RPO=0的故障切换: 是、否。 根据选项,走不同的故障切换流程。
上面配置项提供帮助: RPO=0的故障切换,是指生产发生灾难场景,所有数据库进程宕掉(服务功能不可用),但是生产和灾备之间的网络连通,且生产有可用的一致性副本的数据文件或日志文件,此时可以通过生产的数据文件和日志文件,恢复出集群的状态和交易记录,并能将灾备缺失的数据补齐,实现RPO=0。
3.1) RPO!=0的故障切换
i.场景说明:
切换前:gdb1.c1故障前,gdb1.c1处于服务模式,对外提供服务;gdb2.c1处于同步模式,从gdb1.c1同步数据。gdb1.c1故障后,gdb2.c1同gdb1.c1的同步存在异常。
切换后:gdb1.c1故障;gdb2.c1处于服务模式。
ii.执行阶段说明
1、灾备起服 :faultswitch_1_beforecheck、faultswitch_2_faultswitch, faultswitch_2_faultswitch_aftercheck
2、修复原生产: service_to_readonly, disable_cluster, handle_binlog, handle_rollback, enable_cluster
3、原生产接回新生产: faultswitch_3_sync, faultswitch_4_aftercheck
限制:只能选生产的下级集群。即跟生产直接有同步关系的灾备集群。不能选远端灾备,涉及数据一致性的考量,最近的数据一致性概率高。
iii.操作说明
执行故障切换时,上面过程也不是一个切换按钮能顺序执行的操作,中间原生产故障修复是一个没法确定的过程,需要人工确认。人工确认后再由人工执行接回操作。因此,这个切换要拆分成2个独立的按钮,分开执行。
按钮1:故障升主。 在drsp组的主节点的备租户的操作栏,提供“故障升”按钮。点击,弹出确认窗口。按用户选择进行操作。 灾备集群升为生产集群。 原生产处于故障状态。
按钮2:修复接入。 在drsp组的故障节点(原生产)的操作栏,提供“修复接入”按钮。点击,弹出确认窗口。按用户选择进行操作。
原生产集群故障进行修复。这个不在SI上操作。是否修复人工进行确认。
3.2 ) RPO=0的故障切换
1)场景说明同3.1)
2)执行阶段说明
1、灾备起服:相比上面3.1) 第一步是要更新config.ini,将下面内容增量加到config.ini。 将上述配置文件下发给 选择新生产的灾备集群。
然后切换前检查,退同步。
然后选中的灾备集群恢复数据。
然后执行切换和切换后检查。
提示词:
根据需求澄清文档 + 需求理解文档 + 现有技术框架,形成一遍详设文档。包含:时序图设计、数据库设计、前后端接口设计
理解+修改需求理解文档
根据需求变更点[.......],评审和完善详设文档。
训练学习 && 梳理点:
识别出drsp需要维护的对象 -- 组 和 任务
识别出drsp查询的对象 -- 节点信息
识别出模糊的地方 -- 工作模式,前端父子关系展示
识别出任务系统的关键 -- 底层任务支持重试
输出:
drsp 系统目的通过前后端进行组的创建 和 任务的创建。-- 组 和 任务 由本系统维护
drsp 任务提交后,元数据存在底层drsp系统重。-- 元数据 和 节点信息 不直接由本系统管理,通过定时任务通过rdb数据库中获取并展示。
1. 时序图
1.1 对象梳理
drsp组、drsp节点、config.ini、drsp任务、drsp活动
注:
- drsp的元数据存在rdb中,superInsight 起定时任务从不同的rdb中捞取数据
- 对于实时性要求比较高的,拓扑图的状态,做成实时的查询。
- 当前节点信息获取 依赖于insight openapi,非rdb
/open_api/insight/external/tenant/getDRSPClusterInfo ,
兼容多个版本,需要从insight同步该接口到superInsight。
1.2 drsp组创建时序图
主流程
- 过滤符合状态的租户, 需要满足租户的工作模式为服务+ 租户的role为空 的条件。
- 前端选中源租户 和 目标租户构建drsp的灾备组 【前端调用后端precheck接口】
- 前端根据后端获取自动生成的config.ini模板,进行修改
- 前端点击开始部署任务,任务存入数据库, config.ini 持久化到任务中。
- 通过 预置、部署、服务变只读、只读变同步等4个接口(均依赖config.ini)四个步骤
-- 中间态CREATING, 失败态 FAULT【前端调用后端任务查询接口】 - 若完成则创建新的drsp组,更新数据库 -- ACTIVE【前端调用后端任务查询接口】
特殊情况:
如果先部署drsp,后部署SI,SI需要能读取到已存在的drsp关系,并在列表展示 -- 操作是提供drsp组的纳管 和 信息收集,没有动作。
用户需要填入信息:1)drsp的版本 2)Insighttool 协议 和 端口
所有DRSP操作采用异步任务模式:
1.3 drsp组修改时序图
修改DRSP是指编辑已有DRSP组的config.ini配置文件,重新上传并下发生效。对应origin.md需求5。
- 前端从DRSP组详情页点击"修改配置"按钮
- 前端调用后端接口获取当前config.ini内容,在页面上展示供用户编辑
- 用户修改配置后提交,需输入密码进行二次校验
- 后端校验配置格式 → 持久化新版本到
drsp_config→ 提交异步任务通过IAupdate_all_file下发到该DRSP涉及的所有GDB - 前端轮询任务状态直到完成
注意事项:
- 修改config需要通过IA
update_all_file接口下发到DRSP涉及的所有GDB的所有管理节点 - origin.md要求:需要对config里的配置项进行分类,切换参数应通过切换操作修改,其他参数可编辑下发
- 组内存在 RUNNING 状态任务时拒绝修改,返回
code: 409
1.4 drsp组删除时序图
删除DRSP组将断开所有备租户的同步复制关系,将备租户切为服务模式,清除SI数据库中的DRSP记录。对应origin.md需求4。
- 前端在DRSP组列表页点击"删除"按钮
- 弹出确认窗口,用户输入密码确认
- 后端校验密码 + 校验组内无RUNNING任务 → 更新组状态为
DELETING→ 提交异步删除任务 - 异步任务对每个灾备节点按拓扑反序执行:同步→只读→服务,逐层断开
- 全部执行完毕后,清理SI数据库中的
drsp_group、drsp_node、drsp_edge、drsp_config记录
注意事项:
- 删除顺序:必须按拓扑反序处理(先断末端STANDBY节点,再断CASCADE节点),避免级联节点先断开导致下游节点数据异常
- 每个备节点执行过程:
sync_to_readonly(断开同步,进入只读)→readonly_to_service(只读进服务,恢复读写) - 任一节点的断开操作失败,任务标记为FAILED,已处理的节点不回滚(已断开的节点处于只读/服务模式,不影响使用)
- 删除操作不可逆,删除后如需重建需走创建DRSP流程
- origin.md要求:删除时需在RDB中清除drsp关系
注:
- todo: 删除需要做断开操作吗?还是删除提醒用户还有绑定关系未删除?
1.5 drsp 节点时序图 && 元数据获取
drsp节点获取基于现有的代码逻辑继续完善,元数据存在底层的drsp的数据库中 -- mds.drsp_info。
drsp组创建完成 和 drsp任务下发,节点的数据会在底层组件存储,superInsight不维护节点数据。节点信息通过定时任务从rdb的数据库中获取(mds.drsp_info),一些实时的状态信息通过接口查询获取。
- 遍历drsp 组,获取组下所有的节点。
- 遍历节点,从insight接口 和 rdb 获取需要展示的字段。
- 每个节点一行记录。
新列表:序号、DRSP组ID,组节点数、角色,GDB名称,GDB标签,租户ID,租户名称,工作模式、源端标识、 同步状态,同步时延,回放时延 |操作
说明:
- 主列表展示
- 序号:查询出来按某种排序规则的顺序编号。
- DRSP组ID: drsp自身没有这个ID,SI纳管后,自动给每个drsp组分配一个组ID。 同组的多个复制关系的组ID是相同的。
- DRSP链节点数 : 组中DRSP的节点总数。
- 角色: 主、备、级联。 生产是整个链条的起始节点,是生产集群。备是指没有集群指向它的末端节点。级联是链条中间节点,它是前一段关系的备,是后一段关系的主。角色加个帮助,说明主、备、级联的含义。
- GDB名称:GDB被SI纳管,为区分多套GDB,SI上需要给GDB一个名称。 上面标签的设置,是为了兼容已部署的DRSP环境,部署时没有SI,标签是自己定义。
- GDB标签:对应MDS表中goldendb_tag,即一套GDB的名称。
- 租户ID:就是租户的clusterid。 这里不用集群,是因为集群含义比较广。
- 租户名称:就是租户的clustername。
2)实时查询
- 工作模式:服务,只读、同步。
- 源端标识: 如果是灾备节点 ,显示它的源端标识。 标识形式: GDB标签.租户ID (用点号连接)。
- 同步状态:如果是灾备节点 ,显示同步状态和时延。通过下面命令,获取同步状态。 返回0就是状态正常, 非0就是状态异常。 状态提供下钻,可以弹窗展示命令的详细输出。
1.6 config.ini自动生成规则
模板生成(创建场景)
参考:/home/goldendb/zxmanager/drsp/platform/config/config.ini
对每个选中租户所在的GDB,自动连接RDB获取参数:
| 配置项 | 获取方式 | SQL / 说明 |
|---|---|---|
| zkN_ip / zkN_port | RDB查询 | SELECT device_ip, device_port FROM gdb_device_info WHERE device_type=13 |
| mode | RDB查询 | 查询管理节点数量判断:多管理节点=0,单机=1 |
| mds_ip / mds_port | RDB查询(mode=1时) | SELECT device_ip, device_port FROM gdb_device_info WHERE device_type=6注意:7系列无MDS,留空由用户填写 |
| insight_user | RDB查询 | SELECT apply_user FROM gdb_device_info WHERE device_type=12 |
| insightagent_protocol | 用户手动填写 | http 或 https |
| rest_port | 用户手动填写 | IA端口号 |
| cN_priority | 默认为空 | 每个租户追加优先级配置 |
规则:
- 同一GDB下多个租户只生成一个GDB标签配置段
- SI创建的DRSP,要求GDB标签全局唯一(RDB导入的不强制)
- 非自动获取的参数采用默认值
扩容场景
| 场景 | 处理逻辑 |
|---|---|
| 新租户GDB已在config中 | 复用已有GDB标签配置,仅新增 cN_priority |
| 新租户GDB不在config但已有标签 | 导入已有标签属性 + 新增租户优先级 |
| 新租户GDB不在config且无标签 | 新配标签及全部属性,加入config |
用户可编辑项
| 字段 | 是否必填 | 说明 |
|---|---|---|
| insightagent_protocol | 是 | http 或 https |
| rest_port | 是 | IA端口号 |
| cN_priority | 否 | 租户优先级,默认为空 |
| 其他参数 | 否 | 允许用户在生成的模板上自由编辑 |
1.7 drsp 任务时序图
任务表达
![[drspDeploy.jpg]]
![[drspFaultNorbSwitch.jpg]]
![[drspFaultSimuSwitch.jpg]]
![[drspFaultSwitch.jpg]]
![[drspPlanSwitch.jpg]]
![[drspReadonlyToService.jpg]]
![[drspReadonlyToSync.jpg]]
![[drspServiceToReadonly.jpg]]
![[drspSyncToReadOnly.jpg]]
版本控制
通过drsp的用户组版本,映射不同的xml文件,实现版本控制。
注:第一期版本由用户填入drsp版本,后续根据superInsight 的适配需求做成根据godlendb版本自动获取drsp版本。
任务重试
接口需要支持当前阶段传入,整个流程支持从中间阶段继续执行。
注:todo 需要底层组件支持。
2. 数据结构
2.1 drsp_group(DRSP组表)
| 字段名 | 类型 | 索引 | 允许空 | 默认值 | 备注 |
|---|---|---|---|---|---|
| drsp_group_id | VARCHAR(64) | PK | NO | - | DRSP组唯一ID,SI分配(UUID或雪花算法) |
| node_count | INT | - | NO | 0 | 组内节点总数 |
| status | VARCHAR(32) | IDX | NO | 'CREATING' | CREATING / ACTIVE / SWITCHING / FAULT / DELETING |
| drsp_version | VARCHAR(16) | - | YES | 'v1' | 当前使用的XML流程版本 |
| source_type | VARCHAR(32) | - | NO | 'SI_CREATED' | SI_CREATED=SI创建, RDB_IMPORTED=从RDB导入 |
| cluster_list | TEXT | - | NO | 租户列表 | |
| cluster_name_list | TEXT | - | NO | 'config.ini' | 租户名列表 |
| created_at | DATETIME | - | NO | CURRENT_TIMESTAMP | 创建时间 |
| updated_at | DATETIME | - | NO | CURRENT_TIMESTAMP | 更新时间(ON UPDATE) |
| created_by | VARCHAR(64) | - | NO | - | 创建人(操作审计) |
2.2 drsp_node(DRSP节点表)
| 字段名 | 类型 | 索引 | 允许空 | 默认值 | 备注 |
|---|---|---|---|---|---|
| id | BIGINT | PK AUTO_INCREMENT | NO | - | 自增主键 |
| drsp_group_id | VARCHAR(64) | IDX, FK | NO | - | 所属DRSP组 |
| product_id | INT | IDX | NO | - | GDB产品ID |
| gdb_name | VARCHAR(128) | - | YES | - | GDB显示名称(SI纳管名称) |
| gdb_tag | VARCHAR(128) | IDX | NO | - | GDB标签(goldendb_tag) |
| cluster_id | INT | IDX | NO | - | 租户ID(即clusterid) |
| cluster_name | VARCHAR(128) | - | YES | - | 租户名称(即clustername) |
| role | VARCHAR(16) | IDX | NO | - | PRIMARY / STANDBY / CASCADE |
| work_mode | VARCHAR(16) | IDX | NO | 'SERVICE' | SERVICE=服务 / READONLY=只读 / SYNC=同步 |
| source_tag | VARCHAR(256) | - | YES | NULL | 源端标识,格式: GDB标签.租户ID(仅灾备节点有值) |
| sync_status | VARCHAR(16) | - | YES | NULL | NORMAL / ABNORMAL(仅灾备节点有值) |
| sync_delay | INT | - | YES | NULL | 同步时延(秒),仅灾备节点有值 |
| relay_delay | INT | - | YES | NULL | 回放时延(秒),仅灾备节点有值 |
| ia_protocal | VARCHAR(64) | - | YES | NULL | IA请求地址(建议固定灾备管理节点) |
| ia_port | VARCHAR(64) | - | YES | NULL | IA请求端口(建议固定灾备管理节点) |
| created_at | DATETIME | - | NO | CURRENT_TIMESTAMP | |
| updated_at | DATETIME | - | NO | CURRENT_TIMESTAMP |
注:
- 当前接口来自insight,insight接口返合
- 更多信息来自rdb
角色 自动生成
工作模式 mds.work_model
源端标识 remote_goldendb_tag.remote_cluster_id
同步状态 执行dbtool命令
同步时延 参考insight
回放时延 参考insight
2.2 drsp_config(DRSP配置历史表)
| 字段名 | 类型 | 索引 | 允许空 | 默认值 | 备注 |
|---|---|---|---|---|---|
| id | BIGINT | PK AUTO_INCREMENT | NO | - | |
| drsp_group_id | VARCHAR(64) | IDX, FK | NO | - | 所属DRSP组 |
| version | INT | - | NO | 1 | 配置版本号,每次修改+1 |
| config_content | TEXT | - | NO | - | 加密后的config.ini内容 |
| config_plain | TEXT | - | YES | NULL | 仅调试环境保留原文 |
| change_reason | VARCHAR(256) | - | YES | NULL | 变更原因 |
| operator | VARCHAR(64) | - | YES | - | 操作人 |
| created_at | DATETIME | - | NO | CURRENT_TIMESTAMP |
2.3 drsp_task(DRSP任务记录表)
| 字段名 | 类型 | 索引 | 允许空 | 默认值 | 备注 |
|---|---|---|---|---|---|
| id | BIGINT | PK AUTO_INCREMENT | NO | - | |
| drsp_group_id | VARCHAR(64) | IDX, FK | NO | - | 所属DRSP组 |
| task_id | VARCHAR(64) | UNI | NO | - | TaskEngine分配的任务ID |
| action | VARCHAR(32) | IDX | NO | - | 动作类型枚举(见taskName映射表) |
| xml_version | VARCHAR(16) | - | YES | 'v1' | 使用的XML版本 |
| status | VARCHAR(16) | IDX | NO | 'PENDING' | PENDING / RUNNING / COMPLETED / FAILED |
| input_params | TEXT | - | YES | - | 输入参数JSON |
| result | TEXT | - | YES | - | 执行结果JSON |
| error_message | TEXT | - | YES | NULL | 失败时的错误信息 |
| operator | VARCHAR(64) | - | YES | - | 操作人 |
| retry_count | INT | - | YES | 0 | 已重试次数 |
| max_retries | INT | - | YES | 3 | 最大重试次数 |
| created_at | DATETIME | IDX | NO | CURRENT_TIMESTAMP | |
| updated_at | DATETIME | - | NO | CURRENT_TIMESTAMP |
2.4 drsp_activity(DRSP活动记录表)
| 字段名 | 类型 | 索引 | 允许空 | 默认值 | 备注 |
|---|---|---|---|---|---|
| id | BIGINT | PK AUTO_INCREMENT | NO | - | |
| task_id | VARCHAR(64) | IDX | NO | - | 所属任务ID |
| element_name | VARCHAR(128) | - | NO | - | XML中的节点Name,如 drspFaultSwitchBeforeCheck |
| element_type | VARCHAR(64) | - | NO | - | 节点类型: START_EVENT / END_EVENT / SERVICE_TASK / SCRIPT_TASK / EXCLUSIVE_GATEWAY / PARALLEL_GATEWAY |
| state | VARCHAR(16) | IDX | NO | 'PENDING' | PENDING / RUNNING / COMPLETED / FAILED |
| execution_id | VARCHAR(64) | IDX | YES | NULL | 关联Execution ID |
| parent_execution_id | VARCHAR(64) | - | YES | NULL | 父Execution ID |
| result | TEXT | - | YES | NULL | 执行结果JSON |
| created_at | DATETIME | - | NO | CURRENT_TIMESTAMP | |
| completed_at | DATETIME | - | YES | NULL | 完成时间 |
3. 接口定义
3.1 接口总览
| 方法 | 路径 | 说明 | 认证/权限 | 备注 | 人天 |
|---|---|---|---|---|---|
| GET | /api/dbaas/drsp/tenants/available |
获取可选租户列表(树形) | 登录态 | 支持模糊搜索 | 2 |
| POST | /api/dbaas/drsp/config/create/template |
新建场景生成config.ini模板 | 登录态 | 返回base64 | 1 |
| POST | /api/dbaas/drsp/config/expand/template |
扩容场景生成config.ini模板 | 登录态 | 返回base64 | 0.5 |
| POST | /api/dbaas/drsp/config/modify |
修改config.ini | 登录态 + 密码校验 | 异步任务(需IA下发) | 0.5 |
| GET | /api/dbaas/drsp/groups/{groupId}/config |
获取当前config配置 | 登录态 | 含版本历史 | 0.5 |
| POST | /api/dbaas/drsp/precheck |
创建前提条件校验 | 登录态 | 新增 | 1.5 |
| POST | /api/dbaas/drsp/groups/create |
创建DRSP组 | 登录态 | 异步任务 | 2 |
| GET | /api/dbaas/drsp/groups |
查询DRSP组列表 | 登录态 | 分页 | 1 |
| GET | /api/dbaas/drsp/groups/{groupId} |
查询DRSP组详情 和 指标模式搜索 | 登录态 | 2 | |
| POST | /api/dbaas/drsp/groups/{groupId}/expand |
扩容灾备租户 | 登录态 | 异步任务 | 1 |
| DELETE | /api/dbaas/drsp/groups/{groupId} |
删除DRSP组 | 登录态 + 密码校验 | 异步任务 | 3 |
| POST | /api/dbaas/drsp/groups/import |
从RDB导入已有DRSP关系 | 登录态 | 新增 | 1 |
| POST | /api/dbaas/drsp/tasks |
执行DRSP操作(统一入口) | 登录态 + 条件密码校验 | 异步任务 | 12 |
| GET | /api/dbaas/drsp/tasks/{taskId} |
查询任务执行状态 和 进度列表 | 登录态 | 1 | |
| GET | /api/dbaas/drsp/nodes/{nodeId}/sync-status |
查询节点同步状态详情 | 登录态 | 新增,下钻弹窗用 | 2 |
| 联调测试 | 14天 | ||||
| 统计 | 45天 | ||||
修订说明:
- 合并原
groups/create和groups/deploy为POST /groups- 任务状态查询统一为
GET方法- 任务操作路径改为
/tasks(复数,RESTful 规范)- 新增3个接口:precheck、import、sync-status
3.2 获取可选租户列表
路径:GET /api/dbaas/drsp/tenants/available
功能:返回SI纳管的所有GDB及其租户的树形结构,供创建/扩容时在前端选择。支持按名称模糊搜索。
请求参数(Query):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| keyword | String | 否 | 模糊搜索关键词,匹配GDB名称或租户名称 |
| excludeGroupId | String | 否 | 排除已加入指定DRSP组的租户(扩容场景用) |
响应体:
{
"code": 200,
"message": "success",
"data": [
{
"productId": 1,
"gdbName": "GDB生产集群",
"gdbTag": "gdb_prod",
"tenants": [
{
"clusterId": 101,
"clusterName": "tenant_a",
"workMode": "SERVICE",
"inDrspGroup": null
},
{
"clusterId": 102,
"clusterName": "tenant_b",
"workMode": "READONLY",
"inDrspGroup": "drsp_group_002"
}
]
},
{
"productId": 2,
"gdbName": "GDB灾备集群",
"gdbTag": null,
"tenants": [
{
"clusterId": 201,
"clusterName": "tenant_dr1",
"workMode": "SYNC",
"inDrspGroup": null
}
]
}
]
}
注意事项:
gdbTag可能为null(尚未配置DRSP标签的GDB)inDrspGroup标识该租户是否已加入其他DRSP组,前端据此做选择限制提示- 数据来源:GDB管理库中的租户列表 +
drsp_node表关联查询
3.3 创建前提条件校验(新增)
路径:POST /api/dbaas/drsp/precheck
功能:在用户进入创建配置界面之前,校验所选租户是否满足搭建DRSP的前提条件,并返回校验结果和前提条件说明。对应origin.md要求:"在点击创建后,先弹个提醒的窗口,说明搭建DRSP需要满足的前提条件"。
请求体:
{
"tenants": [
{"productId": 1, "clusterId": 101},
{"productId": 2, "clusterId": 201}
]
}
响应体:
{
"code": 200,
"message": "success",
"data": {
"passed": false,
"prerequisites": [
"源租户和灾备租户需提前创建完成",
"灾备租户的数据需要已从源端恢复",
"源端和灾备端的GDB版本需兼容(建议相同大版本号)",
"管理节点间网络互通",
"IA服务已正常运行"
],
"checkResults": [
{"item": "租户状态检查", "passed": true, "detail": "所有租户状态正常"},
{"item": "GDB版本兼容性", "passed": true, "detail": "gdb_prod=v6.1.3, gdb_dr1=v6.1.3"},
{"item": "租户DRSP冲突检查", "passed": false, "detail": "租户101已加入DRSP组drsp_group_002"},
{"item": "IA连通性检查", "passed": true, "detail": "所有管理节点IA可达"}
]
}
}
3.4 新建,生成config.ini模板
路径:POST /api/dbaas/drsp/config/create/template
功能:根据传入的GDB标签及连接信息,自动从RDB获取参数,生成DRSP的config.ini模板,返回base64编码内容。
请求体:
{
"gdbConfigs": [
{
"gdbTag": "gdb_prod",
"productId": 1,
"rdbInfo": {
"ip": "10.10.10.10",
"port": 3306
}
},
{
"gdbTag": "gdb_dr1",
"productId": 2,
"rdbInfo": {
"ip": "10.10.10.20",
"port": 3306
}
}
]
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| groupId | String | 否 | 创建场景不传(组尚不存在),扩容/修改场景传入 |
| gdbConfigs | Array | 是 | GDB配置列表 |
| gdbConfigs[].gdbTag | String | 是 | GDB标签(英文,不能中文,不能重复) |
| gdbConfigs[].productId | Integer | 是 | GDB产品ID |
| gdbConfigs[].rdbInfo.ip | String | 是 | RDB连接地址 |
| gdbConfigs[].rdbInfo.port | Integer | 是 | RDB连接端口 |
响应体:
{
"code": 200,
"message": "success",
"data": {
"configBase64": "W2dkYjNdCnp......",
"autoFilledFields": {
"gdb_prod": {
"zk1_ip": "10.10.10.10",
"zk1_port": "32181",
"zk2_ip": "10.10.10.11",
"zk2_port": "32181",
"mode": "0",
"insight_user": "insight"
},
"gdb_dr1": {
"zk1_ip": "10.10.10.20",
"zk1_port": "32181",
"mode": "1",
"mds_ip": "10.10.10.20",
"mds_port": "6406",
"insight_user": "insight"
}
},
"manualRequiredFields": ["insightagent_protocol", "rest_port"]
}
}
修订说明:
- 返回
autoFilledFields和manualRequiredFields,帮助前端标识哪些字段可编辑、哪些需要用户填写,todo 待讨论是否需要。
3.5 扩容,生成config.ini模板
路径:POST /api/dbaas/drsp/config/expand/template
功能:根据已有DRSP组的config和新增GDB信息,自动合并生成扩容后的config.ini。
请求体:
{
"groupId": "drsp-xxxx-xxxx",
"gdbConfigs": [
{
"gdbTag": "gdb_dr4",
"productId": 4,
"rdbInfo": {
"ip": "10.10.10.40",
"port": 3306
}
}
]
}
响应体:
{
"code": 200,
"message": "success",
"data": {
"configBase64": "W2dkYjNdCnp......"
}
}
3.6 修改config.ini配置
路径:POST /api/dbaas/drsp/config/modify
功能:更新指定DRSP组的config.ini配置并下发到所有相关GDB。
请求体:
{
"groupId": "drsp-xxxx-xxxx",
"configBase64": "W2dkYjNdCnp......",
"password": "******",
"changeReason": "更新IA协议为https",
"validateOnly": false
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| groupId | String | 是 | DRSP组唯一标识 |
| configBase64 | String | 是 | base64编码后的完整config.ini内容 |
| password | String | 是 | 当前用户密码,二次校验 |
| changeReason | String | 否 | 变更原因,记入配置历史 |
| validateOnly | Boolean | 否 | 默认false,为true时仅校验不执行 |
响应体:
{
"code": 200,
"message": "success",
"data": {
"configBase64": "W2dkYjNdCnp......",
"version": 4,
"taskId": "task_1712492400001_0020"
}
}
修订说明:
- 新增
password必填字段,对应origin.md"修改DRSP需要校验SI用户的密码"- 修改config后需通过IA的
update_all_file接口下发到DRSP涉及的所有GDB,因此返回taskId供前端轮询下发进度- 全量覆盖,不支持部分修改(避免配置不一致)
- 校验:ini格式校验、cN_priority格式校验、GDB标签合法性
- 组内存在 RUNNING 状态任务时拒绝修改,返回
code: 409
3.7 查看DRSP配置
路径:GET /api/dbaas/drsp/groups/{groupId}/config
请求参数:
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| groupId | Path | String | 是 | DRSP组ID |
| includeHistory | Query | Boolean | 否 | 是否返回版本历史,默认false |
| maxHistorySize | Query | Integer | 否 | 最大历史版本数,默认10 |
响应体:
{
"code": 200,
"message": "success",
"data": {
"groupId": "drsp_group_001",
"currentVersion": 3,
"configBase64": "W2dkYjNdCnprMV9pcD0xMC4x......",
"lastModifiedAt": "2026-04-09T15:30:00Z",
"lastModifiedBy": "admin",
"changeReason": "Updated IA protocol due to server upgrade",
"versionHistory": [
{
"version": 3,
"createdAt": "2026-04-09T15:30:00Z",
"createdBy": "admin",
"changeReason": "Updated IA protocol"
},
{
"version": 2,
"createdAt": "2026-04-05T10:00:00Z",
"createdBy": "admin",
"changeReason": "Initial setup"
}
]
}
}
修订说明:
todo 第一版只允许查看历史修改信息,不允许查询和使用历史config.ini
3.8 创建DRSP组
路径:POST /api/dbaas/drsp/groups/create
功能:创建DRSP灾备关系。前端选择源端和灾备租户、配置组网拓扑(鱼骨图)、编辑config.ini后提交。后端执行4阶段部署流程:prepareDrsp → deployDrsp → drspServiceToReadonly → drspReadonlyToSync。
请求体:
{
"version": "v1",
"tenants": [
{"refId": "gdb_prod.101", "productId": 1, "clusterId": 101, "clusterName": "tenant_a"},
{"refId": "gdb_dr1.201", "productId": 2, "clusterId": 201, "clusterName": "tenant_dr1"},
{"refId": "gdb_dr2.301", "productId": 3, "clusterId": 301, "clusterName": "tenant_dr2"}
],
"edges": [
{"sourceRef": "gdb_prod.101", "targetRef": "gdb_dr1.201"},
{"sourceRef": "gdb_prod.101", "targetRef": "gdb_dr2.301"}
],
"gdbTags": {
"1": "gdb_prod",
"2": "gdb_dr1",
"3": "gdb_dr2"
},
"configBase64": "W2dkYjNdCnp......",
"iaHostIp": "10.10.10.20",
"iaHostPort": "8804"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| version | String | 否 | XML流程版本,默认使用当前版本 |
| tenants | Array | 是 | 参与DRSP的所有租户(含源+灾备),refId格式: {gdbTag}.{clusterId} |
| edges | Array | 是 | 有向边列表,定义复制关系方向(source→target = 主→备) |
| gdbTags | Map<String, String> | 是 | key=productId, value=goldendb_tag标签 |
| configBase64 | String | 是 | 用户确认后的config.ini内容(base64编码) |
| iaHostIp | String | 是 | IA接口请求地址(建议填灾备管理节点IP) |
| iaHostPort | String | 是 | IA接口请求端口 |
响应:HTTP 202 Accepted
{
"code": 200,
"message": "success",
"data": {
"drspGroupId": "drsp_group_001",
"taskId": "task_1712492400001_0001"
}
}
后端处理逻辑:
- 校验:
- GDB标签全局唯一性(SI创建范围内)
- 拓扑无闭环(Kahn拓扑排序验证DAG)
- 租户可用性检查
- 角色推导:
- 入度为0 → PRIMARY
- 出度为0 → STANDBY
- 其他 → CASCADE
- 数据持久化:在事务中写入
drsp_group、drsp_node、drsp_edge、drsp_config四张表,初始状态CREATING - 提交任务:TaskEngine提交
processId=drspDeploy,任务完成后更新组状态为ACTIVE
IA接口调用映射(对应"DRSP部署切换api说明.md" §1.4):
| 阶段 | TaskType | Param模板 |
|---|---|---|
| 预置 | prepare_drsp |
--cfg_file {cfgFile} --base64_json_info {BASE64_JSON_INFO} --gtm_upload_period {period} |
| 部署 | deploy_drsp |
--config_file {cfgFile} --system_info {sourceTag}.{sourceCid} {targetTag}.{targetCid} |
| 服务进只读 | service_to_readonly |
--cfg_file {cfgFile} --section {targetTag} --clusterid {targetCid} |
| 只读进同步 | readonly_to_sync |
--cfg_file {cfgFile} --section {targetTag} --clusterid {targetCid} --sourceclusterid {sourceCid} --sourcetag {sourceTag} |
注意:对于1:N或级联拓扑,"服务进只读"和"只读进同步"阶段需对每条边的目标节点分别执行。
3.9 查询DRSP组列表
路径:GET /api/dbaas/drsp/groups
功能:分页查询所有DRSP组列表。对应origin.md列表展示需求:每个节点一行记录。
请求参数(Query):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| page | Integer | 否 | 页码,默认1 |
| pageSize | Integer | 否 | 每页条数,默认20 |
| keyword | String | 否 | 搜索关键词(匹配组ID/GDB名称/租户名称) |
| status | String | 否 | 按组状态筛选 |
| sortField | String | 否 | 排序字段:drspGroupId / role / gdbTag |
| sort | String | 否 | ASC / DESC |
响应体:
每个节点一行记录,展示origin.md定义的全部列:
{
"code": 200,
"message": "success",
"data": {
"total": 50,
"page": 1,
"pageSize": 20,
"list": [
{
"rowNo": 1,
"drspGroupId": "drsp_group_001",
"groupStatus": "ACTIVE",
"nodeCount": 3,
"drsp_version": "2.1",
"status": "CREATING",
"source_type": "SI_CREATED",
"created_at": ""
},
{
"rowNo": 2,
"drspGroupId": "drsp_group_002",
"groupStatus": "ACTIVE",
"nodeCount": 3,
"drsp_version": "2.1",
"status": "CREATING",
"source_type": "SI_CREATED",
"created_at": ""
}
]
}
}
3.10 查询DRSP组详情
路径:GET /api/dbaas/drsp/groups/{groupId}
功能:返回指定DRSP组的完整拓扑信息,包括节点列表和复制关系边,供前端渲染拓扑图。
响应体:
{
"code": 200,
"message": "success",
"data": {
"nodes": [
{
"nodeId": 1,
"drspGroupId": "drsp_group_001",
"productId": 1,
"gdbName": "GDB生产集群",
"gdbTag": "gdb_prod",
"clusterId": 101,
"clusterName": "tenant_a",
"role": "PRIMARY",
"roleDesc": "主",
"workMode": "SERVICE",
"sourceTag": "gdb1.c1",
"syncDelay": "1",
"relayDelay": "1",
"iaProtocal": "https",
"iaPort": "8804"
},
{
"nodeId": 2,
"drspGroupId": "drsp_group_001",
"productId": 1,
"gdbName": "GDB生产集群",
"gdbTag": "gdb_prod",
"clusterId": 101,
"clusterName": "tenant_a",
"role": "PRIMARY",
"roleDesc": "主",
"workMode": "SERVICE",
"sourceTag": "gdb1.c1",
"syncDelay": "1",
"relayDelay": "1",
"iaProtocal": "https",
"iaPort": "8804"
}
]
}
}
修订说明:
- 响应包含origin.md要求的全部列:角色、GDB名称、GDB标签、租户ID、租户名称、工作模式、源端标识、同步状态、同步时延、回放时延
- 新增
availableActions字段,告知前端当前节点可执行哪些操作按钮- 新增
roleDesc提供中文角色描述(主/备/级联),对应origin.md"角色加个帮助"
角色说明(页面tip展示):
- 主(PRIMARY):整个链条的起始节点,即生产集群
- 备(STANDBY):没有下级节点指向它的末端节点,即灾备集群
- 级联(CASCADE):链条中间节点,前一段关系的备,后一段关系的主
3.11 扩容灾备租户
路径:POST /api/dbaas/drsp/groups/{groupId}/expand
功能:向已有DRSP组扩容新的灾备租户。流程与创建类似,但需合并已有config。
请求体:
{
"newTenants": [
{"refId": "gdb_dr4.401", "productId": 4, "clusterId": 401, "clusterName": "tenant_dr3"}
],
"newEdges": [
{"sourceRef": "gdb_prod.101", "targetRef": "gdb_dr4.401"}
],
"gdbTags": {
"4": "gdb_dr4"
},
"configBase64": "W2dkYjNdCnp......"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| newTenants | Array | 是 | 新增灾备租户列表 |
| newEdges | Array | 是 | 新增的复制关系边(统一用 sourceRef/targetRef) |
| gdbTags | Map | 条件 | 新GDB的标签(已有GDB可省略) |
| configBase64 | String | 是 | 合并后的完整config.ini(base64编码) |
响应:HTTP 202 Accepted
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_1712492400001_0002"
}
}
注意事项:
- 扩容只对新租户执行"服务进只读"和"只读进同步"阶段
- 合并后的config需通过IA
prepare_drsp重新下发给所有GDB
3.12 删除DRSP组
路径:DELETE /api/dbaas/drsp/groups/{groupId}
功能:删除指定DRSP组,断开所有备租户的同步关系,将备租户切为服务模式,清除RDB中的DRSP关系记录。
请求体:
{
"password": "******"
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | String | 是 | 当前登录用户密码,二次校验 |
响应:HTTP 202 Accepted
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_1712492400001_0010"
}
}
注意事项:
- 删除是异步操作,内部执行流程:对每个备节点执行
sync_to_readonly→readonly_to_service - 密码校验失败返回
code: 403 - 组内存在 RUNNING 状态任务时拒绝删除,返回
code: 409 - 删除后组状态先变为
DELETING,全部执行完毕后从数据库清除
todo 详设评审
3.13 从RDB导入已有DRSP关系(新增)
路径:POST /api/dbaas/drsp/groups/import
功能:扫描指定GDB的RDB,发现已有的DRSP灾备关系,自动导入SI管理。对应origin.md需求2:"superinsight的drsp页面能自动加载RDB中已有的DRSP关系进行展示"。
请求体:
{
"productIds": [1, 2],
"autoImport": false
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| productIds | Array<Integer> | 是 | 要扫描的GDB产品ID列表 |
| autoImport | Boolean | 否 | 默认false=仅预览,true=直接导入 |
响应体(autoImport=false 时):
{
"code": 200,
"message": "success",
"data": {
"discoveredGroups": [
{
"gdbTag": "gdb1",
"nodes": [
{"gdbTag": "gdb1", "clusterId": 2, "role": "PRIMARY", "workMode": "SERVICE"},
{"gdbTag": "gdb3", "clusterId": 4, "role": "STANDBY", "workMode": "SYNC"}
],
"edges": [
{"sourceGdbTag": "gdb1", "sourceClusterId": 2, "targetGdbTag": "gdb3", "targetClusterId": 4}
],
"alreadyImported": false
}
]
}
}
响应体(autoImport=true 时):
{
"code": 200,
"message": "success",
"data": {
"importedGroups": [
{
"drspGroupId": "drsp_group_imported_001",
"sourceType": "RDB_IMPORTED",
"nodeCount": 2
}
]
}
}
注意事项:
- 导入的DRSP组
source_type标记为RDB_IMPORTED - 导入的GDB标签不强制全局唯一(兼容非SI部署的环境)
- 导入后,SI可对这些组执行切换等操作
todo 现有的drsp需要纳管进来操作吗?
3.14 执行DRSP操作(统一任务入口)
路径:POST /api/dbaas/drsp/tasks
功能:统一的异步任务提交入口。根据 taskName 分派到对应XML流程执行。覆盖计划切换、演练切换(含回迁)、故障切换(含修复接入)、RPO=0故障切换、停止/恢复同步等所有操作。
请求体:
{
"groupId": "drsp_group_001",
"taskName": "planSwitch",
"targetClusterId": 201,
"targetGdbTag": "gdb_dr1",
"sourceClusterId": 101,
"sourceGdbTag": "gdb_prod",
"password": "******",
"extraParams": {}
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| groupId | String | 是 | DRSP组ID |
| taskName | String | 是 | 操作类型,见下方映射表 |
| targetClusterId | Integer | 是 | 目标租户ID(被操作的节点) |
| targetGdbTag | String | 是 | 目标GDB标签 |
| sourceClusterId | Integer | 条件 | 源租户ID(部分操作需要) |
| sourceGdbTag | String | 条件 | 源GDB标签 |
| password | String | 条件 | stopSync/resumeSync/delete 需密码校验 |
| extraParams | Object | 否 | 扩展参数,如RPO=0的增量config |
taskName 映射表
| taskName | 说明 | XML processId | 必填参数 | 后端校验逻辑 |
|---|---|---|---|---|
planSwitch |
计划切换 | drspPlanSwitch | groupId, targetClusterId, targetGdbTag, sourceClusterId, sourceGdbTag | 校验同步状态正常 |
simuSwitch |
演练迁出 | drspFaultSimuSwitch | groupId, targetClusterId, targetGdbTag | 校验目标是末端备节点(出度=0) |
simuSwitchRollback |
演练回迁 | drspFaultSimuSwitch | groupId, targetClusterId, targetGdbTag | 校验目标 simu_status=SIMUING |
faultSwitch |
故障升主 | drspFaultSwitch | groupId, targetClusterId, targetGdbTag | 校验目标是主节点的直接下级 |
faultSwitchRepair |
修复接入 | drspFaultSwitch | groupId, targetClusterId, targetGdbTag | 校验目标 fault_status=FAULT |
faultSwitchSyncNew |
修复后接回 | drspFaultSwitch | groupId, targetClusterId, targetGdbTag, sourceClusterId, sourceGdbTag | 校验修复已完成 |
faultNorbSwitch |
RPO=0故障升主 | drspFaultNorbSwitch | groupId, targetClusterId, targetGdbTag, extraParams.configBase64 | 增量config下发到灾备集群 |
faultNorbSwitchRepair |
RPO=0修复接入 | drspFaultNorbSwitch | groupId, targetClusterId, targetGdbTag | 校验目标 fault_status=FAULT |
faultNorbSwitchSyncNew |
RPO=0修复后接回 | drspFaultNorbSwitch | groupId, targetClusterId, targetGdbTag, sourceClusterId, sourceGdbTag | 校验修复已完成 |
stopSync |
停止同步 | drspSyncToReadonly | groupId, targetClusterId, targetGdbTag, password | 密码校验 + 权限检查 |
resumeSync |
恢复同步 | drspReadonlyToSync | groupId, targetClusterId, targetGdbTag, sourceClusterId, sourceGdbTag, password | 密码校验 + 权限检查 |
各操作对应IA接口调用(完整映射)
计划切换(对应"DRSP部署切换api说明.md" §1.5.1):
| 阶段 | TaskType | Param |
|---|---|---|
| 切换前检查 | planswitch_1_beforecheck |
-cfg_file={cfgFile} -source={sourceTag} -dest={targetTag} -source_cid={sourceCid} -dest_cid={targetCid} |
| 执行切换 | planswitch_2_planswitch |
同上 |
| 切换后检查 | planswitch_3_aftercheck |
同上 |
2节点组可用source+dest模式;3+节点组可用source-only模式 (
-cfg_file={cfgFile} -source={sourceTag} -source_cid={sourceCid})
演练切换(对应§1.5.2):
| 操作 | 阶段 | TaskType |
|---|---|---|
| 演练迁出 | 切换前检查 | faultsimuswitch_1_beforecheck |
| 执行切换 | faultsimuswitch_2_faultsimuswitch |
|
| 切换后检查 | faultsimuswitch_2_faultsimuswitch_aftercheck |
|
| 演练回迁 | 数据回滚 | faultsimuswitch_3_fastrollback |
| 重新同步 | faultsimuswitch_4_sync |
|
| 回迁后检查 | faultsimuswitch_5_aftercheck |
故障切换(RPO≠0)(对应§1.5.3):
| 操作 | 阶段 | TaskType |
|---|---|---|
| 故障升主 | 切换前检查 | faultswitch_1_beforecheck |
| 执行切换 | faultswitch_2_faultswitch |
|
| 切换后检查 | faultswitch_2_faultswitch_aftercheck |
|
| 修复接入 | 服务进只读 | service_to_readonly |
| 禁用集群 | disable_cluster |
|
| 处理binlog | handle_binlog |
|
| 处理回滚 | handle_rollback |
|
| 启用集群 | enable_cluster |
|
| 修复后接回 | 接回同步 | faultswitch_3_sync(注意source/dest互换) |
| 接回后检查 | faultswitch_4_aftercheck |
故障切换(RPO=0)(对应§1.5.4):
| 操作 | 阶段 | TaskType |
|---|---|---|
| RPO=0故障升主 | 更新配置 | update_all_file |
| 切换前检查 | faultnorbswitch_1_beforecheck |
|
| 退同步 | faultnorbswitch_2_quit_sync |
|
| 恢复数据 | faultnorbswitch_3_recover_data_from_remote |
|
| 执行切换 | faultnorbswitch_4_faultnorbswitch |
|
| 切换后检查 | faultnorbswitch_4_faultnorbswitch_aftercheck |
|
| 修复接入 | 服务进只读 | service_to_readonly |
| 禁用集群 | disable_cluster |
|
| 处理回滚 | handle_rollback |
|
| 启用集群 | enable_cluster |
|
| 修复后接回 | 接回同步 | faultnorbswitch_5_sync |
| 接回后检查 | faultnorbswitch_6_aftercheck |
响应:HTTP 202 Accepted
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_1712492400001_0003"
}
}
注意事项:
- 同一DRSP组同一时间只能有一个 RUNNING 状态的任务,重复提交返回
code: 409 - 密码校验失败返回
code: 403 - 操作前校验目标节点的角色/状态是否满足条件,不满足返回
code: 400+ 具体原因 - 对于使用
exclusiveGateway的XML流程,后端将switchMode注入到startVariables中
3.15 查询任务执行状态
路径:GET /api/dbaas/drsp/tasks/{taskId}
功能:查询指定任务的执行进度,返回每个Activity节点的执行状态,供前端渲染进度页。
请求参数(Query):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| detailLevel | String | 否 | summary=仅总体进度(默认)/ detailed=当前活跃节点 / full=所有节点 |
响应体:
{
"code": 200,
"message": "success",
"data": {
"taskId": "task_1712492400001_0003",
"taskName": "faultSwitch",
"processId": "drspFaultSwitch",
"groupId": "drsp_group_001",
"phase": "RUNNING",
"startTime": "2026-04-09T10:30:00",
"endTime": null,
"errorMessage": null,
"progress": {
"totalSteps": 5,
"completedSteps": 2,
"percentage": 40
},
"activities": [
{
"elementName": "drspFaultSwitchBeforeCheck",
"elementType": "SERVICE_TASK",
"state": "COMPLETED",
"createdAt": "2026-04-09T10:30:02",
"completedAt": "2026-04-09T10:30:15"
},
{
"elementName": "drspFaultSwitch",
"elementType": "SERVICE_TASK",
"state": "RUNNING",
"createdAt": "2026-04-09T10:30:15",
"completedAt": null
}
]
}
}
注意事项:
progress.totalSteps只统计 SERVICE_TASK + SCRIPT_TASK 节点数(排除 START_EVENT, END_EVENT, GATEWAY)activities按创建时间排序,包含已完成和当前活跃的所有节点- 前端渲染规则:COMPLETED=绿色、RUNNING=蓝色高亮、FAILED=红色
3.16 查询节点同步状态详情(新增)
路径:GET /api/dbaas/drsp/nodes/{nodeId}/sync-status
功能:查询指定灾备节点的详细同步状态信息,用于"同步状态下钻弹窗"展示。对应origin.md:"状态提供下钻,可以弹窗展示命令的详细输出"。
请求参数:
| 参数 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| nodeId | Path | Long | 是 | 节点ID(drsp_node.id) |
响应体:
{
"code": 200,
"message": "success",
"data": {
"nodeId": 2,
"gdbTag": "gdb_dr1",
"clusterId": 201,
"syncStatus": "NORMAL",
"syncDelay": 2,
"replayDelay": 5,
"checkTime": "2026-04-10T08:30:00Z",
"rawOutput": "check_sync output:\n...(IA check_sync命令原始输出)...",
"details": [
{"item": "DN同步状态", "status": "NORMAL", "detail": "All DNs in sync"},
{"item": "同步时延", "status": "NORMAL", "detail": "2 seconds"},
{"item": "回放时延", "status": "NORMAL", "detail": "5 seconds"}
]
}
}
实现说明:
- 调用IA接口
check_sync(TaskType=check_sync,Param=--cfg_file {cfgFile} --section {gdbTag} --clusterid {clusterId}) - 返回值
code=1状态正常,code=2状态异常 rawOutput保留命令原始输出供高级用户排查
4. 错误码规范(新增)
4.1 统一响应格式
{
"code": 200,
"message": "success",
"data": {}
}
4.2 错误码定义
| HTTP状态码 | 业务code | 说明 | 场景示例 |
|---|---|---|---|
| 200 | 200 | 成功 | |
| 202 | 200 | 异步任务已接受 | 创建/切换/删除等异步操作 |
| 400 | 400 | 请求参数错误 | 必填参数缺失、格式错误 |
| 400 | 40001 | GDB标签不唯一 | 创建时检测到标签冲突 |
| 400 | 40002 | 拓扑存在闭环 | 拓扑排序检测为非DAG |
| 400 | 40003 | 节点状态不满足操作条件 | 非备节点执行演练切换 |
| 400 | 40004 | config.ini格式错误 | ini解析失败或关键字段缺失 |
| 403 | 403 | 密码校验失败 | 停止同步/修改config等操作 |
| 403 | 40301 | 权限不足 | 无 GDB_CLUSTER_DRSP 权限 |
| 404 | 404 | 资源不存在 | DRSP组/任务/节点ID不存在 |
| 409 | 409 | 资源冲突 | 组内已有RUNNING任务,重复提交 |
| 500 | 500 | 服务端内部错误 | 未预期异常 |
| 502 | 502 | IA接口调用失败 | IA返回code=2或连接超时 |
4.3 IA接口错误处理
| IA返回code | 含义 | 后端处理 |
|---|---|---|
| 1 | 成功 | 继续下一阶段 |
| 2 | 失败 | 记录错误信息到 drsp_task.error_message,更新任务状态为FAILED |
IA接口调用时的通用参数说明(对应"DRSP部署切换api说明.md" §1.1):
{
"streamNo": "{自动生成的流水号,格式: DRSP+时间戳}",
"taskType": "{见各操作的TaskType}",
"hostIp": "{iaHostIp,与请求url的IP一致}",
"user": "zxmanager",
"param": "{见各操作的Param模板}",
"timeout": 99999
}
注意:IA接口Param中部分参数用
--key value格式(如--cfg_file config.ini),部分用-key=value格式(如-cfg_file=config.ini),具体以"DRSP部署切换api说明.md"各接口定义为准。后端IA适配层需根据TaskType自动匹配正确的参数格式。
5. 操作按钮与权限控制
5.1 列表页操作按钮
根据origin.md需求,不同角色/状态的节点显示不同操作按钮:
| 按钮 | 显示条件 | 对应taskName |
|---|---|---|
| 扩容 | 组状态=ACTIVE | - (跳转扩容页面) |
| 计划切换 | 在非主节点操作栏显示;组状态=ACTIVE | planSwitch |
| 演练迁出 | 备节点(末端,出度=0)且 simu_status=NONE |
simuSwitch |
| 演练回迁 | 备节点且 simu_status=SIMUING |
simuSwitchRollback |
| 故障升主 | 主节点的直接下级备节点 | faultSwitch 或 faultNorbSwitch |
| 修复接入 | fault_status=FAULT 的节点 |
faultSwitchRepair 或 faultNorbSwitchRepair |
| 停止同步 | 灾备节点且 work_mode=SYNC |
stopSync |
| 恢复同步 | 灾备节点且 work_mode=READONLY |
resumeSync |
| 删除 | 组级别操作,组状态=ACTIVE | - (DELETE接口) |
| 修改配置 | 组级别操作,组状态=ACTIVE | - (config/modify接口) |
5.2 操作权限
| 操作 | 所需权限 | 密码校验 |
|---|---|---|
| 查看DRSP组列表 | GDB_CLUSTER_DRSP |
否 |
| 创建/扩容 | GDB_CLUSTER_DRSP |
否 |
| 计划切换/演练切换 | GDB_CLUSTER_DRSP |
否 |
| 故障切换 | GDB_CLUSTER_DRSP |
否 |
| 停止同步 | GDB_CLUSTER_DRSP |
是 |
| 恢复同步 | GDB_CLUSTER_DRSP |
是 |
| 修改配置 | GDB_CLUSTER_DRSP |
是 |
| 删除DRSP组 | GDB_CLUSTER_DRSP |
是 |
关键Java结构体
@PreAuthorize("hasAuthority('GDB_CLUSTER_DRSP')")
@PostMapping(value = "/getDrsp")
public BaseResult getDrsp(@RequestBody @Validated GdbDrspDto dto) {
log.debug("getDrsp, dto:{}", dto);
return BaseResult.builder().success("success").data(clusterService.getDrsp(dto)).build();
}
List<DrspChain> getDrsp(GdbDrspDto dto);
public class DrspChain {
Set<DrspNode> nodes = new HashSet<>();
List<DrspRelation> relations = new ArrayList<>();
}
@Data
public class DrspNode {
private int productId;
private String productName;
private String gdbTag;
private int clusterId;
private String clusterName;
private String role; // PRIMARY / STANDBY / CASCADE
private String workMode; // SERVICE / READONLY / SYNC
private String faultStatus; // NONE / FAULT
private String simuStatus; // NONE / SIMUING / SIMU_COMPLETE
private String syncStatus; // NORMAL / ABNORMAL
private Integer syncDelay;
private Integer replayDelay;
private String sourceTag; // 源端标识: gdbTag.clusterId
public DrspNode() {}
public DrspNode(String gdbTag, String clusterName) {
this.gdbTag = gdbTag;
this.clusterName = clusterName;
}
}
@Data
public class DrspRelation {
private DrspNode source;
private DrspNode target;
private int relayDelaySeconds;
private String syncStatus; // SYNCED / BROKEN / PAUSED
public DrspRelation(DrspNode source, DrspNode target, int relayDelaySeconds) {
this.source = source;
this.target = target;
this.relayDelaySeconds = relayDelaySeconds;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DrspRelation that = (DrspRelation) o;
return Objects.equals(source, that.source) &&
Objects.equals(target, that.target);
}
@Override
public int hashCode() {
return Objects.hash(source, target);
}
}
附录A:IA接口快速参考
IA接口统一入口(对应"DRSP部署切换api说明.md" §1.1):
POST http[s]://{iaHostIp}:{iaPort}/api/insightAgent/commonUtils/executeDrsp
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| streamNo | String | 是 | 流水号,格式建议: DRSP{yyyyMMddHHmmssSSS} |
| taskType | String | 是 | 任务类型(见各操作表格) |
| hostIp | String | 是 | 管理节点IP,与请求URL的IP一致 |
| user | String | 是 | 管理节点用户名,如 zxmanager |
| param | String | 否 | 脚本入参 |
| timeout | Integer | 否 | 超时时间(秒),0=不超时,建议设为99999 |
附录B:config.ini配置文件JSON更新说明
详见"DRSP部署切换api说明.md" §1.3。关键要点:
- JSON通过
BASE64_JSON_INFO传递,是针对config.ini的增量更新 - JSON第一层key对应不同配置文件:
drsp→config.ini,check_item→check_item.ini,rdb→rdb/config.ini,agent_auth→agent_auth.txt - 可通过命令获取完整JSON模板:
python platform/basic/convert_json_and_file.py --cfg_file config.ini --func_type f2j - 删除配置项使用
BASE64_DELETE_JSON_INFO参数 - 更新配置使用
update_all_fileTaskType,会同步到所有管理节点
附录C:需求覆盖追踪矩阵
| Origin需求条目 | 接口/功能 | 覆盖状态 |
|---|---|---|
| 1-(1) 页面展示DRSP关系 | GET /groups + GET /groups/{id} |
✅ 已覆盖 |
| 1-(2) 创建DRSP关系 | POST /precheck + POST /config/template + POST /groups |
✅ 已覆盖 |
| 1-(3) 卸载/删除DRSP | DELETE /groups/{id} |
✅ 已覆盖 |
| 1-(4) 修改DRSP | POST /config/modify |
✅ 已覆盖 |
| 2. 自动加载RDB已有DRSP | POST /groups/import |
✅ 已覆盖(新增) |
| 3. 计划切换 | POST /tasks (taskName=planSwitch) |
✅ 已覆盖 |
| 3. 演练切换 | POST /tasks (taskName=simuSwitch/simuSwitchRollback) |
✅ 已覆盖 |
| 3. 故障切换 | POST /tasks (taskName=faultSwitch/*) |
✅ 已覆盖 |
| 3. RPO=0故障切换 | POST /tasks (taskName=faultNorbSwitch/*) |
✅ 已覆盖 |
| 扩容 | POST /config/expand + POST /groups/{id}/expand |
✅ 已覆盖 |
| 停止同步 | POST /tasks (taskName=stopSync) |
✅ 已覆盖 |
| 恢复同步 | POST /tasks (taskName=resumeSync) |
✅ 已覆盖 |
| 同步状态下钻 | GET /nodes/{id}/sync-status |
✅ 已覆盖(新增) |
| 密码校验+权限控制 | 各接口password字段 + @PreAuthorize | ✅ 已覆盖 |

浙公网安备 33010602011771号