网易首页 > 网易号 > 正文 申请入驻

如何实现MySQL代码和数据的一站式变更

0
分享至

作为一款开源的关系型数据库管理系统,MySQL因其体积小灵活性强、运行速度快、成本低而被企业和社区广泛使用。然而在业务迭代中,随着数据的积累和业务场景的复杂化,涉及到数据变更的操作往往会带来额外的心智负担。本文将分析这些痛点,并结合 Zadig 的自定义工作流阐述解决问题的实践,enjoy~

数据变更的痛点

日常研发流程中,涉及到数据变更的场景和痛点包括但不限于:


  1. 开发工程师在 dev 环境进行开发和自测,某次变更既涉及到数据变更(比如引入新的字段),又有业务代码变更,此时只能先登录到数据库中手动执行变更脚本后,再将代码变更部署到 dev 环境中。

  2. 业务数据存放于 MySQL 数据库中(比如账号登录信息、用户下单信息),测试(开发)工程师日常在 qa 环境验收时创建了很多临时测试数据,每次测试完毕都需要手动清理这部分脏数据,将数据恢复至初始状态。


下面以 Zadig 官方提供的 MySQL 数据库变更任务为例,就上述场景分别说明如何在 Zadig 中实现 MySQL 代码、数据的一站式变更,将重复的事情自动化。

准备工作

  1. 搭建项目 microservice-demo,参考教程如何使用 GitLab + Zadig 实现产品级持续交付[1]

  2. 官方提供的 MySQL 数据库变更任务说明:

    1. 实现的功能:连接 MySQL 数据库并执行指定的 SQL 脚本,详细逻辑可在 main.go 源码中查阅。

    2. 源码:mysql-runner[2],目录结构如下:


mysql-runner # 任务目录
└── v0.0.1 # 版本号
├── Dockerfile # 对应 mysql-runner 的镜像构建 Dockerfile
├── Makefile # mysql-runner 的工程编译文件
├── main.go # mysql-runner 任务的实现源码
└── mysql-runner.yaml # 任务的 YAML 配置文件


实践一:数据、代码一站式变更

第一步:配置工作流

包括:新建自定义工作流 -> 配置数据变更任务 -> 配置构建任务 -> 配置部署任务。

新建自定义工作流

点击「新建工作流」-> 选择「自定义工作流」-> 输入工作流名称「workflow-dev」。


配置数据变更任务

添加阶段:点击「+阶段」->填写阶段名称「数据变更」。

添加任务:点击「+任务」-> 选择「MySQL 数据库变更」。


配置任务:填写任务名称「mysql-data-update」-> 填写变量的值,本例中配置说明如下:

  • mysql-hostMySQL 数据库的地址,指定为固定值

  • mysql-portMySQL 数据库的端口号,指定为固定值

  • usernameMySQL 数据库的用户名,指定为固定值

  • passwordMySQL 数据库的密码,指定为固定值并设置为敏感信息

  • query要执行的 SQL 脚本,指定为运行时输入

至此,数据变更任务配置完毕。


配置构建任务

添加「构建」阶段 -> 点击「+任务」-> 选择「构建」。

配置任务名称「build-myapps」 -> 选择镜像仓库 -> 选择服务组件及构建名称后点击「确定」。

至此,构建任务配置完毕。

配置部署任务

添加「部署」阶段 -> 点击「+任务」-> 选择「部署」。

配置任务名称「deploy-myapps」-> 选择环境 dev -> 指定服务为「其他任务输出」并选择任务 「build-myapps」-> 点击「保存」完成工作流的配置。

第二步:执行工作流

点击执行 -> 填写要执行的 SQL 变更脚本 -> 选择需要更新的服务组件及代码信息 -> 启动任务。

本实践中 SQL 变更脚本如下(修改服务 hadas-core 的鉴权类型):

use service_config;
update services set auth_type = 2 where service_name = "hadas-core";

数据变更任务执行完毕前后分别查看 MySQL 数据效果如下(其中 1 为任务执行前,2 为执行后)

第一个数据变更任务执行完毕后,会自动执行后续的构建和部署任务,实现数据和业务的一站式变更。

实践二:脏数据一键自动清理

第一步:配置工作流

包括:新建自定义工作流 -> 配置构建任务 -> 配置部署任务 -> 配置自动化测试任务 -> 配置数据变更任务。

其中新建自定义工作流「workflow-qa」、配置构建任务「build-myapps」、部署任务「deploy-myapps」参考实践一,此处不再赘述,下面详细介绍自动化测试和数据清理任务的配置。


配置自动化测试任务

添加阶段「自动化测试」-> 添加任务 -> 选择通用任务 -> 填写任务配置。

自动化任务配置请根据自己的实际情况配置,本例中自动化测试用于测试商品创建和修改,运行完毕后会导致系统中遗留状态错误的商品数据。

配置数据清理任务

添加阶段「数据清理」-> 添加任务 -> 选择「MySQL 数据库变更」-> 填写任务配置。本例中配置说明如下:

  • 任务名称:handle-dirty-data

  • mysql-host:MySQL 数据库的地址,指定为固定值

  • mysql-port:MySQL 数据库的端口号,指定为固定值

  • username:MySQL 数据库的用户名,指定为固定值

  • password:MySQL 数据库的密码,指定为固定值并设置为敏感信息

  • query:要执行的 SQL 脚本,指定为固定值,本例中脚本如下(删除状态为不在线的商品数据):

添加任务 -> 选择 MySQL 数据库变更 -> 填写任务配置。本例中配置说明如下:"},"attribs":{"0":"*0+d*0*1+4*0+f*0*1+b*0+l"}},"apool":{"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]},"nextNum":2}},"align":"","folded":false,"seq":"2"}},"doxcne4oiYsommGuUoLbO9MCBFx":{"id":"doxcne4oiYsommGuUoLbO9MCBFx","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+4*0+i"},"text":{"0":"任务名称:handle-dirty-data"}}},"align":"","folded":false,"seq":"1"}},"doxcnw8k6kGusCyQKJSoSzez8E7":{"id":"doxcnw8k6kGusCyQKJSoSzez8E7","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+a*0+k"},"text":{"0":"mysql_host:MySQL 数据库的地址,指定为固定值"}}},"align":"","folded":false,"seq":"auto"}},"doxcnk8aAG2U4sKUG8lKXEyIu9e":{"id":"doxcnk8aAG2U4sKUG8lKXEyIu9e","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+a*0+l"},"text":{"0":"mysql_port:MySQL 数据库的端口号,指定为固定值"}}},"align":"","folded":false,"seq":"auto"}},"doxcnoWIGyCkgUO0icbQgnWUlVd":{"id":"doxcnoWIGyCkgUO0icbQgnWUlVd","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+8*0+l"},"text":{"0":"username:MySQL 数据库的用户名,指定为固定值"}}},"align":"","folded":false,"seq":"auto"}},"doxcnACuskgkmmcgKU1G60TAnBb":{"id":"doxcnACuskgkmmcgKU1G60TAnBb","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+8*0+s"},"text":{"0":"password:MySQL 数据库的密码,指定为固定值并设置为敏感信息"}}},"align":"","folded":false,"seq":"auto"}},"doxcnIeMQis4YqKC0kLstd6LTsh":{"id":"doxcnIeMQis4YqKC0kLstd6LTsh","snapshot":{"type":"ordered","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"initialAttributedTexts":{"text":{"0":"query:要执行的 SQL 脚本,指定为固定值,本例中脚本如下(删除状态为不在线的商品数据):"},"attribs":{"0":"*0*1+5*0+17"}},"apool":{"numToAttrib":{"0":["author","6999256783185248260"],"1":["inlineCode","true"]},"nextNum":2}},"align":"","folded":false,"seq":"auto"}},"doxcn6oiqas6EoSc6Yi1ZExT8CC":{"id":"doxcn6oiqas6EoSc6Yi1ZExT8CC","snapshot":{"type":"code","parent_id":"doxcn8gGo8UkWk2YyiIpsG55Fze","comments":[],"locked":false,"hidden":false,"author":"6999256783185248260","children":[],"text":{"apool":{"nextNum":1,"numToAttrib":{"0":["author","6999256783185248260"]}},"initialAttributedTexts":{"attribs":{"0":"*0|1+g*0+11"},"text":{"0":"use order_info;\ndelete from product where status = 0;"}}},"align":"","folded":false,"language":"SQL"}},"doxcn2SJcTo6gFJh1kGsRtpSrdl":{"id":"doxcn2SJcTo6gFJh1kGsRtpSrdl","snapshot":{"type":"page","parent_id":"","comments":["7137647336443904002"],"locked":false,"hidden":false,"author":"6999256783185248260","children":["doxcn6GIi4wuAWmYiqytzaP7Oqb","doxcnAoouasEksySYy04xiNxK7d","doxcn0WQCSAeYwA4cs7Npqdq4ph","doxcn8gIcosMWw6mo2zd2AFC9zh","doxcneSOCM8kkKWq2We8kLttgDe","doxcncKSoquAsEEmmSA4kQBapYd","doxcnQCUKWsYMKAGEyA78ALOhnd","doxcn64cigmIyOgeEk1O4tyQrKh","doxcnIUiOSKOgYMq22puXCN0aug","doxcnIgge8mkyKyGyCG8c9s378L","doxcnAw2kMuaIqO6sMdUUYrOQNc","doxcnK4cg0Ee4eAOC2ByKjIuz6e","doxcnq2ASMwUeKAYeYTqJ6TuCsf","doxcnSos8k8S8Wawq44chfDT9me","doxcnUIYm4y40ISGU8njAeCZcge","doxcnKSomaIaSWkkY6ezO6gT2nf","doxcnQuaoEsoaIyEI6ClMRwSJWh","doxcngwYIoeSy2cSqwVUnWwawQe","doxcniaiCK6omM6KyofteqNcv4c","doxcng2SsAa2kMCGUsVR5cc9BAW","doxcnGg6KQQOyQam2wRH1WfrEsb","doxcnmIKkMgOIc2IkSqBWnZvqwe","doxcn6UEKyUiys6uCofTFRhGWed","doxcnGw2iUwa8ykikg7eXvwH2ld","doxcn08GCcg4ouoyOSaXnBvm2kf","doxcnAU8MMiI8s6MWkxVHPWnm8g","doxcnIQk0Iyiwao6uOSrTgcYkGb","doxcn8WQQgYA0cASW4m8R4p3bZ6","doxcnqEOAYW4qoSeCmSRYwTtJ2e","doxcnOaAGAwykgsU0a4yLR9IaXe","doxcn020AA2CGSOkGC0deZQOfzg","doxcnO6wuAcOU0uMMITVmlZ7muc","doxcnk6Wiw42CeasoghSkB7OZ9d","doxcnGYeSi4KWOeAIwVexE0Advd","doxcnQkgaGyQ6cgSeo9v1yESWyh","doxcnowgIgMk4eYEYs1Y8xgvFrg","doxcnOyu2m2QQIYGuQJt3DCFmnd","doxcn8gGo8UkWk2YyiIpsG55Fze","doxcnkK0OmEgcMW4WUhyqgMFyUh","doxcnseMug2I4GC8mqa6Y2cVx2b","doxcnUISuSY4SaCy0t0sx4ZH0sJ","doxcnyWGois0AiIGawNqVDZtdnd","doxcnKkOaMAeI2uO4869c1tk7Ab","doxcngCSiYAeKeGAgg3gIILqPFf","doxcnWG88ceGuA2euuKbKmhRuuh","doxcnYsqw4gesM0IUaQXlglxFOX","doxcnsKWusmkikkKESUaSaSUGpf","doxcnUWAI8MkY6ciSqOq9Y32WEe","doxcnoAS2Uq2QEaawUv99kobEJg","doxcnMSAuGEa6Qe4ueUyQFBiTje","doxcnemoK4Ii2OQiOC6OGDkHYpf","doxcnmioCK0GE0q0qQ96Vz3e0Uf","doxcny2wKYK6sCKoYYLqzIcbXag","doxcnWCa8ueWKuCogxQo15i6qJl","doxcneeW06i4kU44MaIcuPslQ92","doxcnScSy8GS62CCocD2JEcatUe","doxcnq6YSySogQEYWwNuQ5IZCXb","doxcn8YiyS648q0SU0yBlWjoC8b","doxcn2gAkaaUMMqA2QL2JCHgT5g","doxcnCQSKqUAEOyqI2FW5w7GzQe","doxcnGCMi6aykG0Ku8r7614P9ed","doxcncqUeUi4aA20IIWG8bWSydb","doxcnSSg0O8EsC0MwM7cJZhlwFg","doxcnwIYSIoak2uIseGxf5Je4oc"],"text":{"apool":{"nextNum":2,"numToAttrib":{"0":["author","6999256783185248260"],"1":["comment-id-7137647336443904002","true"]}},"initialAttributedTexts":{"attribs":{"0":"*0*1+x"},"text":{"0":"Zadig + Mysql 代码、数据变更一站式编排,可靠丝滑交付"}}},"align":""}}},"payloadMap":{},"extra":{"mention_page_title":{},"external_mention_url":{}},"isKeepQuoteContainer":false,"pasteFlag":"ca8bcf57-f51e-4d90-b904-4d060fc7d800"}" data-lark-record-format="docx/record">


use order_info;
delete from product where status = 0;

至此,工作流配置完毕。

第二步:执行工作流

点击「执行」-> 选择要更新的服务组件及代码信息 -> 选择 qa 环境 -> 启动任务。

系统会按照顺序依次执行以下阶段:构建 -> 部署 -> 自动化测试 -> 数据清理。

待自动化测试执行完毕后,查看数据库中数据如下:

待数据清理执行完毕后,查看数据库中数据如下,可以看到因自动化测试产生的错误状态数据已被自动清理。

第三步(进阶):配置 Git 触发器,自动清理

配置触发器:编辑工作流「workflow-qa」-> 点击「触发器」 -> 配置代码库信息、触发事件和工作流执行变量等。

修改代码并提交到代码库后,会触发工作流执行,自动完成构建 -> 部署 -> 自动化测试 -> 数据清理流程,既保障本次变更的质量,又确保下次的自动化测试执行无后顾之忧。


探索更多实践

本文主要讲解了如何在 Zadig 上实现 MySQL 数据以及代码的一站式变更实践。如果官方提供的 MySQL 数据变更任务不能满足日常需求,可以参考自定义任务 | Zadig 文档[3]编写符合自己情况的自定义任务,也欢迎在Zadig 论坛[4]分享你的实践~

[1] https://koderover.com/tutorials/codelabs/GitLab/index.html

[2] https://github.com/koderover/zadig/tree/release-1.14.0/pkg/microservice/aslan/core/workflow/service/workflow/plugins

[3] https://docs.koderover.com/zadig/v1.14.0/settings/custom-task/

[4] https://community.koderover.com

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
突发!东莞一“擎天柱”在大风中倒下,路过车辆被砸中!

突发!东莞一“擎天柱”在大风中倒下,路过车辆被砸中!

东莞本地生活
2024-06-16 15:31:30
重返CBA?曝多支球队接触前广东功勋外援,欢迎回来

重返CBA?曝多支球队接触前广东功勋外援,欢迎回来

篮球大陆
2024-06-16 10:21:08
18个欧冠在开会!皇马三队长魔笛纳乔卡瓦哈尔交谈,3人18座欧冠

18个欧冠在开会!皇马三队长魔笛纳乔卡瓦哈尔交谈,3人18座欧冠

直播吧
2024-06-16 08:53:09
头部主播也卖不动了,抖音有点慌

头部主播也卖不动了,抖音有点慌

品牌营销官
2024-06-14 19:32:38
最终积分榜!中国女排3-0爆冷,日本女排三重不利,8强对阵敲定

最终积分榜!中国女排3-0爆冷,日本女排三重不利,8强对阵敲定

体育插班生
2024-06-16 22:12:58
《玫瑰的故事》的原型,美貌胜过刘亦菲,一人搞垮两个亿万富豪,如今成直播带货新宠?

《玫瑰的故事》的原型,美貌胜过刘亦菲,一人搞垮两个亿万富豪,如今成直播带货新宠?

LULU生活家
2024-06-16 18:06:49
黄一鸣正式上位,与王思聪挑选母婴用品,万达迎来了它的长公主

黄一鸣正式上位,与王思聪挑选母婴用品,万达迎来了它的长公主

综艺拼盘汇
2024-06-16 16:25:17
女副镇长出轨领导,聊天记录被丈夫曝光,内容露骨毁三观

女副镇长出轨领导,聊天记录被丈夫曝光,内容露骨毁三观

奇趣阁
2024-06-16 11:10:23
离婚实锤,黄景瑜私生活堪比罗志祥多人运动,带小三上爱巢拍照

离婚实锤,黄景瑜私生活堪比罗志祥多人运动,带小三上爱巢拍照

娱乐哈哈酱
2023-02-14 21:00:18
"最美女婴"刚出生就成网红,凭颜值征服网友,护士:难得一遇

"最美女婴"刚出生就成网红,凭颜值征服网友,护士:难得一遇

大果小果妈妈
2024-06-15 08:51:31
专家:对俄战争已然失败

专家:对俄战争已然失败

俄罗斯卫星通讯社
2024-01-22 15:13:11
红色预警!大暴雨!浙江入梅后最强降水来袭

红色预警!大暴雨!浙江入梅后最强降水来袭

鲁中晨报
2024-06-16 10:19:06
太狗血,37岁前国门私生活曝光,曾诚人设崩塌,300万补偿成空谈

太狗血,37岁前国门私生活曝光,曾诚人设崩塌,300万补偿成空谈

九霄云者
2024-06-14 10:26:31
A股:股市或将迎来暴风雨

A股:股市或将迎来暴风雨

生活中的栗子
2024-06-16 12:34:28
“花几百块让朋友出丑一个月”,地铁广告成了00后最新社死神器

“花几百块让朋友出丑一个月”,地铁广告成了00后最新社死神器

科学发掘
2024-06-16 12:45:06
偶遇蔡依林,搜了下才知道有演唱会,她本人真的好年轻好瘦好美!

偶遇蔡依林,搜了下才知道有演唱会,她本人真的好年轻好瘦好美!

娱记掌门
2024-06-16 16:06:48
解放军中将在京突然去世,两女儿定居美国,亲弟弟关联25家公司

解放军中将在京突然去世,两女儿定居美国,亲弟弟关联25家公司

求实者
2024-06-12 14:30:22
养老金调整方案公布在即,满60、70和80岁的老人,每月能涨多少?

养老金调整方案公布在即,满60、70和80岁的老人,每月能涨多少?

猫叔东山再起
2024-06-16 20:37:57
太离谱了!《墨雨云间》追剧日历更新,竟然减更了,严重的剧缩力

太离谱了!《墨雨云间》追剧日历更新,竟然减更了,严重的剧缩力

娱乐寡姐
2024-06-16 21:08:06
湖人新目标来了?24岁眼镜哥将成为自由球员 队记回应薪水是关键

湖人新目标来了?24岁眼镜哥将成为自由球员 队记回应薪水是关键

罗说NBA
2024-06-16 06:58:42
2024-06-16 23:30:44
开源中国
开源中国
每天为开发者推送最新技术资讯
6329文章数 34225关注度
往期回顾 全部

科技要闻

iPhone 16会杀死大模型APP吗?

头条要闻

理想车友聚会多车连环追尾 组织者:突遭大雨 车距较近

头条要闻

理想车友聚会多车连环追尾 组织者:突遭大雨 车距较近

体育要闻

没人永远年轻 但青春如此无敌还是离谱了些

娱乐要闻

上影节红毯:倪妮好松弛,娜扎吸睛

财经要闻

打断妻子多根肋骨 上市公司创始人被公诉

汽车要闻

售17.68万-21.68万元 极狐阿尔法S5正式上市

态度原创

艺术
房产
家居
本地
公开课

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

房产要闻

万华对面!海口今年首宗超百亩宅地,重磅挂出!

家居要闻

空谷来音 朴素留白的侘寂之美

本地新闻

粽情一夏|海河龙舟赛,竟然成了外国人的大party!

公开课

近视只是视力差?小心并发症

无障碍浏览 进入关怀版